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唯一标识符推断是否存在该会话的返回结果,获得结果后将结果返回给请求发起者。

异步的特点是被调用者主动获取消息。并主动通过其它队列发送结果消息。这时被调用者能够依据自己的状态和处理情况推断是否(及怎样)获取消息。是否(及怎样)运行操作并返回结果。被调用者能够自行决定该怎样操作,比方能够批处理。

因此对于并发处理能力较弱的应用(被调用者)应採用异步方式主动接收消息。并主动创建会话返回处理结果消息,并依据实际情况决定怎样处理及返回结果(比方可採用批处理及返回的方式),之后请求发起者通过新建会话在本地缓存或本地数据库中获取返回结果,真正实现应用间的解耦。

异步消息流转架构图例如以下:

3. 跨中心消息时序图

3.1跨中心异步消息处理时序图一

异步消息结果,通过新建会话返回。

生产者发送消息后关闭会话,无需等待。全然的异步流程无需返回结果消息。用户通过发起新的查询请求。通过本地缓存或本地数据库获得结果。

3.2跨中心异步消息处理时序图二

在某些项目实际使用中,异步会话不会马上关闭而是等待结果,被调用者运行请求后将结果依照异步消息发送流程主动发送回去。会话通过轮询Redis结果缓存。依据Session唯一标识符推断是否存在该会话的返回结果,获得结果后将结果返回给请求发起者。异步的特点是被调用者主动获取消息。并主动通过其它队列发送结果消息。这时被调用者能够依据自己的状态和处理情况推断是否(及怎样)获取消息。是否(及怎样)运行操作并返回结果,被调用者能够自行决定该怎样操作。比方能够批处理。因此并发处理能力较弱的应用应採用该异步方式主动处理消息。而且请求发起者通过新建会话在本地缓存或本地数据库中获取结果,真正实现应用间的解耦。

3.3跨中心同步消息处理时序图一

会话发出异步消息后,会话堵塞,循环接收Topic Response 队列的广播消息。通过Session 唯一标识符推断每次收到的Topic订阅消息是否为该会话的请求结果消息,是的话返回给应用,否则忽略该消息,继续循环接收广播,超时后直接返回超时。

Topic消息并不会由于第一个消息没有被处理而发生堵塞。

全然的异步流程无需返回结果消息。用户通过发起查询。通过本地缓存或本地数据库获得结果;而跨中心同步异步化处理流程须要得到外系统处理结果。

3.4跨中心同步消息处理时序图二(使用暂时队列)

同步消息结果。通过暂时队列在一次会话中返回。暂时队列中仅仅保存本次会话中的消息。生产者需保持会话,等待结果返回。

4. 高可用(主从)与负载均衡架构图

消息发送中的接收Topic订阅结果消息队列URL地址、消息接收队列URL地址、消息代理的发送与接收队列URL地址以及消息转发器发送的Topic结果消息队列URL地址,均需设置为Failover
地址。

由于消息队列组件ActiveMQ是设置为主从的,因此不论什么组件连接消息队列的URL地址均需配置为主从Failover地址。

  1. <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机制有关。

取消消息通知的配置方法,在配置文件里添加例如以下配置:

  1. <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创建频繁的情况下,本功能很实用。

配置例如以下:

  1. <broker xmlns="http://activemq.apache.org/schema/core" schedulePeriodForDestinationPurge="10000" advisorySupport="false">
  2. <destinationPolicy>
  3. <policyMap>
  4. <policyEntries>
  5. <policyEntry queue=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="10000"/>
  6. </policyEntries>
  7. </policyMap>
  8. </destinationPolicy>
  9. </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策略来进行改动。

生产环境的配置例如以下:

  1. <policyEntry queue=">">
  2. <deadLetterStrategy>
  3. <!-- Use the prefix 'DLQ.' for the destination name, and make
  4. the DLQ a queue rather than a topic -->
  5. <individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true" />
  6. </deadLetterStrategy>
  7. </policyEntry>

queuePrefix:设置死信队列前缀

useQueueForQueueMessages: 设置使用队列保存死信。还能够设置useQueueForTopicMessages,使用Topic来保存死信

5.4  消息队列数过多问题

默认的消息队列配置中使用一个独立的线程负责将消息存储中的消息提取到消息队列中,而后再被分发到对其感兴趣的消息消费者。假设有大量的消息队列,建议通过启用optimizeDispatch这个属性改善这个特性,演示样例代码例如以下所看到的:

  1. <destinationPolicy>
  2. <policyMap>
  3. <policyEntries>
  4. <policyEntry queue=">" optimizedDispatch="true"/>
  5. </policyEntries>
  6. </policyMap>
  7. </destinationPolicy>

代码清单中使用通配符“>”表示该配置会递归的应用到全部的消息队列中。

6. 总结

6.1为什么不能使用ActiveMQ暂时队列实现同步消息

1)每个消息生成一个暂时队列。依旧是并发訪问没有产生“队列”的效果;

2)由于要通过暂时队列维持每个会话连接不断开。当大量会话同一时候到来时会造成网络拥堵,暂时队列没有异步高速传递消息的效果;

3)同一时候也会造成一处阻塞,处处阻塞的火烧连营的效果。

6.2异步消息的优势和特点

所谓异步传输。就是当我将消息传递给你后,该消息就与我无关了。消息在不同应用或设备之间传递。但应用或设备彼此并不须要关联(在一次会话间建立长连接)。即让消息通过不同会话在网络中进行短连接高速传递,实现应用或设备之间的解耦。

异步传输的特征是会话层採用短连接,网络层更加稳定。

