您现于de位置乃:亚博 > APP学习

亚博 2019-12-29 APP学习 179

消息队列de实用场景和逻辑

1 消息队列概述
消息队列中间件乃分布式系统中重要de组件 主要解决应用解耦 异步消息 流量削锋等问题 实现高性能 高可用 可伸缩和最终1致性架构.

目前使用较多de消息队列有ActiveMQ RabbitMQ ZeroMQ Kafka MetaMQ RocketMQ


2 消息队列应用场景
以下介绍消息队列于实际应用中常用de使用场景.异步处理 应用解耦 流量削锋和消息通讯4个场景.

2.1异步处理
场8得鳎河没ё⒉岷 需要发注册邮件和注册短信.传统de做法有两种 1.串行de方式;2.并行方式
a 串行方式:将注册信息写入数据库成功后 发送注册邮件 再发送注册短信.以上3个任务全部完成后 返回给客户端.

image.png

b 并行方式:将注册信息写入数据库成功后 发送注册邮件de同时 发送注册短信.以上3个任务完成后 返回给客户端.与串行de差别乃 并行de方式可以提高处理de时间

image.png

假设3个业务节点每个使用50毫秒钟 不考虑网络等其他开销 则串行方式de时间乃150毫秒 并行de时间可能乃100毫秒.
因为CPU于单位时间内处理de请求数乃1定de 假设CPU1秒内吞吐量乃100次.则串行方式1秒内CPU可处理de请求量乃7次(1000/150).并行方式处理de请求量乃10次(1000/100)
小结:如以上案例描述 传统de方式系统de性能(并发量 吞吐量 响应时间)会有瓶颈.如何解决这个问题呢?

引入消息队列 将不乃必须de业务逻辑 异步处理.改造后de架构如下:
image.png按照以上约定 用户de响应时间相当于乃注册信息写入数据库de时间 也就乃50毫秒.注册邮件 发送短信写入消息队列后 直接返回 因此写入消息队列de速度很快 基本可以忽略 因此用户de响应时间可能乃50毫秒.因此架构改变后 系统de吞吐量提高到每秒20 QPS.比串行提高了3倍 比并行提高了两倍.

2.2应用解耦
场8得鳎河没碌ズ 订单系统需要通知库存系统.传统de做法乃 订单系统调用库存系统de接口.如下图:
270324-20160730143219809-1948583125.png传统模式de缺点:假如库存系统无法访问 则订单减库存将失败 从而导致订单失败 订单系统与库存系统耦合

如何解决以上问题呢?引入应用消息队列后de方案 如下图:
270324-20160730143228325-953675504.png订单系统:用户下单后 订单系统完成持久化处理 将消息写入消息队列 返回用户订单下单成功
库存系统:订阅下单de消息 采用拉/推de方式 获取下单信息 库存系统根据下单信息 进行库存操作
假如:于下单时库存系统不能正常使用.也不影响正常下单 因为下单后 订单系统写入消息队列就不再关心其他de后续操作了.实现订单系统与库存系统de应用解耦

2.3流量削锋
流量削锋也乃消息队列中de常用场景 1般于秒杀或团抢活动中使用广泛.
应用场景:秒杀活动 1般会因为流量过大 导致流量暴增 应用挂掉.为解决这个问题 1般需要于应用前端加入消息队列.
a 可以控制活动de人数
b 可以缓解短时间内高流量压垮应用
270324-20160730151710106-2043115158.png用户de请求 服务器接收后 首先写入消息队列.假如消息队列长度超过好的数量 则直接抛弃用户请求或跳转到错误页面.
秒杀业务根据消息队列中de请求信息 再做后续处理

2.4日志处理
日志处理乃指将消息队列用于日志处理中 比如Kafkade应用 解决大量日志传输de问题.架构简化如下
270324-20160730152810934-1818295010.png日志采集客户端 负责日志数据采集 定时写受写入Kafka队列
Kafka消息队列 负责日志数据de接收 存储和转发
日志处理应用:订阅并消费kafka队列中de日志数据 

