消息中间件之RabbitMQ

一、概述

1.1 核心概念
1.1.1 JMS

JMS:Java Message Service,java消息服务,是一个消息服务的标准或者说是规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。
JMS是java的消息服务,JMS的客户端之间可以通过JMS服务进行异步的消息传输。

1.1.2 P2P

p2p:点对点发送,一个消息只能被消费一次
涉及:
消息队列(Queue)
发送者(Sender)
接收者(Receiver)
每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着信息,直到它们被消费或超时。
示意图:p2p示意图
特点:

  1. 不用同时在线
  2. 一个消息只能被消费1次
1.1.3 Pub/Sub

Pub/Sub:发布订阅,一个消息可以被消费多次
涉及角色:
主题(Topic)
发布者(Publisher)
订阅者(Subscriber)
客户端将消息发送到主题。多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。
示意图:Pub/Sub示意图
特点:

  1. 发布者和订阅者同时在线
  2. 一个消息可以被多个订阅者消费
1.1.4 MQ

MQ:消息中间件(MOM:Message Orient middleware),消息队列
作为系统间通信的必备技术,低耦合、可靠传输、流量控制、最终一致性
实现异步消息通信

1.2 MQ的优缺
  1. 解耦
    降低系统模块的耦合度
  2. 提高系统响应时间
  3. 异步消息
  4. 过载保护
    基于MQ实现削峰填谷
1.3 主流MQ
1.3.1 ActiveMQ

Apache下
完全支持Java的JMS协议
消息模式:1、点对点 2、发布订阅

1.3.2 RabbitMQ

Erlang语言实现的开源的MQ中间件,支持多种协议
主要的通信协议是AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用协议的一个开放标准,为面向消息的中间件设计。

1.3.3 Kafka

Apache下开源项目
高性能分布式消息队列,一般海量数据传输,大数据部门用
单机吞吐量:10w/s

1.3.4 RocketMQ

阿里 贡献给了Apache
参考了Kafka实现基于Java 消息中间件

1.3.5 ZeroMQ

消息传输最快

对比
  1. 从社区活跃度
  2. 持久化消息比较
    ZeroMQ不支持,ActiveMQ和RabbitMQ都支持。持久化消息主要是值我们机器在不可抗李因素等情况挂掉了,消息不会丢失的机制。
  3. 综合技术实现
    可靠性、灵活的路由、集群、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统等等。
    RabbitMQ/Kafka最好,ActiceMQ次之,ZeroMQ最差。当然ZeroMQ也可以做到,不过自己不过自己必须手动写代码实
    现,代码量不小。尤其是可靠性中的:持久性、投递确认、发布者证实和高可用性。
  4. 高并发
    毋庸置疑,RabbitMQ最高,原因是它的实现语言是天生具备高并发可用的erlang语言。
    比较示意图:各大消息中间件对比

二、RabbitMQ

2.1 简介

RabbitMQ是一个开源的AMQP实现,服务端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。

2.2 通信模块
  1. 发送端
    将消息发送到对应的交换器中,可以指定路由关键字
  2. MQ服务器
    将交换器获取到的消息,根据路由规则,转发到对应的消息队列中
  3. 消费端
    监听MQ服务器的消息队列,如果由消息变化,就会从消息队列中获取消息
2.3 核心类说明
  1. ConnectionFactory
    为Connection的制造工厂,可以设置服务器和端口号和账号密码等信息
  2. Connection
    是RabbitMQ的socket链接,它封装了socket协议相关部分逻辑
  3. Channel
    与RabbitMQ打交道的最重要的一个接口,我们大部分业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。
  4. Queue
    RabbitMQ的作用是存储消息,队列的特性是先进先出。即生产者生成消息被送到RabbitMQ的内部对象Queue中去,而消费者则是从Queue队列中取出数据
  5. Exchange(交换机、交换器)
    根据绑定的匹配规则,对消息进行匹配处理

三、RabbitMQ初体验

涉及角色:

3.1 MQ服务器

可以基于Docker安装RabbitMQ,记住其端口:
15672:网页版可视化服务器数据
5672:客户端连接的端口号

3.1.1 Docker安装RabbitMQ
  1. 搜索
    docker search rabbitmq:management
  2. 下载
    docker pull rabbitmq:management
  3. 创建
    docker create --name rabbitmq -p 15671:15671 -p 15672:15672 -p 5671:5671 -p 5672:5672 rabbitmq:management
    docker run -d --name rabbitmq -p 15671:15671 -p 15672:15672 -p 5671:5671 -p 5672:5672 rabbitmq:management
  4. 启动
    docker start rabbitmq
  5. 测试
    浏览器输入:
    http://服务器ip:15672
    用户名和密码:
    默认:guest 密码:guest

