消息系统中,常用的一致性解决方案如下:
1) 发送消息给消息系统
2) 消息系统入库消息
3) 消息系统返回结果
4) 业务操作
5) 发送业务操作结果给消息系统
6) 更改存储中的消息状态
如果消息丢失,从业务数据补发消息是最彻底的容灾手段。一般地,把集群和集群之间对消息的消费作为topic模型处理,而集群内部的各个应用实例对消息的消费当做Queue模型处理。引入clusterID来标识不同的集群,集群内的各个应用实例的连接使用同样的ClusterID。分两级处理,从而达到多个不同的集群进行消息订阅的目的。需要注意的是从topic中分发消息分发到不同的queue中时,需要由独立的中转消息订阅者来完成,并且对同一个queue的中转只能由一个连接完成,为了实现高可用性,还需要备份节点。
为了保证消息发送的可靠性,首先要保证消息发送端的可靠性。保证消息存储的可靠性有多种方法:有基于文件的消息存储例如ActiveMQ,采用数据库的消息存储一般考虑采用宽表、冗余数据的方式实现,还有基于双机内存的消息存储。通过服务器主动调度安排投递的方式可以实现数据库存储的便利扩容。由于消息系统需要显示地收到接受者确认消息处理完毕的信号才能删除消息,所以保证消息投递的可靠性一定从应用层的响应入手。在进行投递时一定要采用多线程的方式处理,单机多订阅者共享连接,消息只发送一次,然后传到单机的多订阅者生成多个实例处理。消息重复接收主要是因为消息接受者成功处理消息后,消息系统不能及时更新投递状态造成的。应对消息重复的办法是使消息接收端的处理是一个幂等操作。
对应有序的消息队列而言,单机多队列的隔离完成了对消息的有序支持,进一步,把发送到这台机器的消息数据进行顺序写入,然后根据队列做一个索引,每个队列的索引是独立的,其中保存的只是相对于存储数据的物理队列的索引。另外,采用消息同步复制的方式解决本地存储的可靠性。