2.5消息通讯
消息通讯乃指 消息队列1般都内置了高效de通信机制 因此也可以用于纯de消息通讯.比如实现点对点消息队列 或者聊天室等
点对点通讯:
270324-20160730153544294-1894255488.png客户端A和客户端B使用同1队列 进行消息通讯.

聊天室通讯:
270324-20160730153550184-1160563716.png客户端A 客户端B 客户端N订阅同1主题 进行消息发布和接收.实现类似聊天室效果.

以上实际乃消息队列de两种消息模式 点对点或发布订阅模式.模型为示意图 供参考.


3 消息中间件示例 
3.1电商系统
270324-20160801102300309-25949110.jpg消息队列采用高可用 可持久化de消息中间件.比如Active MQ Rabbit MQ Rocket Mq.
(1)应用将主干逻辑处理完成后 写入消息队列.消息发送乃否成功可以开启消息de确认模式.(消息队列返回消息接收成功状态后 应用再返回 这样保障消息de完整性)
(2)扩展流程(发短信 配送处理)订阅队列消息.采用推或拉de方式获取消息并处理.
(3)消息将应用解耦de同时 带来了数据1致性问题 可以采用最终1致性方式解决.比如主数据写入数据库 扩展应用根据消息队列 并结合数据库方式实现基于消息队列de后续处理.

3.2日志收集系统
270324-20160801102309481-1983324345.jpg分为Zookeeper注册中心 日志收集客户端 Kafka集群和Storm集群(OtherApp)4部分组成.
Zookeeper注册中心 提出负载均衡和地址查找服务
日志收集客户端 用于采集应用系统de日志 并将数据推送到kafka队列
Kafka集群:接收 路由 存储 转发等消息处理
Storm集群:与OtherApp处于同1级别 采用拉de方式消费队列中de数据


4 JMS消息服务
讲消息队列就不得不提JMS .JMS(JAVA Message Service java消息服务)API乃1个消息服务de标准/规范 允许应用程序组件基于JavaEE平台创建 发送 接收和读取消息.它使分布式通信耦合度更低 消息服务更加可靠以及异步性.
于EJB架构中 有消息bean可以无缝de与JM消息服务集成.于J2EE架构模式中 有消息服务者模式 用于实现消息与应用直接de解耦.

4.1消息模型
于JMS标准中 有两种消息模型P2P(Point to Point),Publish/Subscribe(Pub/Sub).

4.1.1 P2P模式
270324-20160802140753731-1936750467.pngP2P模式包含3个角色:消息队列(Queue) 发送者(Sender) 接收者(Receiver).每个消息都被发送到1个特定de队列 接收者从队列中获取消息.队列保留着消息 直到他们被消费或超时.

P2Pde特点
每个消息只有1个消费者(Consumer)(即1旦被消费 消息就不再于消息队列中)
发送者和接收者之间于时间上没有依赖性 也就乃说当发送者发送了消息之后 不管接收者有没有正于运行 它不会影响到消息被发送到队列
接收者于成功接收消息之后需向队列应答成功 
如果希望发送de每个消息都会被成功处理de话 那么需要P2P模式.

4.1.2 Pub/Sub模式
270324-20160802140802043-807024073.png包含3个角色主题(Topic) 发布者(Publisher) 订阅者(Subscriber) 多个发布者将消息发送到Topic 系统将这些消息传递给多个订阅者.

Pub/Subde特点
每个消息可以有多个消费者
发布者和订阅者之间有时间上de依赖性.针对某个主题(Topic)de订阅者 它必须创建1个订阅者之后 才能消费发布者de消息
为了消费消息 订阅者必须保持运行de状态
为了缓和这样严格de时间相关性 JMS允许订阅者创建1个可持久化de订阅.这样 即使订阅者没有被激活(运行) 它也能接收到发布者de消息.
如果希望发送de消息可以不被做任何处理 或者只被1个消息者处理 或者可以被多个消费者处理de话 那么可以采用Pub/Sub模型.

4.2消息消费
于JMS中 消息de产生和消费都乃异步de.对于消费来说 JMSde消息者可以通过两种方式来消费消息.
(1)同步
订阅者或接收者通过receive方法来接收消息 receive方法于接收到消息之前(或超时之前)将1直阻塞;

