
消息队列中间件是分布式系统中的重要组件. 它主要解决了应用程序耦合,异步消息传递和流量削减的问题. 实现高性能,高可用性,可扩展以及最终一致的体系结构. 它是大型分布式系统必不可少的中间件.
当前在生产环境中,最常用的消息队列是ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等.
下面是对消息排队在实际应用中的常见使用场景的详细介绍. 场景分为四个场景: 异步处理,应用程序解耦,流量锐化和消息通信.
方案说明: 用户注册后,需要发送注册电子邮件和注册信息. 传统方法有两种: 串行模式和并行模式
成功将注册信息写入后,发送注册电子邮件,然后发送注册短信,并在完成所有任务后,将信息返回给客户端

串行模式
成功将注册信息写入后,同时执行发送注册电子邮件和发送注册SMS的操作. 执行完所有任务后,信息将返回给客户端. 与串行模式相比,并行模式可以提高执行效率并减少执行时间.

并行方法
可以得出上述比较,假设所有三个操作都需要50ms的执行时间(不包括网络因素),最终执行完成,串行模式需要150ms,并行模式需要100ms.
由于CPU单位时间内处理的请求数相同,假设CPU吞吐量为每秒100,则串行模式下1秒内可以执行的请求数为1000/150 ,少于7次;可以在并行模式下在一秒钟内执行的请求数是1000/100,十次.
从上面可以看出,传统的串行和并行方法会受到系统性能的限制,那么如何解决这个问题呢?
我们需要引入一个消息队列来异步处理不必要的业务逻辑,并且从中转换的过程是

引入消息队列并异步处理消息
根据上述过程,用户的响应时间基本上等于将用户数据写入的时间. 将注册电子邮件和注册SMS消息发送到消息队列后,执行结果可以返回到消息队列中. 时间非常快,几乎可以忽略不计,还有一种可以将系统吞吐量提高到20QPS的系统,比串行模式高3倍,比并行模式高2倍.
场景说明: 用户下订单后,订单系统需要通知库存系统.
传统方法是: 订单系统调用库存系统的接口. 如下图所示:

传统方式: 调用广告资源界面

传统方法具有以下缺点:
-1. 假设对库存系统的访问失败,减少库存的订单将失败消息队列中间件,从而导致无法创建订单
-2. 订单系统和库存系统的过度耦合
如何解决以上缺点?需要引入消息队列. 下图显示了引入消息队列后的体系结构:

引入消息队列以实现应用程序解耦
如果下订单时无法正常使用库存系统. 它不会影响正常的订单放置,因为在放置订单后,订单系统将写入消息队列,而不再关心其后续操作. 这使订购系统和库存系统的应用程序脱钩.
流量锐化也是消息队列中的常见情况,并广泛用于尖峰或抢夺活动中.
应用程序场景: 尖峰活动,通常是因为流量太大,导致流量突然增加并且应用程序挂断. 为了解决此问题,通常需要在应用程序的前端添加消息队列.
可以控制参加活动的人数;可以在短时间内缓解高流量应用的巨大压力;
流锐化处理方法的系统框图如下:

流量锐化方法系统图
在接收到用户请求之后,服务器首先写入消息队列. 此时,如果消息队列中的消息数超过最大数量,则直接拒绝用户请求或返回错误页面;尖峰服务根据尖峰规则读取消息队列中的请求信息,并进行后续处理.
日志处理是指在诸如Kafka的应用程序的日志处理中使用消息队列来解决大量日志传输的问题. 结构简化如下:

应用于日志处理的消息队列的体系结构
该架构在实际开发中的应用可以参考以下案例: 新浪技术共享: 我们如何进行32亿次实时日志的分析和处理

服务技术架构设计
Kafka: 用于接收用户日志的消息队列. Logstash: 执行日志解析并将其统一为JSON输出到Elasticsearch. Elasticsearch: 实时日志分析服务的核心技术,一种无模式的实时数据存储服务,通过索引组织数据,具有强大的搜索和统计功能. Kibana: 基于Elasticsearch的数据可视化组件,超级数据可视化功能是许多公司选择ELK堆栈的重要原因.

消息通信意味着消息队列通常具有内置的高效通信机制,因此它们也可以用于纯消息通信中. 例如,实现对等消息队列,等.

点对点通信体系结构设计
在对等通信体系结构的设计中,客户端A和客户端B共享一个消息队列以实现消息通信功能.

通信体系结构的设计
客户端A,客户端B和客户端N订阅相同的消息队列,并发布和接收消息,以实现聊天通信方案的设计.

电子商务系统
消息队列使用高度可用且持久的消息中间件. 例如Active MQ,Rabbit MQ,Rocket MQ.

