MQ 分布式消息队列入门

1 概述

消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。

目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等。

2 JMS简介

2.1 JMS概述

JMS(Java Messaging Service)是Java平台上有关面向消息中间件(MOM)的技术规范,它便于消息系统中的Java应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口简化企业应用的开发,翻译为Java消息服务。

JMS只是接口,并没有给予实现,实现JMS接口的消息中间件称为"JMS Provider",目前知名的开源MOM(Message Oriented Middleware,也就是消息中间件) 系统包含Apache的ActiveMQ、RocketMQ、Kafka以及RabbitMQ,可以说他们都是"基本遵循"和”参考“ JMS规范,有各自的特点和优势。

2.2 专业术语

  • JMS(Java Message Service):实现JMS 接口的消息中间件;
  • Provider(MessageProvider):消息的生产者;
  • Consumer(MessageConsumer):消息的消费者;
  • PTP(Point to Point):即点对点的消息模型,这也是非常经典的模型;
  • Pub / Sub(Publish/Subscribe):,即发布/订阅的消息模型;
  • Queue:队列目标,也就是我们常说的消息队列,一般都是会真正的进行物理存储;
  • Topic:主题目标;
  • ConnectionFactory:连接工厂,JMS 用它创建连接;
  • Connection:JMS 客户端到JMS Provider 的连接;
  • Destination:消息的目的地;
  • Session:会话,一个发送或接收消息的线程(这里Session可以类比Mybatis的Session);

2.3 JMS消息格式定义

  • StreamMessage 原始值的数据流
  • MapMessage 一套名称/值对
  • TextMessage 一个字符串对象
  • BytesMessage 一个未解释字节的数据流
  • ObjectMessage 一个序列化的Java对象

3 应用场景

分布式消息队列的使用场景大概有4个:

  • 异步处理
  • 应用解耦
  • 流量削锋
  • 消息通讯

3.1 异步处理

场景说明:用户信用卡消费后,需要执行两个业务功能:

  • 发送消费账单信息到用户邮箱
  • 发动消费信息短信到用户手机

简单的业务实现,一般两种,单线程方式和多线程方式:

  1. 单线程方式

在这里插入图片描述

如图所示,一共耗时60ms。

  1. 多线程方式

    在这里插入图片描述

    如图所示,一共耗时60ms。

  2. 消息队列方式

在这里插入图片描述

如图所示,一共耗时25ms。

架构的改变,明显比前面两种方式响应时间减少,提高了系统的吞吐量。

3.2 应用解耦

场景说明:以上面的用户消费为例子。如下图:

在这里插入图片描述

  • 支付系统:用户消费成功后,完成持久化处理,将消息写入消息队列,返回用户消费成功。
  • 短信系统:订阅短信的消息,采用拉/推的方式,获取消费信息,然后发送短信。
  • 邮件系统:订阅邮件的消息,采用拉/推的方式,获取消费信息,然后发送邮件。
  • 假如:当短信系统或者邮件系统出现故障的时候,不影响用户的消费。因为用户消费后,就将消费的记录写入到了消息队列中。实现了支付系统和短信系统以及邮件系统的应用解耦。

3.3 流量削锋

流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛。

应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。

  1. 可以控制活动的人数;
  2. 可以缓解短时间内高流量压垮应用;
  3. 将用户的请求,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面,例如 “当前页面太火爆了,请刷新后重试”;
  4. 秒杀业务根据消息队列中的请求信息,再做后续处理。

3.4 日志处理

日志处理是指将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题。架构简化如下:

在这里插入图片描述

  • 日志采集模块,负责监控系统应用产生的是日志信息,解析处理写入到kafka消费队列;
  • Kafka消息队列,负责日志数据的接收,存储和转发;
  • 日志分析模块:订阅并消费kafka队列中的日志数据;

4 应用实例

4.1 实时日志分析ELK平台

开源实时日志分析ELK平台能够完美的解决我们上述的问题,ELK由ElasticSearch、Logstash和Kiabana三个开源工具组成。官方网站:https://www.elastic.co/products

  • Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
  • Logstash是一个完全开源的工具,他可以对你的日志进行收集、过滤,并将其存储供以后使用(如,搜索)。
  • Kibana 也是一个开源和免费的工具,它Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志。

4.2 电商系统

在这里插入图片描述

消息队列采用高可用,可持久化的消息中间件。比如Active MQ,Rabbit MQ,Rocket Mq。

(1)应用将主干逻辑处理完成后,写入消息队列。消息发送是否成功可以开启消息的确认模式。(消息队列返回消息接收成功状态后,应用再返回,这样保障消息的完整性)

(2)扩展流程(发短信,配送处理)订阅队列消息。采用推或拉的方式获取消息并处理。

(3)消息将应用解耦的同时,带来了数据一致性问题,可以采用最终一致性方式解决。比如主数据写入数据库,扩展应用根据消息队列,并结合数据库方式实现基于消息队列的后续处理。

5 消息模型

5.1 P2P模式

P2P (Point to Point) 模式,即点对点模式,包含三个角色,消息队列(Queue),发送者(Sender),接收者(Receiver)。每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到他们被消费或超时。

  1. 每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)
  2. 发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列
  3. 接收者在成功接收消息之后需向队列应答成功

如果你希望发送的每个消息都应该被成功处理的话,那么你需要P2P模型。

5.2 Pub/Sub模式

Pub/Sub (Publish/Subscribe) 模式,即发布订阅模式,主题(Topic),发布者(Publisher),订阅者(Subscriber)。多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。

  1. 每个消息可以有多个消费者
  2. 发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息。
  3. 为了消费消息,订阅者必须保持运行的状态。

当然,为了缓和这种严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息。
如果你希望发送的消息可以不被做任何处理、或者被一个消费者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型。

6 相关信息

  • 博文不易,辛苦各位猿友点个关注和赞,感谢
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小P聊技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值