(2)异步
订阅者或接收者可以注册为1个消息监听器.当消息到达之后 系统自动调用监听器deonMessage方法.

JNDI:Java命名和目录接口,乃1种标准deJava命名系统接口.可以于网络上查找和访问服务.通过指定1个资源名称 该名称对应于数据库或命名服务中de1个记录 同时返回资源连接建立所必须de信息.
JNDI于JMS中起到查找和访问发送目标或消息来源de作用.


MQ选型对比文档

20160506134211236.png


5 常用消息队列

1般商用de容器 比如WebLogic JBoss 都支持JMS标准 开发上很方便.但免费de比如Tomcat Jetty等则需要使用第3方de消息中间件.本部分内容介绍常用de消息中间件(Active MQ,Rabbit MQ Zero MQ,Kafka)以8莇e特点.

5.1 ActiveMQ
ActiveMQ 乃Apache出品 最流行de 能力强劲de开源消息总线.ActiveMQ 乃1个完全支持JMS1.1和J2EE 1.4规范de JMS Provider实现 尽管JMS规范出台已经乃很久de事情了 但乃JMS于当今deJ2EE应用中间仍然扮演着特殊de地位.

ActiveMQ特性如下:
⒈ 多种语言和协议编写客户端.语言: Java,C,C++,C#,Ruby,Perl,Python,APP.应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
⒉ 完全支持JMS1.1和J2EE 1.4规范 (持久化 XA消息 事务)
⒊ 对Springde支持 ActiveMQ可以很容易内嵌到使用Springde系统里面去 而且也支持Spring2.0de特性
⒋ 通过了常见J2EE服务器(如 Geronimo,JBoss 4,GlassFish,WebLogic)de测试 其中通过JCA 1.5 resource adaptorsde配置 可以让ActiveMQ可以自动de部署到任何兼容J2EE 1.4 商业服务器上
⒌ 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
⒍ 支持通过JDBC和journal提供高速de消息持久化
⒎ 从设计上保证了高性能de集群 客户端-服务器 点对点
⒏ 支持Ajax
⒐ 支持与Axisde整合
⒑ 可以很容易得调用内嵌JMS provider 进行测试

5.2 Kafka
Kafka乃1种高吞吐量de分布式发布订阅消息系统 它可以处理消费者规模de网站中de所有动作流数据. 这种动作(网页浏览 搜索和其他用户de行动)乃于现代网络上de许多社会功能de1个关键因素. 这些数据通常乃由于吞吐量de要求而通过处理日志和日志聚合来解决. 对于像Hadoopde1样de日志数据和离线分析系统 但又要求实时处理de限制 这乃1个可行de解决方案.Kafkade目de乃通过Hadoopde并行加载机制来统1线上和离线de消息处理 也乃为了通过集群机来提供实时de消费.

Kafka乃1种高吞吐量de分布式发布订阅消息系统 有如下特性:
通过O(1)de磁盘数据结构提供消息de持久化 这种结构对于即使数以TBde消息存储也能够保持长时间de稳定性能.(文件追加de方式写入数据 过期de数据定期删除)
高吞吐量:即使乃非常普通de硬件Kafka也可以支持每秒数百万de消息
支持通过Kafka服务器和消费机集群来分区消息
支持Hadoop并行数据加载
Kafka相关概念
Broker
Kafka集群包含1个或多个服务器 这种服务器被称为broker[5]
Topic
每条发布到Kafka集群de消息都有1个类别 这个类别被称为Topic.(物理上不同Topicde消息分开存储 逻辑上1个Topicde消息虽然保存于1个或多个broker上但用户只需指定消息deTopic即可生产或消费数据而不必关心数据存于何处)
Partition
Parition乃物理上de概念 每个Topic包含1个或多个Partition.
Producer
负责发布消息到Kafka broker
Consumer
消息消费者 向Kafka broker读取消息de客户端.
Consumer Group
每个Consumer属于1个特定deConsumer Group(可为每个Consumer指定group name 若不指定group name则属于默认degroup).
1般应用于大数据日志处理或对实时性(少量延迟) 可靠性(少量丢数据)要求稍低de场景使用.


评论