切记:开放端口,否则拦截

3.2 MQ消息发送者
//http://39.105.189.141:15672
public static void main(String[] args) throws IOException, TimeoutException {
  //1、创建连接工厂
  ConnectionFactory factory=new ConnectionFactory();
  //设置连接信息
  factory.setHost("39.105.189.141");
  factory.setPort(5672);
  factory.setUsername("guest");
  factory.setPassword("guest");
  //2、获取连接对象
  Connection connection=factory.newConnection();
  //3、获取通道对象
  Channel channel=connection.createChannel();
  //4、创建队列
  /**
  * 定义队列 参数说明
  * 1、队列名称
  * 2、是否持久化 队列消息是否存储到磁盘
  * 3、是否独占队列
  * 4、是否断开之后自动删除消息
  * 5、额外设置的数据信息 */
  channel.queueDeclare("queue1902",false,false,false,null);
  //5、发送消息
  /*参数说明:
  * 1、交换机名称
  * 2、队列名称
  * 3、属性参数
  * 4、发送的消息内容 要求字节*/
  channel.basicPublish("","queue1902",null,"你睡着了吗".getBytes());
  //6、关闭
  channel.close();
  connection.close();
}
3.3 MQ消息接收者
public static void main(String[] args) throws IOException, TimeoutException {
  //1、创建连接工厂
  ConnectionFactory factory=new ConnectionFactory();
  //设置连接信息
  factory.setHost("39.105.189.141");
  factory.setPort(5672);
  factory.setUsername("guest");
  factory.setPassword("guest");
  //2、获取连接对象
  Connection connection=factory.newConnection();
  //3、获取通道对象
  Channel channel=connection.createChannel();
  //4、创建队列
  /**
  * 定义队列 参数说明
  * 1、队列名称
  * 2、是否持久化 队列消息是否存储到磁盘
  * 3、是否独占队列
  * 4、是否断开之后自动删除消息
  * 5、额外设置的数据信息 */
  channel.queueDeclare("queue1902",false,false,false,null);
  //5、定义消费者
  Consumer consumer=new DefaultConsumer(channel){
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
      System.out.println("消费者:"+new String(body));
   }
 };
  //6、绑定消费者
  /**
  * 参数说明:
  * 1、队列名称
  * 2、是否自动应答
  * 3、消费者对象*/
  channel.basicConsume("queue1902",true,consumer);
}

四、RabbitMQ的消息模式

4.1 普通消息

点对点消息
一个消息只能消费一次
只需要队列就可以,不需要交换机
消息发送者和消息接收者者可以不同时在线

4.2 交换器消息

RabbitMQ特色就在于Exchange,主要有以下类型:
fanout:只要有消息就转发给绑定的队列,不会进行消息的路由判断
direct:会根据路由匹配规则,将消息发送到指定队列中,注意路由规则不支持特殊字符
topic:会根据路由匹配规则,将消息发送到指定队列中,注意路由规则支持特殊字符,比如:* #

五、使用场景

  1. 异步解耦
    如果某个方法,有很多逻辑需求处理,但是部分的逻辑处理和用户无关。那么就可以采用异步
  2. 耗时的操作
    网络请求、IO流、复杂的业务逻辑
  3. 削峰填谷
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容

  • 一.概述 1.1核心概念 1.1.1JMS JMS (JAVA MESSAGE SERVICE) 1.1.2 P2...
    青青子衿zq阅读 381评论 0 0
  • 这类 RabbitMQ 技术博客是打算出三套的,计算如下表格。原理上 RabbitMQ 的使用都是一致的,只不过不...
    小小奶狗阅读 1,831评论 0 0
  • 关于消息队列,从前年开始断断续续看了些资料,想写很久了,但一直没腾出空,近来分别碰到几个朋友聊这块的技术选型,是时...
    预流阅读 584,673评论 51 786
  • 关于消息队列,从前年开始断断续续看了些资料,想写很久了,但一直没腾出空,近来分别碰到几个朋友聊这块的技术选型,是时...
    中v中阅读 1,968评论 0 20
  • 关于消息队列,从前年开始断断续续看了些资料,想写很久了,但一直没腾出空,近来分别碰到几个朋友聊这块的技术选型,是时...
    Johnson_zx阅读 1,109评论 0 5