分布式系统消息通信技术简介
分布式系统消息通信技术主要包括:
RPC(Remote Procedure Call Protocol)
一般是C/S
方式,同步的,跨语言跨平台,面向过程
CORBA(Common Object Request Broker Architecture)
从概念上扩展了RPC
,面向对象的,企业级的
面向对象中间件还有分布式组件对象模型DCOM
RMI(Remote Method Invocation)
面向对象方式的 Java RPC
WebService
基于Web
,C/S
或B/S
,跨系统跨平台跨网络。多为同步调用, 实时性要求较高
MOM(Message oriented Middleware)面向消息中间件
主要适用于消息通道、消息总线、消息路由和发布/订阅的场景。
目前主流标准有JMS(Java Message Service)
、AMQP(Advanced Message Queuing Protocol)
和STOMP(Streaming Text Oriented Messaging Protocol)
JMS
是Java
平台上的面向接口的消息规范,是一套API标准,并没有考虑异构系统。AMQP
是一个面向协议的,跟语言平台无关的消息传递应用层协议规范。STOMP
是流文本定向消息协议,是一种为MOM
设计的简单文本协议。AMQP
和STOMP
都是跟Http
处于同一层的协议。
AMQP 系统构架
在AMQP
模型中,消息的producer
将 Message
发送给 Exchange
,Exchange
负责交换 / 路由,将消息正确地转发给相应的 Queue
。消息的 Consumer
从 Queue
中读取消息。
消息队列
MQ 我们可以理解为消息队列(Message Queue),队列我们可以理解为管道。以管道的方式做消息传递。
简介
消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。
应用场景
消息队列在实际应用中常用在异步处理,应用解耦,流量削锋,日志处理和消息通讯
具体场景使用
异步处理
场景说明:用户注册后,需要发注册邮件和注册短信。
传统的做法有串行方式和并行方式。
串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。
并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间。
假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。
CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。
串行方式1秒内CPU可处理的请求量是7次(1000/150)。
并行方式处理的请求量是10次(1000/100)。
传统方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。
引入消息队列,将不是必须的业务逻辑,异步处理。
结果:用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,因此用户的响应时间可能是50毫秒。架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了两倍。
2.2应用解耦
场景说明:用户下单后,订单系统需要通知库存系统。
传统的做法是:订单系统调用库存系统的接口。
存在的问题
1.假如库存系统无法访问,则订单减库存将失败,从而导致订单失败
2.订单系统与库存系统耦合
引入应用消息队列后的架构:
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。
库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作。
结果:如果在下单时库存系统不能正常使用,也不影响正常下单。因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。这样就实现订单系统与库存系统的应用解耦。
2.3流量削锋
应用场景:秒杀活动或团抢活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。
这样可以控制活动的人数并可以缓解短时间内高流量压垮应用
结果:服务器接收到用户的请求后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。秒杀业务根据消息队列中的请求信息,再做后续处理。
2.4日志处理
日志处理是指将消息队列用在日志处理中
比如Kafka
的应用,解决大量日志传输的问题。
架构如下:
日志采集客户端,负责日志数据采集,定时写受写入Kafka
队列Kafka
消息队列,负责日志数据的接收,存储和转发
日志处理应用:订阅并消费kafka
队列中的日志数据
新浪kafka日志处理应用案例:
(1)Kafka:接收用户日志的消息队列。
(2)Logstash:做日志解析,统一成JSON
输出给Elasticsearch
。
(3)Elasticsearch:实时日志分析服务的核心技术,一个schemaless
,实时的数据存储服务,通过index
组织数据,兼具强大的搜索和统计功能。
(4)Kibana:基于Elasticsearch
的数据可视化组件,超强的数据可视化能力是众多公司选择ELK stack
的重要原因。
2.5消息通讯
消息队列一般都内置了高效的通信机制
应用场景:实现点对点消息队列,或者聊天室等。
点对点通讯:
客户端A和客户端B使用同一队列,进行消息通讯。
聊天室通讯:
客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收。实现类似聊天室效果。
以上实际是消息队列的两种消息模式,点对点或发布订阅模式。
流行的MQ框架
RabbitMQ
官网:https://www.rabbitmq.com/
官方文档:https://www.rabbitmq.com/documentation.html
github地址:https://github.com/rabbitmqRabbitMQ
是一个Advanced Message Queuing Protocol (AMQP)
的开源实现,由以高性能、健壮以及可伸缩性出名的Erlang写成,因此也是继承了这些优点。
RabbitMQ
具有健壮的消息确认机制、用户角色体系、以及认证和授权管理功能,保障消息可靠传输。灵活的交换器和绑定规则设置提供了强大的消息路由功能,同时支持AMQP
、HTTP
、STOMP
、MQTT
等协议。
重量级,更适合于企业级的开发。代理(Broker)
架构,对路由(Routing)
,负载均衡(Load balance)
或者数据持久化都有很好的支持。
此外,RabbitMQ
多节点集群的联合不依赖外部服务,支持服务的高可用,但服务的负载均衡需要使用第三方组件。
AMQP
中两个重要组件:Exchange
和 Queue
, 如下图所示,绿色的 X 就是 Exchange
,红色的是Queue
,这两者都在 Server
端,又称作 Broker
,这部分是 RabbitMQ
实现的,而蓝色的则是客户端,通常有 Producer
和 Consumer
两种类型
Kafka/Jafka
官网:https://kafka.apache.org/
官方文档:http://kafka.apache.org/documentation.html
Kafka的github地址:https://github.com/apache/kafka
Jafka的github地址:https://github.com/adyliu/jafkaLinkedIn
用Scala
语言开发。高吞吐量高性能支持跨语言分布式Publish/Subscribe
消息队列系统,而Jafka
是在Kafka
之上孵化而来的。快速持久化、高吞吐、完全的分布式系统、支持Hadoop
数据并行加载。
Kafka
具有高性能、高可用、分布式的技术特点。Kafka
强大的负载均衡和副本策略保证了节点的可靠性和高可用性,支持节点的动态扩展。是一种高吞吐量的分布式发布订阅消息系统。在设计实现上与传统消息中间件有较大差异,使用文件系统来管理消息的生命周期,能够在常数时间复杂度内提供消息持久化和数据访问,支持消息的批量发送和压缩传输,性能表现优异。
在Kafka
中,客户端和服务器之间的通信是通过简单,高性能,语言无关的TCP
协议完成的。
kafka
的目的是提供一个发布订阅解决方案,它可以处理消费者规模的网站中的所有动作流数据。Kafka
适用于大规模消息处理的应用场景,具有良好的可扩展性和性能优势。与传统消息系统不同,Kafka
还被广泛应用于日志聚合、流式数据处理等场景中。
ActiveMQ
官网:http://activemq.apache.org/
官方文档:http://activemq.apache.org/getting-started.html
github地址:https://github.com/apache/activemq
ActiveMQ是Apache出品,基于Java语言,最流行的,能力强劲的开源消息总线。基于STOMP协议ActiveMQ
是一种开源的,面向消息(MOM)
的中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信。居于两者(RabbitMQ
和 ZeroMQ
)之间,类似于ZeroMQ
,它可以部署于代理模式和P2P
模式。完全支持JMS1.1
和J2EE 1.4
规范。跨平台的,支持多种语言编写客户端 ,支持多种传输协议。ActiveMQ
的设计目标是提供标准的,面向消息的,能够跨越多语言和多系统的应用集成消息通信中间件。
Apollo
官网:http://activemq.apache.org/apollo/
官方文档:https://rocketmq.apache.org/docs/quick-start/
github地址:https://github.com/apache/rocketmq
ActiveMQ的下一代产品为Apollo,Apollo
以ActiveMQ
原型为基础,是一个更快、更可靠、更易于维护的消息代理工具。Apache
称Apollo
为最快、最强健的流文本定向消息协议STOMP(Streaming Text Orientated Message Protocol)
服务器。
RocketMQ
官网:https://rocketmq.apache.org/
官方文档:https://rocketmq.apache.org/docs/quick-start/
github地址:https://github.com/apache/rocketmq
RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。同时,广泛应用于多个领域,包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销、社交、即时通信、移动应用、手游、视频、物联网、车联网等。
ZeroMQ
官网地址:http://zeromq.org/
官方文档:http://api.zeromq.org/2-1:zmq
github地址:https://github.com/zeromq/libzmq
ZeroMQ是基于C/C++语言,以嵌入式网络编程库的形式实现了一个并行开发框架, 能够提供进程内(inproc)
、进程间(IPC)
、网络(TCP)
和广播方式的消息信道, 并支持扇出(fan-out)
、发布-订阅(pub-sub)
、任务分发(task distribution)
、请求/响应(request-reply)
等通信模式。
ZeroMQ的性能足以用来构建集群产品, 其异步I/O模型能够为多核消息系统提供足够的扩展性。ZeroMQ
支持许多高级消息场景,但必须实现ZeroMQ
框架中的各个块(比如Socket
或Device
等)。没有中间件架构,应用程序端点扮演了这个服务角色。部署简单,仅提供非持久性的队列。与RabbitMQ
相比,ZeroMQ
并不像是一个传统意义上的消息队列服务器,事实上,它根本不是一个服务器,它更像是一个底层的网络通讯库,在socket API
之上做了一层封装,将网络通讯、进程通讯和线程通讯抽象为统一的API
接口。
以上介绍的就是现在生存环境上用得比较多的MQ框架
至于MQ选型对比开源参考
https://www.sojson.com/blog/48.html
https://bravenewgeek.com/dissecting-message-queues/
https://blog.csdn.net/qq_35873847/article/details/78737796