基于ActiveMQ的消息中间件系统逻辑与物理架构设计具体解释
1. 基本介绍与组件架构图
维基百科对消息中间件的定义是“Message-oriented Middleware is software infrastructure
focused on sending and receiving messages between distributed system。”分布式系统中实现消息发送和接受的基础设施。随着企业信息化建设的不断深入。多种业务应用相互关联,easy造成底层数据分散,应用系统间的耦合度高。针对该问题应从总体上调整眼下系统架构。面向不同业务应用提供统一的数据訪问服务,使用消息中间件对不同系统间的交互进行解耦,消息中间件技术有两个核心功能:异步和解耦。这两个核心功能总体上提高了应用系统的工作效率,增强了系统的可用性、稳定性和可扩展性。提升了用户体验。
使用OneMM消息中间件系统能够实现应用系统各模块间或应用系统与其它系统(如ERP系统、支付系统)之间的解耦与异步消息传输。改变直接通过数据库共享方式交换数据,造成系统之间底层数据耦合度过高问题以及远程跨地域应用系统的数据交换问题。
OneMM系统组件逻辑架构图例如以下:
消息中间件架构主要组件说明:
(1)消息发送组件:接收应用server发起的外系统调用请求。并将请求消息发送到本地消息队列或跨中心消息队列;
(2)消息接收组件:接收本地消息队列或跨中心消息队列中的请求消息,并调用外系统提供的业务接口;
(3)消息转发组件:消息转发器帮助跨中心应用进行消息转发,如图中的中心1和中心2之间。应用能够通过消息转发器进行消息互发。
(4)消息代理组件:消息代理组件主要负责接收跨中心消息,并将跨中心消息依据相关參数发送到下图中心1的“请求处理结果Topic订阅消息队列“或分发到中心2的相关详细业务队列;
(5)队列管理组件:配置管理不同中心下的所有消息队列。及相关调用接口。
(6)消息队列组件:提供消息队列创建、销毁等队列操作及管理功能。架构使用ActiveMQ开源消息队列工具。
(7)消息缓存组件:本地或跨中心异步消息通过Redis缓存组件获得返回结果消
2. 消息流转架构图
2.1同步消息流转架构:消息发送组件创建会话发出异步消息后,同步流程会话循环接收Topic消息回复订阅队列的广播消息,通过会话唯一标识推断是否为该会话的结果消息。是的话返回给应用,否则忽略该消息,超时后直接返回超时。同步消息流转架构图例如以下:
2.2异步消息流转架构:本地或跨中心异步消息通过Redis缓存组件获得返回结果消息。异步消息结果,通过新建会话返回。生产者发送消息后关闭会话,无需等待。
全然的异步流程无需返回结果消息。用户通过发起查询请求通过缓存或本地系统数据库获得结果。
可是在某些项目实际使用中,异步会话不会马上关闭而是等待结果。被调用者运行请求后将结果依照异步消息发送流程主动发送回去。会话通过轮询Redis结果缓存,依据Session唯一标识符推断是否存在该会话的返回结果,获得结果后将结果返回给请求发起者。
异步的特点是被调用者主动获取消息。并主动通过其它队列发送结果消息。这时被调用者能够依据自己的状态和处理情况推断是否(及怎样)获取消息。是否(及怎样)运行操作并返回结果。被调用者能够自行决定该怎样操作,比方能够批处理。
因此对于并发处理能力较弱的应用(被调用者)应採用异步方式主动接收消息。并主动创建会话返回处理结果消息,并依据实际情况决定怎样处理及返回结果(比方可採用批处理及返回的方式),之后请求发起者通过新建会话在本地缓存或本地数据库中获取返回结果,真正实现应用间的解耦。
异步消息流转架构图例如以下:
![](http://img.ptcms.csdn.net/article/201509/29/5609e23c076f7.jpg)
3. 跨中心消息时序图
3.1跨中心异步消息处理时序图一
异步消息结果,通过新建会话返回。
生产者发送消息后关闭会话,无需等待。全然的异步流程无需返回结果消息。用户通过发起新的查询请求。通过本地缓存或本地数据库获得结果。
![](http://img.ptcms.csdn.net/article/201509/29/5609e29ae5fce.jpg)
3.2跨中心异步消息处理时序图二
在某些项目实际使用中,异步会话不会马上关闭而是等待结果,被调用者运行请求后将结果依照异步消息发送流程主动发送回去。会话通过轮询Redis结果缓存。依据Session唯一标识符推断是否存在该会话的返回结果,获得结果后将结果返回给请求发起者。异步的特点是被调用者主动获取消息。并主动通过其它队列发送结果消息。这时被调用者能够依据自己的状态和处理情况推断是否(及怎样)获取消息。是否(及怎样)运行操作并返回结果,被调用者能够自行决定该怎样操作。比方能够批处理。因此并发处理能力较弱的应用应採用该异步方式主动处理消息。而且请求发起者通过新建会话在本地缓存或本地数据库中获取结果,真正实现应用间的解耦。
![](http://img.ptcms.csdn.net/article/201509/29/5609e2df947d5.jpg)
3.3跨中心同步消息处理时序图一
会话发出异步消息后,会话堵塞,循环接收Topic Response 队列的广播消息。通过Session 唯一标识符推断每次收到的Topic订阅消息是否为该会话的请求结果消息,是的话返回给应用,否则忽略该消息,继续循环接收广播,超时后直接返回超时。
Topic消息并不会由于第一个消息没有被处理而发生堵塞。
全然的异步流程无需返回结果消息。用户通过发起查询。通过本地缓存或本地数据库获得结果;而跨中心同步异步化处理流程须要得到外系统处理结果。
![](http://img.ptcms.csdn.net/article/201509/29/5609e37858585.jpg)
3.4跨中心同步消息处理时序图二(使用暂时队列)
同步消息结果。通过暂时队列在一次会话中返回。暂时队列中仅仅保存本次会话中的消息。生产者需保持会话,等待结果返回。
![](http://img.ptcms.csdn.net/article/201509/29/5609ea41eebb8.jpg)
4. 高可用(主从)与负载均衡架构图
消息发送中的接收Topic订阅结果消息队列URL地址、消息接收队列URL地址、消息代理的发送与接收队列URL地址以及消息转发器发送的Topic结果消息队列URL地址,均需设置为Failover 地址。由于消息队列组件ActiveMQ是设置为主从的,因此不论什么组件连接消息队列的URL地址均需配置为主从Failover地址。
- <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" advisorySupport="false">
5. 消息队列组件ActiveMQ配置
通过改动消息队列组件ActiveMQ的配置文件activemq.xml。以“效率优先”的原则调整相关參数。配置说明例如以下:
5.1 ActiveMQ消息通知配置
消息通知实现了ActiveMQ的Broker上各种操作的记录跟踪和通知。可是在使用暂时队列实现同步消息时我们发现ActiveMQ产生了大量advisory通知消息,而且这些消息重复在网络中传输。这有可能与ActiveMQ 同步消息ACK机制有关。
取消消息通知的配置方法,在配置文件里添加例如以下配置:
- <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" advisorySupport="false">
5.2删除不活动的队列配置
ActiveMQ的Queue在不使用之后,能够通过web控制台或是JMX方式来删除掉。
也能够通过配置。使得Broker能够自己主动探測到没用的队列(一定时间内为空的队列)并删除掉,回收响应资源。因为ActiveMQ使用时自己主动创建Destination。而且默认情况下不会删除掉。这样的仅仅添加不降低。导致在queue创建频繁的情况下,本功能很实用。
配置例如以下:
- <broker xmlns="http://activemq.apache.org/schema/core" schedulePeriodForDestinationPurge="10000" advisorySupport="false">
- <destinationPolicy>
- <policyMap>
- <policyEntries>
- <policyEntry queue=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="10000"/>
- </policyEntries>
- </policyMap>
- </destinationPolicy>
- </broker>
參数说明:
1) schedulePeriodForDestinationPurge:10000 每十秒检查一次,
默觉得0,此功能关闭
2) gcInactiveDestinations:true 删除掉不活动队列。默觉得false
3) inactiveTimoutBeforeGC:30000 不活动30秒后删除,默觉得60秒
5.3死信队列配置
DLQ-死信队列(Dead Letter Queue)用来保存处理失败或者过期的消息。出现下面情况时,消息会被再投递
1)A transacted session is used and rollback() is called.
2)A transacted session is closed before commit is called.
3)A session is using CLIENT_ACKNOWLEDGE and Session.recover() is called.
当一个消息被redelivered超过maximumRedeliveries(缺省为6次)次数时,会给broker发送一个"Poison ack"。这个消息被觉得是a poison pill,这时broker会将这个消息发送到DLQ,以便兴许处理。
缺省的死信队列是ActiveMQ.DLQ。假设没有特别指定。死信都会被发送到这个队列。缺省持久消息过期,会被送到DLQ,非持久消息不会送到DLQ
缺省全部队列的死信消息都被发送到同一个缺省死信队列(ActiveMQ.DLQ)。不便于管理。能够通过individualDeadLetterStrategy或sharedDeadLetterStrategy策略来进行改动。
生产环境的配置例如以下:
- <policyEntry queue=">">
- <deadLetterStrategy>
- <!-- Use the prefix 'DLQ.' for the destination name, and make
- the DLQ a queue rather than a topic -->
- <individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true" />
- </deadLetterStrategy>
- </policyEntry>
queuePrefix:设置死信队列前缀
useQueueForQueueMessages: 设置使用队列保存死信。还能够设置useQueueForTopicMessages,使用Topic来保存死信
5.4 消息队列数过多问题
默认的消息队列配置中使用一个独立的线程负责将消息存储中的消息提取到消息队列中,而后再被分发到对其感兴趣的消息消费者。假设有大量的消息队列,建议通过启用optimizeDispatch这个属性改善这个特性,演示样例代码例如以下所看到的:
- <destinationPolicy>
- <policyMap>
- <policyEntries>
- <policyEntry queue=">" optimizedDispatch="true"/>
- </policyEntries>
- </policyMap>
- </destinationPolicy>
代码清单中使用通配符“>”表示该配置会递归的应用到全部的消息队列中。
6. 总结
6.1为什么不能使用ActiveMQ暂时队列实现同步消息
![](http://img.ptcms.csdn.net/article/201509/29/5609eb951bfa8.jpg)
1)每个消息生成一个暂时队列。依旧是并发訪问没有产生“队列”的效果;
2)由于要通过暂时队列维持每个会话连接不断开。当大量会话同一时候到来时会造成网络拥堵,暂时队列没有异步高速传递消息的效果;
3)同一时候也会造成一处阻塞,处处阻塞的火烧连营的效果。
6.2异步消息的优势和特点
所谓异步传输。就是当我将消息传递给你后,该消息就与我无关了。消息在不同应用或设备之间传递。但应用或设备彼此并不须要关联(在一次会话间建立长连接)。即让消息通过不同会话在网络中进行短连接高速传递,实现应用或设备之间的解耦。
异步传输的特征是会话层採用短连接,网络层更加稳定。
异步传输的关键在于:消息传递的速度。消息传输的速度越快。会话连接的时间也就越短。系统更加稳定(不会由于数据堵塞造成超时、网络堵塞、内存溢出等问题),系统的效率更高。就像人体的血液循环(提高血液循环的速度的关键在于,一是推动血液运动的“力”要足,二是血脂要低降低阻力)。因此能够说提高互联网应用稳定性的要诀在于:不断提高数据传输的速度。在大并发的情况下要做到这一点,一是要採用异步方式使用短连接传输,假设会话连接长时间不断开(长连接),当大量会话同一时候到来时会造成网络拥堵;二是对数据传输尽可能的压缩;三是提高数据处理的能力。
互联网开发无小事。由于互联网应用要面对海量信息,一个小小的问题也能被无限放大,就像汪洋中的蝴蝶效应。一个互联网应用(如本文所说的消息中间件)遇到的问题可能与系统、网络、应用、架构、数据等各个层面的问题有关,仅仅有耐心发现并处理好每个相关层面的问题。才干终于形成一款好的互联网应用。时刻提醒自己当下一波巨浪到来前我们会准备的更好。