你的任务消费机制会采用那种方式?
1.背景
这是个服务端根据配置信息不断产生任务信息,客户端不断拉取并处理任务,那么该如何解决任务的争抢问题?
2.思路
这是一个比较经典的抢单场景,传统方式是利用redis的单线程特性达成这一功能,不过在这个场景中需要注意任务是不断生成的,那么该如何解决呢?
很明显,如果大家都采用同步的操作去数据库进行检索,就会出现并发场景下的数据争抢,所以可以将争抢的动作交给队列去完成,不管是redis还是mq都可以很好的解决这一问题,随之而来的问题就是数据加载的时机。
数据获取的方式有很多,比较常见的有三类:
* 定时轮询加载:比如每过10秒钟将所有满足条件的部分(10条?)数据加载到对应的队列中,优点是动作很完整,缺点是实时性不高,在应对实时性要求不高的场景下应该是个不错的选择,不过客户端的轮询间隔明显是一个考量因素,如果客户端一天只会跑一次这就是个灾难了。
* 产生即加载:在任务配置衍生出任务时将任务加载到数据库以及队列中,优点是实时性很高,缺点是面对一些异常任务信息需要使用额外的方式去补偿,并且如果数据量过大则排队信息较多。
* 接受到请求时检测并加载:在请求发生时Peek 队列,如果数据存在则返回数据,如果队列为空,则将请求发送到正在监听的加载线程中。优点是及时性较高,缺点是单次请求性能略低。
其实不论以那种方式,我们都会有三个角色参与到这一流程里面:数据生产者,数据加载者,数据的消费者。

1. 生产者:任务的生产
2. 消费者:消费队列的任务,并通知数据库任务已消费
3. 加载者:将数据库满足条件信息的任务加载进入队列
消费者应对加载者的不同动作也会有以下两种实现:
* 只检查队列中的数据信息
* 检查队列信息,如果没有就通知加载者干活,一直等到队列中有反馈信息(不管有没有结果,这是一个封装信息)
通常我们会用单独线程去扮演每一个角色,这三者理论上是没有关联的,不过很明显当消费者发现货架上没有货物的时候是不是应该问一下加载者:到底还有没有货?
在这里使用消费者和加载者就需要进行通信,线程通信就被提出来了,既然用到redis,阻塞队列也算是一个不错的选择。
3.反思
服务端水平扩展中是否会存在着另一种竞争?数据库和队列的数据一致性该如何解决?
如果引入新的角色比如任务的管理者撤销任务又该如何处理?
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号