`
houlinyan
  • 浏览: 147709 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

消息队列的处理方案

    博客分类:
  • java
阅读更多
基本情况介绍:
agent:负载容器的生命周期管理,和容器的健康检查,在容器进程down和start的时候给master发通知
master:接收到agent的消息放到一个队列里面,一个线程循环从队列中获取appid,将最新的应用的实例列表发给router(由于很多种业务场景都会触发router更新,且要保证先后顺序,所以用了一个队列,且把放的和取的分开)
router:router接收到master过来的消息,更新应用的实例列表,以保证请求都转发到可用的实例上。

问题来了:
有的应用处理总超时,导致健康检查频繁的失败和成功,每一次变化都会通知master,master都会通知router,状态变化过于频繁会导致router处理失败。

解决方法一:
队列里本来就放了appid和addtime,再加一个map,key=appid,value=最后一次放入队列的time
每次从队列取出appid后比较addtime和map里面的appid的time,< 不处理,>= 通知router,以此减少通知的频率,减轻router的压力。问题:如果容器的状态变化很频繁,从队列里面取到的时间永远小于map中的时间,永远不会通知。

解决方法二:
将队列改为优先级队列PriorityQueue,这样所有的appid的消息在一起,从队列里面取出来的下一次的appid和上一次的不一样,通知rouer,一样pass。缺点:不能保证先变化的先通知。


解决方法三:
使用queue和set,每次放队列的时候,先判断set是否有appid,有pass,没有set和queue同时添加。这样可以把重复的的在放的时候就过滤掉。为了保证处理过快,过滤重复的效果不佳,每处理队列里面的一个元素,sleep1秒。这个sleep1s对于业务是可以接受的。这个方案对于目前的并发量来说,应该是没有问题的。一定要注意在放set和queue,删set和queue的时候加锁,以防止高并发的问题

综合考虑,我们采用了方案三。




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics