高并发架构系列:如何从0到1设计一个MQ消息队列
消息队列作为系统解耦,流量控制的利器,成为分布式系统核心组件之一。
如果你对消息队列背后的实现原理关注不多,其实了解消息队列背后的实现非常重要。
不仅知其然还要知其所以然,这才是一个优秀的工程师需要具备的特征。
今天,我们就一起来探讨设计一个消息队列背后的技术。
消息队列整体设计思路
主要是设计一个整体的消息被消费的数据流。
这里会涉及到:消息生产Producer、Broker(消息服务端)、消息消费者Consumer。
1.Producer(消息生产者):发送消息到Broker。
2.Broker(服务端):Broker这个概念主要来自于Apache的ActiveMQ,特指消息队列的服务端。
主要功能就是:把消息从发送端传送到接收端,这里会涉及到消息的存储、消息通讯机制等。
3.Consumer(消息消费者):从消息队列接收消息,consumer回复消费确认。
Broker(消息队列服务端)设计重点
1)消息的转储:在更合适的时间点投递,或者通过一系列手段辅助消息最终能送达消费机。
2)规范一种范式和通用的模式,以满足解耦、最终一致性、错峰等需求。
3)其实简单理解就是一个消息转发器,把一次RPC做成两次RPC,发送者把消息投递到broker,broker再将消息转发一手到接收端。
总结起来就是两次RPC加一次转储,如果要做消费确认,则是三次RPC。
为了实现上述消息队列的基础功能:
1)消息的传输
2)存储
3)消费
就需要涉及到如下三个方面的设计:
1)通信协议
2)存储选择
3)消费关系维护
通讯协议
消息Message:既是信息的载体,消息发送者需要知道如何构造消息,消息接收者需要知道如何解析消息,它们需要按照一种统一的格式描述消息,这种统一的格式称之为消息协议。
传统的通信协议标准有XMPP和AMQP协议等,现在更多的消息队列从性能的角度出发使用自己设计实现的通信协议。
1.JMS
JMS(Java MessageService)实际上是指JMS API。JMS是由Sun公司早期提出的消息标准,旨在为java应用提供统一的消息操作,包括创建消息、发送消息、接收消息等。
JMS通常包含如下一些角色:
JMS提供了两种消息模型:
1)点对点
2)以及publish-subscribe(发布订阅)模型。
当采用点对点模型时,消息将发送到一个队列,该队列的消息只能被一个消费者消费。
而采用发布订阅模型时,消息可以被多个消费者消费。
在发布订阅模型中,生产者和消费者完全独立,不需要感知对方的存在。
2.AMQP
AMQP是 Advanced Message Queuing Protocol,即高级消息队列协议。
AMQP不是一个具体的消息队列实现,而 是一个标准化的消息中间件协议。
目标是让不同语言,不同系统的应用互相通信,并提供一个简单统一的模型和编程接口。 目前主流的ActiveMQ和RabbitMQ都支持AMQP协议。
AMQP是一种协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。
JMS和AMQP比较
JMS: 只允许基于JAVA实现的消息平台的之间进行通信
AMQP: AMQP允许多种技术同时进行协议通信
**3.Kafka的通信协议
**
Kafka的Producer、Broker和Consumer之间采用的是一套自行设计的基于TCP层的协议。Kafka的这套协议完全是为了Kafka自身的业务需求而定制的。
存储选型
对于分布式系统,存储的选择有以下几种
1)内存
2)本地文件系统
3)分布式文件系统
4)nosql
5)DB
从速度上内存显然是最快的,对于允许消息丢失,消息堆积能力要求不高的场景(例如日志),内存会是比较好的选择。
DB则是最简单的实现可靠存储的方案,很适合用在可靠性要求很高,最终一致性的场景(例如交易消息),对于不需要100%保证数据完整性的场景,要求性能和消息堆积的场景,hbase也是一个很好的选择。
理论上,从速度来看,文件系统>分布式KV(持久化)>分布式文件系统>数据库,而可靠性却截然相反。
还是要从支持的业务场景出发作出最合理的选择,如果你们的消息队列是用来支持支付/交易等对可靠性要求非常高,但对性能和量的要求没有这么高,而且没有时间精力专门做文件存储系统的研究,DB是最好的选择。
对于不需要100%保证数据完整性的场景,要求性能和消息堆积的场景,hbase也是一个很好的选择,典型的比如 kafka的消息落地可以使用hadoop。
消费关系处理
现在我们的消息队列初步具备了转储消息的能力。
下面一个重要的事情就是解析发送接收关系,进行正确的消息投递了。
市面上的消息队列定义了一堆让人晕头转向的名词,如JMS 规范中的Topic/Queue,Kafka里面的Topic/Partition/ConsumerGroup,RabbitMQ里面的Exchange等等。
抛开现象看本质,无外乎是单播与广播的区别。
所谓单播,就是点到点;而广播,是一点对多点。
为了实现广播功能,我们必须要维护消费关系,通常消息队列本身不维护消费订阅关系,可以利用zookeeper等成熟的系统维护消费关系,在消费关系发生变化时下发通知。
消息队列需要支持高级特性
1.消息的顺序
2.投递可靠性保证
3.消息持久化
4.支持不同消息模型
5.多实例集群功能
6.事务特性等
除了上述的消息队列基本功能以外,消息队列在某些特殊的场景还需要支持事务,消息重试等功能。
以上就是如何设计一个消息队列MQ的介绍,由于篇幅关系,后续再详解消息队列需要支持的高级特性。
觉得有用请点赞支持,送你[架构学习资料包],资料包内容:
1.最新最全的架构师学习图谱高清版:架构师知识点一目了然;
2.架构师学习专题88期资料合集:配合图谱,学习更科学;
3.程序员高赞的架构师学习图书9本。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
【直播预告】:Java Spring Boot开发实战系列课程【第11讲】:消息中间件 RabbitMQ 与api源码解析
内容概要:mq消息中间件在高并发系统架构中扮演关键角色,阿里双11高并发使用了mq技术。本次课程一起学习最新Java Spring Boot 2.0、RabbitMQ中间件的最新特性与实战应用,同样会分析核心api源码。主讲人:徐雷(阿里云栖特邀Java专家)直播时间:2019年1月8日 周二 今晚20:00直播地点:【阿里Java技术进阶】钉钉群详情请看下方图片:想看免费直播的提前扫码入群,或点击link入群: http://tb.cn/gXRstIw前十讲均在群中有回放视频点击《史上最大Java群已经诞生啦 ~ 热爱Java的你快快加入啦 ~》了解本钉群
- 下一篇
2019,一线程序员该如何面对中年危机?
中年危机是真实存在的,即便有技术傍身,在一些特定阶段及环境下,还是难免对未来产生质疑与焦虑。一线程序员该如何面对中年危机呢?这是绝大多数程序员的困惑,这也是绝大多数职场人的困惑。希望大家能通过此篇找到一些方法。 一、程序员中年危机的焦虑 说到程序员的“中年危机”,这四个字承载着太多焦虑,而焦虑的原因主要有以下三点: 1、上有老下有小、左有房贷右有车贷,职业选择经不起任性; 2、自己不断增长的期望和实现之间的差距越来越大; 3、行业从业者更加年轻化,互联网寒冬人才需求缩减,自己却一直停滞不前遭遇瓶颈。 二、时代成就了我们 很长一段时间,我都在想,这些年程序员收入确实不错,程序员因此一度被特别关注,其实深入思考你会发现,我们也只是运气还行,恰好赶上历史机遇了而已,说直白点,这是智能手机和移动互联网带来的行业爆发式增长的结果。 互联网万众创业创新的那几年”猪都能飞起来”。而2018互联网寒冬“猪掉下来摔死了”,互联网也将迎来又一次行业巨变、人才洗牌,下面详解: 越来越多的大学生加入程序员这个行业,计算机专业的学生数量及质量都不断上升。根据教育部的统计,2016 年有高校毕业生 765 万人,...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- MySQL8.0.19开启GTID主从同步CentOS8
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS7设置SWAP分区,小内存服务器的救世主