一、应用场景:

(1) 异步操作:

任务异步处理将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。

(2) 解耦:

应用程序解耦合MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合

(3) 削峰:

在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见;如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用MQ能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。

(4) 可恢复性:

系统的一部分组件失效时,不会影响到整个系统。MQ降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。

二、概述:

(1)两种主流方式:

AMQP:

是一种协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。

JMS:

即Java消息服务(JavaMessage Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

AMQP 与 JMS 区别

JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。JMS规定了两种消息模式;而AMQP的消息模式更加丰富.

(2)市场上常见的消息队列有如下:

  • ActiveMQ:基于JMS实现, 比较均衡, 不是最快的, 也不是最稳定的.
  • ZeroMQ:基于C语言开发, 目前最好的队列系统.
  • RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好, 数据基本上不会丢失
  • RocketMQ:基于JMS,阿里巴巴产品, 目前已经捐献给apahce, 还在孵化器中孵化.
  • Kafka:类似MQ的产品;分布式消息系统,高吞吐量, 目前最快的消息服务器, 不保证数据完整性.

三、 RabbitMQ工作原理

组成部分说明如下:

  • Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue。
  • Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。
  • Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的消费方。
  • Producer:消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。
  • Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。

消息发布接收流程:

-----发送消息

1、生产者和Broker建立TCP连接。

2、生产者和Broker建立通道。

3、生产者通过通道消息发送给Broker,由Exchange将消息进行转发。

4、Exchange将消息转发到指定的Queue(队列)

----接收消息

1、消费者和Broker建立TCP连接

2、消费者和Broker建立通道

3、消费者监听指定的Queue(队列)

4、当有消息到达Queue时Broker默认将消息推送给消费者。

5、消费者接收到消息。

相关定义:

  • Broker: 简单来说就是消息队列服务器实体
  • Exchange: 消息交换机,它指定消息按什么规则,路由到哪个队列
  • Queue: 消息队列载体,每个消息都会被投入到一个或多个队列
  • Binding: 绑定,它的作用就是把exchange和queue按照路由规则绑定起来
  • Routing Key: 路由关键字,exchange根据这个关键字进行消息投递
  • VHost: 虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
  • Producer: 消息生产者,就是投递消息的程序
  • Consumer: 消息消费者,就是接受消息的程序
  • Channel: 消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务

由Exchange、Queue、RoutingKey三个才能决定一个从Exchange到Queue的唯一的线路。

四、安装及配置rabbitMQ

(1) linux安装rabbitMQ容器

  • 下载镜像
  docker pull rabbitmq:management
  • 创建容器
   docker run -di --name=myrabbitmq -p 5671:5617 -p 5672:5672 -p4369:4369 -p 15671:15671 -p 15672:15672 -p 25672:25672 rabbitmq:management
   15672 (if management plugin is enabled.管理界面 )15671 management监听端口5672, 5671 (AMQP 0-9-1 without and with TLS 消息队列协议是一个消息协议)4369 (epmd) epmd 代表 Erlang 端口映射守护进程25672 (Erlang distribution)
  • 访问后台

浏览器中输入地址

http://服务器ip:15672/
  • 设置容器开机自动启动
docker update --restart=always 容器ID

(2) 用户以及Virtual Hosts配置

1、 用户角色

RabbitMQ在安装好后,可以访问http://服务器ip:15672;其自带了guest/guest的用户名和密码;如果需要创建自定义用户;那么也可以登录管理界面后,如下操作:

角色说明:

  • 超级管理员(administrator)可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操作。
  • 监控者(monitoring)可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
  • 策略制定者(policymaker)可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。
  • 普通管理者(management)仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。
  • 其他无法登陆管理控制台,通常就是普通的生产者和消费者。
2、 Virtual Hosts配置

像mysql拥有数据库的概念并且可以指定用户对库和表等操作的权限。RabbitMQ也有类似的权限管理;在RabbitMQ中可以虚拟消息服务器Virtual Host,每个Virtual Hosts相当于一个相对独立的RabbitMQ服务器,每个VirtualHost之间是相互隔离的。exchange、queue、message不能互通。相当于mysql的db。Virtual Name一般以/开头。

  • 创建Virtual Hosts
  • 设置Virtual Hosts权限

  • 创建交换机
  • 创建队列
  • 交换机绑定队列

  • 发消息
  • 接收消息

五、Spring Boot整合RabbitMQ

生产者工程:

  • application.yml文件配置RabbitMQ相关信息;
  • 在生产者工程中编写配置类,用于创建交换机和队列,并进行绑定
  • 注入RabbitTemplate对象,通过RabbitTemplate对象发送消息到交换机

消费者工程:

  • application.yml文件配置RabbitMQ相关信息
  • 创建消息处理类,用于接收队列中的消息并进行处理

创建父工程

 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-parent</artifactId><version>2.1.6.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies>

生产者工程&消费者工程

yml文件一样

spring:rabbitmq:host: 122.51.207.162port: 5672virtual-host: /laoshentou   # 地址username:                  # rabbitmq账号password:                   # rabbitmq密码

各自创建springboot启动类

创建交换机/队列代码

package com.rabbitmq.producer.config;import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RabbitMQConfig {/*** 主题交换器的名称*/public static final String TOPIC_EXCHANGE = "topicExchange";/*** 搜索队列*/public static final String SEARCH_QUEUE = "searchQueue";/*** 插入队列*/public static final String INSERT_QUEUE = "insertQueue";/*** 通配符*/public static final String ROUTING_KEY = "it.#";/*** 主题模式交换机*/@Beanpublic Exchange topicExchange() {return new TopicExchange(TOPIC_EXCHANGE);}/*** 搜索队列*/@Beanpublic Queue searchQueue() {return new Queue(SEARCH_QUEUE);}/*** 插入队列*/@Beanpublic Queue insertQueue() {return new Queue(INSERT_QUEUE);}/*** 主题交换机绑定搜索队列*/@Beanpublic Binding bindingSearchQueueToTopicExchange() {return BindingBuilder.bind(searchQueue()).to(topicExchange()).with(ROUTING_KEY).noargs();}/*** 主题交换机绑定插入队列*/@Beanpublic Binding bindingInsertQueueToTopicExchange() {return BindingBuilder.bind(insertQueue()).to(topicExchange()).with(ROUTING_KEY).noargs();}
}

生产者代码:

package com.rabbitmq.producer;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@SpringBootTest(classes = ProducerApplication.class)
@RunWith(SpringRunner.class)
public class TestSimple {@Autowiredprivate RabbitTemplate rabbitTemplate;/*** 简单模式:一个生产者,一个消费者,不需要设置交换机(使用的是默认的交换机,routing key与队列名一致)*/@Testpublic void testSimpleSend() {//发消息,形参为指定的队列名和要发送的消息内容for (int i = 0; i < 5; i++) {rabbitTemplate.convertAndSend("simple_queue", "测试简单模式!" + i);}}/*** 工作队列模式:一个生产者,多个消费者(竞争关系),不需要设置交换机(使用的是默认的交换机,routing key与队列名一致)*/@Testpublic void testWorkSend() {for (int i = 0; i < 5; i++) {rabbitTemplate.convertAndSend("work_queue", "work模式:" + i);}}/*** 广播模式/发布订阅模式* 一个生产者发,多个消费者通过不同队列接,所有人都可以接到* 需要设置类型为fanout的交换机,并且交换机和队列进行绑定,当发送消息到交换机后,交换机会将消息发送到绑定的队列*/@Testpublic void testPubAndSubSend() {for (int i = 0; i < 5; i++) {rabbitTemplate.convertAndSend("fanout_exchange", "", "发布订阅/广播模式:" + i);}}/*** 路由模式* 需要设置类型为direct的交换机,交换机和队列进行绑定,并且指定routing key* 当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列* - 交换机direct_exchange将routing key为insert的消息发给绑定了对应routing key的队列direct_queue_insert* direct_exchange ==> routing key(insert)  ==> direct_queue_insert* direct_exchange ==> routing key(update)  ==> direct_queue_update*/@Testpublic void testDirectSend1() {for (int i = 0; i < 5; i++) {rabbitTemplate.convertAndSend("direct_exchange", "insertKey", "路由模式(insertKey):" + i);}}@Testpublic void testDirectSend2() {for (int i = 0; i < 5; i++) {rabbitTemplate.convertAndSend("direct_exchange", "updateKey", "路由模式(updateKey):" + i);}}/*** 通配符/主题模式* 需要设置类型为topic的交换机,交换机和队列进行绑定,并且制定通配符方式的routing key* 当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列* item后面加一个`.`的routing key(例如item.goods) 使用item.*可以接受* item后面加一个或多个`.`的routing key(例如item.goods.spu) 使用item.#可以接受* - 交换机topic_exchange将routing key为item.goods的消息发送到绑定的队列,routing key为item.*和item.#的队列都能接收到* - 交换机topic_exchange将routing key为item.goods.spu的消息发送到绑定的队列,routing key为item.#的队列才能接收到*/@Testpublic void testTopicSend1() {for (int i = 0; i < 5; i++) {rabbitTemplate.convertAndSend("topic_exchange", "item.goods", "通配符/主题模式(item.goods):" + i);}}@Testpublic void testTopicSend2() {for (int i = 0; i < 5; i++) {rabbitTemplate.convertAndSend("topic_exchange", "item.goods.spu", "通配符/主题模式(item.goods.spu):" + i);}}
}

消费者代码

简单模式

package com.rabbitmq.consumer.listener;import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
@RabbitListener(queues = "simple_queue")
public class SimpleListener {@RabbitHandlerpublic void testListener(String message) {System.out.println("简单模式:" + message);}
}

工作队列模式1

package com.rabbitmq.consumer.listener;import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
@RabbitListener(queues = "work_queue")
public class WorkListener1 {@RabbitHandlerpublic void testListener(String message) {System.out.println("工作队列模式1:" + message);}
}

工作队列模式2

package com.rabbitmq.consumer.listener;import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class WorkListener2 {@RabbitListener(queues = "work_queue")public void testListener1(String message) {System.out.println("工作队列模式2:" + message);}@RabbitListener(queues = "work_queue")public void testListener2(String message) {System.out.println("工作队列模式3:" + message);}
}

发布订阅/广播模式

package com.rabbitmq.consumer.listener;import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class PubAndSunListener {@RabbitListener(queues = "pubandsub1_queue")public void testListener1(String message){System.out.println("发布订阅/广播模式1:"+message);}@RabbitListener(queues = "pubandsub2_queue")public void testListener2(String message){System.out.println("发布订阅/广播模式2:"+message);}
}

路由模式

package com.rabbitmq.consumer.listener;import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class DirectListener {@RabbitListener(queues = "direct_queue_insert")public void testListener1(String message) {System.out.println("路由模式(insertKey):" + message);}@RabbitListener(queues = "direct_queue_update")public void testListener2(String message) {System.out.println("路由模式(updatekey):" + message);}
}

通配符/主题模式

package com.rabbitmq.consumer.listener;import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class TopicListener {@RabbitListener(queues = "topic_queue_item*")public void testListener1(String message){System.out.println("通配符/主题模式(item.goods):" + message);}@RabbitListener(queues = "topic_queue_item#")public void testListener2(String message){System.out.println("通配符/主题模式(item.goods.spu):" + message);}
}

六、rabbitMQ五种模式

(1)简单模式



(2)工作队列模式




(3)发布订阅模式/广播模式



(4)路由模式



(5)通配符模式



(6)RabbitMQ模式总结

工作模式:

1、简单模式 HelloWorld : 一个生产者、一个消费者,不需要设置交换机(使用默认的交换机,routingKey与队列名一致)

2、工作队列模式 Work Queue: 一个生产者、多个消费者(竞争关系),不需要设置交换机(使用默认的交换机)

3、发布订阅模式 Publish/subscribe: 需要设置类型为fanout的交换机,并且交换机和队列进行绑定,当发送消息到交换机后,交换机会将消息发送到绑定的队列

4、路由模式 Routing: 需要设置类型为direct的交换机,交换机和队列进行绑定,并且指定routing key,当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列

5、通配符模式 Topic: 需要设置类型为topic的交换机,交换机和队列进行绑定,并且指定通配符方式的routing key,当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列

rabbitMQ概述/在springboot下测试五种模式相关推荐

  1. Linux 下的五种 IO 模型

    Linux 下的五种 IO 模型 来源:decaywood's Blog 概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2 ...

  2. qemu-kvm磁盘读写的缓冲(cache)的五种模式

    qemu-kvm磁盘读写的缓冲(cache)模式一共有五种,分别是 writethrough, wirteback, none, unsafe, directsync 当你对VM读写磁盘的性能有不同的 ...

  3. OSPF在NBMA网络中的五种模式

    帧中继网络中,可以使用多种OSPF配置,具体使用哪种取决于网络拓扑,下面是一些帧中继的拓扑类型: • 星形拓扑 又称为中央-分支拓扑,是最常用的拓扑类型,在这种拓扑中,远程站点与中央站点相连.星形拓扑 ...

  4. 帝国理工创新领袖:数据驱动创新的五种模式

    ◆ ◆ ◆ 前言 当今世界,数据为创新带来新动力.数据创造了新的产品和服务.产生了新的商业模式.带来了新的创业机会.英国帝国理工大学副校长.著名创新领袖David Gann博士提出了"数据驱 ...

  5. 如何关联php5与apche,PHP5在Apache下的两种模式的安装_php

    php 5.0.0 和PHP 4.0.38 于2004年7月13日同时发布,这是一个值得我们PHP爱好者的一大喜讯.期盼已久的PHP5终于出来了,我们可以更进一步的享受PHP新的功能和使用开发的乐趣. ...

  6. 关于无线网络的五种模式

    WIFI或者WLAN有5种模式:Router模式.AP模式.Repeater模式.Bridge模式.Cliet模式. 五种模式对应无线设备在无线网络中体现的不同角色.   1.Cliet模式:无线设备 ...

  7. springBoot整合rabbitmq并测试五种常用模型

    之前我们记录了原生java代码使用rabbitmq的方法,很简单,类似于原生jdbc代码一样,将连接对象抽离出来作为工具类,生产者和消费者通过工具类获取连接对象,进而获取通道对象,再注册交换机或者是队 ...

  8. 一篇文章学会RabbitMQ。SpringAMQP操作RabbitMQ。RabbitMQ五种模式及其代码实现。

    目录 一.同步与异步调用: 一)同步调用: 二)异步调用: 三)使用建议: 四)MQ种类 二.SpringAMQP 1.导入依赖: 2.启动相关服务: 3.配置序列化: 三.Rabbit五种关系模式: ...

  9. RabbitMQ五种模式

    队列模式 五种队列 Queue--简单队列 Work queue--Work模式 Publish/Subscribe--发布/订阅者模式 Routing--路由模式 Topics--通配符模式 RPC ...