异步传输的关键在于:消息传递的速度。消息传输的速度越快。会话连接的时间也就越短。系统更加稳定(不会由于数据堵塞造成超时、网络堵塞、内存溢出等问题),系统的效率更高。就像人体的血液循环(提高血液循环的速度的关键在于,一是推动血液运动的“力”要足,二是血脂要低降低阻力)。因此能够说提高互联网应用稳定性的要诀在于:不断提高数据传输的速度。在大并发的情况下要做到这一点,一是要採用异步方式使用短连接传输,假设会话连接长时间不断开(长连接),当大量会话同一时候到来时会造成网络拥堵;二是对数据传输尽可能的压缩;三是提高数据处理的能力。

互联网开发无小事。由于互联网应用要面对海量信息,一个小小的问题也能被无限放大,就像汪洋中的蝴蝶效应。一个互联网应用(如本文所说的消息中间件)遇到的问题可能与系统、网络、应用、架构、数据等各个层面的问题有关,仅仅有耐心发现并处理好每个相关层面的问题。才干终于形成一款好的互联网应用。时刻提醒自己当下一波巨浪到来前我们会准备的更好。

基于ActiveMQ的消息中间件系统逻辑与物理架构设计具体解释的更多相关文章

  1. Java生鲜电商平台-生鲜系统中微服务架构设计与分析实战

    Java生鲜电商平台-生鲜系统中微服务架构设计与分析实战 说明: Java生鲜系统中微服务的拆分应该如何架构设计与分析呢?以下是我的实战中的设计与经验分析. 目录 1. 微服务简介2. 当前现状3. ...

  2. 系统间通信——RPC架构设计

    架构设计:系统间通信(10)——RPC的基本概念 1.概述经过了详细的信息格式.网络IO模型的讲解,并且通过JAVA RMI的讲解进行了预热.从这篇文章开始我们将进入这个系列博文的另一个重点知识体系的 ...

  3. 三:基于Storm的实时处理大数据的平台架构设计

    一:元数据管理器==>元数据管理器是系统平台的“大脑”,在任务调度中有着重要的作用[1]什么是元数据?--->中介数据,用于描述数据属性的数据.--->具体类型:描述数据结构,数据的 ...

  4. 升讯威微信营销系统开发实践:(1)功能概要与架构设计( 完整开源于 Github)

    GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...

  5. 基于Vue实现后台系统权限控制

    原文地址:http://refined-x.com/2017/08/29/基于Vue实现后台系统权限控制/,转载请注明出处. 用Vue/React这类双向绑定框架做后台系统再适合不过,后台系统相比普通 ...

  6. 基于Web在线考试系统的设计与实现

    这是一个课程设计的文档,源码及文档数据库我都修改过了,貌似这里复制过来的时候图片不能贴出,下载地址:http://download.csdn.net/detail/sdksdk0/9361973   ...

  7. deep QA 基于生成的chatbot系统

    deep QA: https://github.com/Conchylicultor/DeepQA  基于论文:https://arxiv.org/pdf/1506.05869.pdf  基于生成的c ...

  8. 基于开源博客系统(mblog)搭建网站

    基于开源博客系统(mblog)搭建网站 上一章讲了基于jpress部署的博客系统,这一章了解一下 mblog这个开源的基于springboot的博客系统,相比与jpress 的热度fork数量要少一些 ...

  9. 基于python 信用卡评分系统 的数据分析

    基于python 信用卡评分系统 的数据分析 import pandas as pd import matplotlib.pyplot as plt #导入图像库 from sklearn.ensem ...

随机推荐

  1. Django day06 模版层(二) 过滤器 标签

    一: 模板语言之过滤器: " | " 前后的区分: 前面的是函数的第一个参数, 后面的是python的一个函数, 冒号后面的是第二个参数例:  <p>过滤器之默认值:{ ...

  2. Oracle占用内存过高解决办法

    1.cmd sqlplus system账户登录 2.show parameter sga; --显示内存分配情况 3.alter system set sga_max_size=200m scope ...

  3. [BZOJ1821][JSOI2010]部落划分

    感觉学了这么久还是有那么一丢丢进步的...上个学期看到这道题,虽然早就学过并查集和二分了但还是一点思路都没有,现在可以秒切了呢 思路就是二分+并查集,有些人说是生成树,其实它没有变成树,只是运用了生成 ...

  4. EditPlus 4:设置字体

    打开软件上面菜单栏点击Tools,在此下拉栏点击Configure User Tools,在弹出的设置框在左边框框中找到General->Fonts,显示的左边框即为字体框,具体如图:

  5. 剑指offer笔记

    1.在定义类的赋值描述符成员函数时,有以下几点要注意: 1)判断是否是自己赋值给自己 2)返回值是const类的引用(为了连续赋值) 3)参数是const类的引用 4)如果数据成员中有指针,注意要深拷 ...

  6. Windows 环境下 Docker 使用及配置

    原文引用: https://www.cnblogs.com/moashen/p/8067612.html 我们可以使用以下两种方式在Windows环境下使用docker: 1. 直接安装: Docke ...

  7. Android第一次项目

    学习了一个月的Android,接触了人生中第一个安卓项目,对于一个小白来说,总结是很重要的学习方法,以下我把学到的东西总结以下: 1. 1>okhttp3用法解析(边贴代码边熟悉) public ...

  8. 实现三联tab切换特效

    当移动到菜单“小说”,“非小说”,“少儿”时菜单背景变换,并显示相应内容: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitio ...

  9. C# 去掉代码前边空格(格式化代码)

    private void button1_Click(object sender, EventArgs e) { textBox2.Text = ""; string str = ...

  10. Java设计模式之JDK动态代理原理

    动态代理核心源码实现public Object getProxy() { //jdk 动态代理的使用方式 return Proxy.newProxyInstance( this.getClass(). ...