1. 相关概念

  • 主题(Topic):指的是第一级的消息类型。例如实际中主题可以是“交易消息”
  • 消息类型(Tag):第二级消息类型。例如在交易消息的主题下,可以有交易创建和交易完成两个Tag(更加细致的去检索分类消息)

以上两种比较常见

  • 发送/订阅组(ProducerID/ConsumerID):方便收缩一个订阅或者服务组集群的机器。注意这里的消费是不广播的,只发给一台机器

2.消息乱序问题

2.1 产生原因

权衡 吞吐+容错 VS 方便 容易理解(性能往往较差)

顺序同步的方式吞吐量上不去,收到单机的限制。

2.2 有序队列优劣分析

优势: 容易理解,编码简单
劣势:并行度瓶颈、异常处理(一个处理失效,系统就阻塞了)

2.3 阿里中间件做法

基本有序、偶尔乱序。

例子:比如一笔订单有三个状态(创建、付款、发货):

  1. 三个状态之间是需要顺序的
  2. 不同的付款之间是需要顺序的
  3. 创建和发货可以考虑不需要顺序

是否可以乱序可以考虑应用本身的情况来分析。

发送乱序可以在接收端恢复顺序(例如TCP的传包),通过对消息编号的方式。

有序时候性能会差点,可以考虑减小锁的粒度。锁分越细,并行度越高。

3. 消息重复问题

3.1 产生原因

由于网络不可达的时候导致。回滚的代价比较大,所以一般是消息服务器再重发消息。

3.2 解决办法

采用“幂等”的操作(不去重)。例如S*S=S,使得操作无论重复多少次,结果都是一样的
例如SQL: insert into T(coll) values (1) 就是个幂等操作。

去重的代价较大,去重操作是否要做由用户自己抉择:

  1. 保证有个唯一ID标记每一条消息
  2. 保证消息处理成功与去重表日志同时出现(一次写变成两次写)

保证唯一ID和去重,可以将消息划分成更小的单位,方便并行,有时候也不一定时坏事。

4. 分布式事务与ONS

分割事务,利用异步事务,利用异步并行消息来提升性能。
例子:转账

难点:

  1. 消息发出和事务同时进行,必须原子性:处理方法是发送消息后还要ONS等待事务完成后的确认消息。ONS得到确认消息才会给消息接受者发送消息。 2.处理超时问题:如果不能采用幂等操作,就只能加个去重表,进行消息去重;如果有账号销户的问题,则人工处理(概率非常低)。

努力送达模型:送达失败继续送,不需要回滚。系统处理成本较低,性能好。