最新文章

  1. 【android-cocos2d-X2.2 环境配置】在Mac下搭建Cocos2d-X-android开发环境!
  2. C#的加密解密算法,包括Silverlight的MD5算法
  3. 工作是属于公司的,而职业生涯却是属于你自己的
  4. php ci提交表单验证,ci表单验证代码
  5. python xlwt xlrd 写入一行_自己总结python用xlrd\xlwt读写excel
  6. 【SpringCloud】Spring cloud Sleuth
  7. 2017 Multi-University Training Contest - Team 1
  8. Scaled Exponential Linear Unit
  9. Scratch编程入门
  10. 开发者必看的免费资源分享网站,让开发更简单!
  11. (CCF模拟)F1方程式冠军
  12. hdu 2502月之数
  13. python四边形转矩形_如何用PIL将矩形图像映射成四边形?
  14. 经济学原理上中国故事2019尔雅满分答案
  15. 自制操作系统日志——第二十五天
  16. Vim 复制 全部复制
  17. matlab如何添加数据集,如何用matlab把数据集导入数据库
  18. windows下SourceTree的安装位置,用于创建快捷方式到桌面
  19. STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器
  20. 金庸--王重阳谈学习、旅游、谈交友等等

热门文章

  1. 【汉诺塔】汉诺塔问题
  2. 如何在电脑上添加蓝牙耳机设备
  3. [前端框架]-VUE(下篇)
  4. 【前端框架】前端框架学习
  5. 星瞳科技 OpenMV 的使用
  6. 百度TTS,支持离线环境下使用
  7. 看完20000条微博,捋一捋杜蕾斯的营销套路
  8. Python+request 将获取的url和接口响应时间(timeout)写入到Excel中《八》
  9. Json转对象失败:No suitable constructor found for type [simple type, class com.test.faster.domain.respons
  10. 思岚A1与A2性能及建图测试比较