消息延迟是异步吗
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消息延迟是异步吗相关的知识,希望对你有一定的参考价值。
消息延迟不是异步,消息延迟的具体情形包括:一、网络延迟
这是经常的事件,我们所处的位置网络不好,或者运营商给我们短了网,或者是WiFi信号问题等等,都可能导致微信消息延迟,这是因为网络导致的延迟。
解决方式:建议大家在手机设置中,通过对无线和网络进行设置,保证即使在休眠状态下保持WLAN连接,或者始终连接数据业务,打开开关。
二、手机设置问题
我们以华为手机为例,我们要确保手机有没有被列入白名单,或者在电池自动启动中,有没有关闭。
三、通知栏的设置
比如我们将手机的通知功能关闭了,一样也收不到消息,需要进入手机“设置”,找到“通知栏和状态栏”,点击“通知管理”,将“允许通知”开启就好了;或者iPhone的设置——通知——允许通知打开。
手机省电模式下,可能也会将微信通知功能关闭,建议在不必要的时候开启省电模式。 参考技术A 废话补不多说上代码:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
//发送消息
$redis->lPush($list, $value);
//消费消息
while (true)
try
$msg = $redis->rPop($list);
if (!$msg)
sleep(1);
//业务处理
catch (Exception $e)
echo $e->getMessage();
上面代码会有个问题如果队列长时间是空的,那pop就不会不断的循环,这样会导致redis的QPS升高,影响性能。所以我们使用sleep来解决,当没有消息的时候阻塞一段时间。但其实这样还会带来另一个问题,就是sleep会导致消息的处理延迟增加。这个问题我们可以通过blpop/brpop 来阻塞读取队列。
blpop/brpop在队列没有数据的时候,会立即进入休眠状态,一旦数据到来,则立刻醒过来。消息的延迟几乎为零。用blpop/brpop替代前面的lpop/rpop,就完美解决了上面的问题。
还有一个需要注意的点是我们需要是用try/catch来进行异常捕获,如果一直阻塞在那里,Redis服务器一般会主动断开掉空链接,来减少闲置资源的占用。
延迟队列
你是否在做电商项目的时候会遇到如下场景: - 订单下单后超过一小时用户未支付,需要关闭订单 - 订单的评论如果7天未评价,系统需要自动产生一条评论
这个时候我们就需要用到延时队列了,顾名思义就是需要延迟一段时间后执行。Redis可通过zset来实现。我们可以将有序集合的value设置为我们的消息任务,把value的score设置为消息的到期时间,然后轮询获取有序集合的中的到期消息进行处理。
实现代码如下:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->zAdd($delayQueue,$tts, $value);
while(true)
try
$msg = $redis->zRangeByScore($delayQueue,0,time(),0,1);
if($msg)
continue;
//删除消息
$ok = $redis.zrem($delayQueue,$msg);
if($ok)
//业务处理
catch(Exception $e)
消息队列介绍
应用解耦、异步通信、流量削峰、数据同步
功能
优先级队列
优先级高的消息优先被消费,如果消费者的消费速度大于生产者的速度,并且消息服务器中没有消息堆积,那么对发送的消息设置优先级也就没有意义了
延迟队列
延迟消息是指消息发送后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到消息进行消费
延迟队列分两种:基于消息的延迟和基于队列的延迟,基于消息的延迟是指为每条消息设置不同的延迟时间,每当队列红油新消息进入就会重现根据延迟时间重新排序,这种方式的队列对性能影响很大;基于队列的延迟,是指不同延迟时间的消息放入不同的队列,每一个队列中的消息的延迟时间都是相同的,就不需要根据延迟时间进行排序了
死信队列
由于某些原因消息无法被正确的投递,为了确保消息不会无故丢弃,一般将其放入死信队列
与此对应的是回退队列,试想如果消费者在消费时发生异常,那么就不会对消息进行确认(ack),进而发生回滚消息的操作之后消息始终放在队列的顶部,然后不断被处理和回滚,导致队列进入死循环,为了解决该问题,可以为每个队列设置一个回退队列,它和死信队列都是为异常的处理提供的一种机制保障,实际情况下,回退队列的角色可以由死信队列和重试队列来扮演。
重试队列
重试队列其实可以看成是一种回退队列,指当消费端消费消息失败时,为防止消息无故丢失而重新将消息回滚到broker中,与回退队列不同的是重试队列一般分为多个重试等级,每个重试等级一般也会设置重新投递延时,重试次数越多投递延时就越大。举个例子:消费第一次消息失败放入重试队列Q1,Q1的重新投递延迟为5S,在5s过后重新投递该消息,如果消息再次消费失败则入重试队列Q2,Q2的重新投递延迟为10S,在10s过后重新投递该消息;以此类推,重试越多次重新投递的时间就越久,为此需要设置一个上限,超过投递次数就进入死信队列
重试队列与延迟队列的区别:延迟队列动作由内部触发,重试队列动作由外部消费端触发;延迟队列作用一次,而重试队列的动作范围会向后传递
消费模式
消费模式分为推模式和拉模式
广播消息
消息一般有两种传递模式:点对点模式和发布/订阅模式
消息回溯
消息堆积、持久化
流量削峰得益于消息堆积的能力,消息堆积分为内存式堆积和磁盘式堆积
消息追踪
消息过滤
多租户
多协议支持
跨语言支持
流量控制
消息顺序性
安全机制
消息幂等性
例如:以订单号作为唯一性标识别,并在下游设置去重表
事物性消息
性能
吞吐量、时延,消息堆积越大也就意味着时延也就越长,如果要求时效性高完全可以采用rpc方式实现。
可靠性、可用性
可靠性是指对消息不丢失的保障程度;可用性是指无故障运行的时间百分比
运维能力
社区力度及生态发展
以上是关于消息延迟是异步吗的主要内容,如果未能解决你的问题,请参考以下文章