日志收集系统
它分为四个部分: Zookeeper注册中心,日志收集客户端,Kafka群集和Storm群集(OtherApp).
谈到消息队列,您必须提到JMS. JMS(Java消息服务,Java消息服务)API是消息服务的标准/规范,它允许应用程序组件基于JavaEE平台创建,发送,接收和读取消息. 它使分布式通信的耦合性降低,消息服务更加可靠和异步.
在EJB体系结构中,有些消息bean可以与JM消息服务无缝集成. 在J2EE体系结构模式中,有一个消息服务器模式,用于实现消息和应用程序的直接解耦.
在JMS标准中,有两种消息模型P2P(点对点),即发布/订阅(发布/订阅).

P2P模式
P2P模式包括三个角色: 消息队列(Queue),发送者(Sender),接收者(Receiver). 每条消息都发送到特定的队列,并且收件人从队列中获取消息. 队列保留消息,直到消息被消耗或超时.
P2P功能
如果您希望发送的每条消息都将被成功处理,则需要P2P模式.

4.1.2发布/订阅模式

Pub / Sub模式
包含三个角色: 主题,发布者和订阅者. 多个发布者将消息发送到Topic,然后系统将这些消息传递给多个订阅者.
发布/子功能
为了减轻这种严格的时间相关性,JMS允许订阅者创建持久订阅. 这样,即使未激活(运行)订阅者,它也可以接收发布者的消息.
如果您要发送的消息可以不做任何处理,或者仅由一个消息处理者处理,或者可以由多个使用者处理,则可以使用发布/订阅模型.
在JMS中,消息的生成和使用是异步的. 为了使用,JMS消息传递者可以通过两种方式使用消息.
同步
订户或接收者通过接收方法接收消息. 接收方法将一直阻塞,直到接收到消息为止(或在消息超时之前). 异步
订户或接收者可以注册为消息侦听器. 消息到达时,系统会自动调用侦听器的onMessage方法.
JNDI: Java命名和目录接口,是标准的Java命名系统接口. 您可以在Internet上找到并访问服务. 通过指定资源名称,该名称对应于或命名服务中的记录,并返回建立资源连接所需的信息.
JNDI充当在JMS中查找和访问发送目标或消息源的角色.
创建一个Connection对象工厂,对于两个不同的JMS消息模型,有QueueConnectionFactory和TopicConnectionFactory. 您可以通过JNDI找到ConnectionFactory对象.
目标是指消息生产者的消息发送目的地或消息使用者的消息源. 对于消息生产者,其目标是队列或主题;对于邮件使用者,其“目的地”也是队列或主题(即邮件的来源).
因此,目的地实际上是两种类型的对象: 队列和主题可以通过JNDI找到目的地.
Connection表示在客户端和JMS系统之间建立的连接(TCP / IP套接字的包装). 连接可以生成一个或多个会话. 像ConnectionFactory一样,有两种连接类型: QueueConnection和TopicConnection.
会话是用于操作消息的接口. 可以通过会话创建生产者,消费者,消息等. 会话提供交易功能. 当您需要使用会话发送/接收多条消息时,可以将这些发送/接收操作放入事务中. 同样,有QueueSession和TopicSession.
消息是由会话创建的,用于将消息发送到目的地. 同样,有两种类型的消息: QueueSender和TopicPublisher. 您可以调用消息生产者的方法(发送或发布方法)来发送消息.
消息使用者由会话创建,用于接收发送到目标的消息. 两种类型: QueueReceiver和TopicSubscriber. 它可以由会话的createReceiver(队列)或createSubscriber(主题)创建. 当然,会话的creatDurableSubscriber方法也可以用于创建持久订阅者.
消息侦听器. 如果注册了消息侦听器消息队列中间件,则消息到达后,将自动调用该侦听器的onMessage方法. EJB中的MDB(消息驱动Bean)是一种MessageListener.

