MessageQueue 队列设计(待续)

MessageQueue 队列设计

Overview

消息队列中的队列, 一大设计核心

队列设计重点

RPC通信协议
存储选型
消费关系处理
实现事务
防丢失、重复
批量、异步与性能

Rpc通信协议

市面上有不少成熟的RPC框架, 例如dubbo, thrift等, 无需重复造轮子, 消息队列对rpc框架并没有什么特别的要求.
甚至复用RPC框架, 可以直接获得RPC的高可用特性, 例如服务自动发现, 负载均衡, failover等

消费关系处理

可靠投递(最终一致性)

实现事务

Spring提供了实现事务的基类 DataSourceTransactionManager, 继承即可.
可以通过实现自己的事务管理器, 将provider的业务逻辑和消息本地落地绑定, 确保消息落地成功.

丢失, 重复

待续

批量, 异步, 性能

批量处理, 无疑是性能的要求和体现.

典型的生产消费者模式, 消费者到底应该何时消费?
两种常见的批量方式: 达到一定的数量, 等待一定的时间.
单纯的使用任何一种, 都有极大的局限性. 比如要求凑够4个消息, 批量处理一次, 那么当消息的间隔长的时候, 性能就极大的浪费了. 如果固定等待一定时间, 显然也对消息频率高, broker处理能力有限的场景不够适用.
而实际的业务场景可能是多变的, 所以大多的解决方案都是在数量和时间中取得一个平衡, 争取达到最优的性能.

举一个简单的实现例子

  1. 一个队列存放所有待发送消息
  2. 一个线程池批量发送消息 (最大线程数=核心线程数=n, 队列长度=1, reject=忽略)
  3. 线程池中的每个Runnable, 批量尝试从队列里捞a条消息去发送. 发送完继续回来捞, 捞空为止.(捞a条的batch模式, 是为了减少队列的并发冲突, 和RPC通信的损耗)
  4. 每次新消息入队, 都会尝试向线程池提交一个新的Runnable.
  5. 线程池任务满时, 直接丢弃.

为什么这么设计

  1. 动态调整并发量, provider消息频率高, 并发就大一点, 频率低, 就单线程发送, 以免浪费资源.
  2. 有速度上限, provider提交消息频率太高, 也有一个限制的最大发送速度. 不至于压力太大, 冲垮broker.
  3. 有一个问题, 如果以恰好的频率发送消息, 可能导致线程池始终保持最大线程数, 但是每次只发一条消息, 利用率极低, 远不如单线程独立发送. 但是在业务场景中, 几乎不可能出现.
  4. 那么, 还有什么问题?

另一种设计

  1. 一个线程监管队列长度, 达到x, 就调用线程池去取x个任务发送.
  2. 一个线程计时, 达到y, 就调用线程池去取所有任务发送.
  3. 每次发送前, 归零时间和数量的计数器.
  4. 问题: 死板, 需要线程资源来监控…

接下来再来聊聊异步.
郑重声明: 异步, 同步, oneway是三种东西; 客户端异步和服务端异步也是不一样的.

  1. 异步和同步的区别在于是否阻塞等待, 而oneway的意思是不关注结果
  2. 客户端异步是指的提交任务之后, 不阻塞等待结果; 服务端异步指的是不阻塞执行任务直到返回. 代码举例如下
// 客户端同步, 服务端同步
Result ret = service.request();

// 客户端异步, 服务端同步
Future future = executor.submit(new Callable<Result>() {
            @Override
            public Result call() throws Exception {
                return service.request();
            }
        })

// 客户端同步, 服务端异步
Future future = service.request();
Result ret = future.get(); //阻塞等待服务端返回

// 客户端异步, 服务端异步
Future future = service.request();
return future; //客户端也直接返回future, 想怎么用这个future就怎么用, 比如启个线程等待这个future isDone也可以.

// oneway
service.request();
  1. 在消息队列的实际中, 客户端是显而易见应该异步投递消息.
  2. broker服务端是否应该异步处理消息? 异步处理消息可以减少rpc通信线程的挂起数量, 还可以有选择的合并消息, batch insert, 但是这就不可避免的会带来消息的延迟.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值