深入研究JMS对于精通JAVA架构和EJB架构非常有帮助. 消息中间件也是大型分布式系统的必要组件. 此共享主要用于一般性介绍. 具体的深度需要大家学习,实践,总结和理解.
WebLogic和JBoss等常用的商用容器支持JMS标准,这对于开发非常方便. 但是免费的软件(例如Tomcat和Jetty)需要使用第三方消息中间件. 本节介绍常用的消息中间件(Active MQ,Rabbit MQ,Zero MQ,Kafka)及其特征.
ActiveMQ是Apache生产的最流行,功能最强大的开源消息总线. ActiveMQ是一个JMS Provider实现,它完全支持JMS1.1和J2EE 1.4规范. 尽管自从JMS规范引入以来已经很长时间了,但是JMS在当今的J2EE应用程序中仍然扮演着特殊的角色.
ActiveMQ功能如下:
多语言和协议编写客户端.
语言: Java,C,C ++,C#,Ruby,Perl,Python,PHP.
应用协议: OpenWire,Stomp REST,WS通知,XMPP,AMQP完全支持Spring的JMS1.1和J2EE 1.4规范(持久性,XA消息,事务).
ActiveMQ可以使用Spring轻松地嵌入到系统中,并且通过对J2EE服务器(例如Geronimo,JBoss 4,GlassFish,WebLogic)的测试,并通过了JCA 1.5资源适配器,还支持Spring2.0的功能. 配置允许ActiveMQ自动部署在任何J2EE 1.4兼容的商用服务器上. 它支持多种传输协议: VM,TCP,SSL,NIO,UDP,JGroups,JXTA通过JDBC和日志支持高速消息持久性. 旨在确保高性能集群,客户端服务器,对等支持Ajax支持和Axis集成可以轻松地调用嵌入式JMS提供程序进行测试
RabbitMQ是使用erlang语言开发的流行的开源消息队列系统. RabbitMQ是AMQP(高级消息队列协议)的标准实现. 支持多个客户端,例如: Python,Ruby,.NET,Java,JMS,C,PHP,ActionScript,XMPP,STOMP等,支持AJAX,持久性. 它用于在分布式系统中存储和转发消息,并且在易用性,可伸缩性和高可用性方面表现良好.

RabbitMQ
上图中有几个重要概念:
消息队列的使用过程如下:
客户端连接到消息队列服务器并打开一个通道. 客户端声明一个交换并设置相关属性. 客户端声明一个队列并设置相关属性. 客户端使用路由密钥在交换和队列之间建立绑定关系. 客户将消息发布到交易所.
交换机收到消息后,它将根据消息的密钥和已设置的绑定路由消息,并将消息传递到一个或多个队列.
它被称为历史上最快的消息队列. 它实际上类似于一系列套接字接口. 他和Socket之间的区别是: 普通套接字是端到端的(1: 1的关系),但是ZMQ是N的关系M,人们对BSD套接字的更多了解是点对点连接,点对点连接. 点连接需要显式建立连接,破坏连接,选择协议(TCP / UDP)和处理错误等,ZMQ屏蔽了这些详细信息,以使您的Web编程更加轻松. ZMQ用于节点之间的通信. 节点可以是主机或进程.
引用官方声明: “ ZMQ(ZeroMQ缩写为ZMQ)是一个简单易用的传输层. 它是一个类似于框架的套接字库. 它使套接字编程更简单,更简洁并且具有ZMQ的明确目标是“成为标准网络协议栈的一部分,然后进入Linux内核. ”它是一种消息处理,可以在多个线程,核心和主机盒之间灵活地扩展队列库. 尚未见到它们的成功. 但是,毫无疑问,它是“传统” BSD套接字上非常有前途且要求更高的封装层. ZMQ使编写高性能网络应用程序变得极其简单和有趣.
特征是:
与RabbitMQ相比,ZMQ不像传统的消息队列服务器. 实际上,它根本不是服务器. 它更像是底层网络通信库. 它是Socket API之上的一层. 将封装,抽象网络通信,过程通信和线程通信集成到统一的API接口中. 支持“请求-答复”,“发布者-订阅者”,“并行管道”三种基本模型和扩展模型.
ZeroMQ高性能设计要点:
无锁队列模型
对于跨线程交互(客户端和会话)之间的数据交换通道管道,使用了无锁队列算法CAS;异步事件在管道的两端注册. 在管道中读取或写入消息时,它将自动触发读取和写入事件. 批处理算法
对于传统的消息处理,每条消息在发送和接收时都需要系统调用,因此对于大量消息,系统开销相对较大,并且zeroMQ已针对批消息进行了自适应优化. 您可以批量接收和发送消息. 多核下的线程绑定,无需CPU切换
zeroMQ与传统的多线程并发模式,信号量或关键部分不同,它充分利用了多核的优势. 每个内核都必须运行一个工作线程,以避免CPU在多线程之间切换开销.
Kafka是一个高吞吐量的分布式发布-订阅消息传递系统,可以处理消费者规模网站中的所有操作流数据. 此操作(Web浏览,搜索和其他用户操作)是现代网络上许多社交功能的关键因素. 由于吞吐量要求,通常通过处理日志和日志聚合来解析这些数据. 对于像Hadoop这样的日志数据和离线分析系统,但需要实时处理的限制,这是一个可行的解决方案. Kafka的目的是通过Hadoop的并行加载机制统一联机和脱机消息处理,并通过群集计算机提供实时消耗.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-176182-1.html
可是浙商历史上