springboot(十)SpringBoot消息中间件RabbitMQ
github地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service
1.RabbitMQ简介
AMQP(高级消息队列协议)是一个异步消息传递所使用应用层协议规范,为面向消息中间件设计,基于此协议的客户端与消息中间件可以无视消息来源传递消息,不受客户端、消息中间件、不同的开发语言环境等条件的限制;
涉及概念解释:
Server(Broker):接收客户端连接,实现AMQP协议的消息队列和路由功能的进程; Virtual Host:虚拟主机的概念,类似权限控制组,一个Virtual Host里可以有多个Exchange和Queue。
Exchange:交换机,接收生产者发送的消息,并根据Routing Key将消息路由到服务器中的队列Queue。(这个有点类似于Nginx服务器的概念) ExchangeType:交换机类型决定了路由消息行为,RabbitMQ中有三种类型Exchange,分别是fanout、direct、topic; Message Queue:消息队列,用于存储还未被消费者消费的消息; Message:由Header和body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化、优先级是多少、由哪个Message Queue接收等;body是真正需要发送的数据内容; BindingKey:绑定关键字,将一个特定的Exchange和一个特定的Queue绑定起来。


2.RabbitMQ运行机制
2.1 Exchange类型
生产者发送消息不会向传统方式直接将消息投递到队列中,而是先将消息投递到交换机中,在由交换机转发到具体的队列,队列在将消息以推送或者拉取方式给消费者进行消费,这点Nginx有点类似。
交换机的作用根据具体的路由策略分发到不同的队列中,交换机有四种类型。
Direct exchange(直连交换机)是根据消息携带的路由键(routing key)将消息投递给对应队列的
Fanout exchange(扇型交换机)将消息路由给绑定到它身上的所有队列
Topic exchange(主题交换机)队列通过路由键绑定到交换机上,然后,交换机根据消息里的路由值,将消息路由给一个或多个绑定队列
Headers exchange(头交换机)类似主题交换机,但是头交换机使用多个消息属性来代替路由键建立路由规则。通过判断消息头的值能否与指定的绑定相匹配来确立路由规则
Headers 匹配 AMQP 消息的 header 而不是路由键, headers 交换器和 direct 交换器完全一致,但性能差很多,目前几乎用不到了,所以直接看另外三种类型:
2.1.1 Direct Exchange


消息中的路由键(routing key)如果和 Binding 中的 binding key 一致, 交换器就将消息发到对应的队列中。
路由键与队列名完全匹配,如果一个队列绑定到交换机要求路由键为“dog”,则只转发 routing key 标记为“dog”的消息,
不会转发“dog.puppy”,也不会转发“dog.guard”等等。它是完全匹配、单播的模式。
2.1.2 Fanout Exchange


每个发到 fanout 类型交换器的消息都会分到所有绑定的队列上去。
fanout 交换器不处理路由键,只是简单的将队列绑定到交换器上,每个发送到交换器的消息都会被转发到与该交换器绑定的所有队列上。
很像子网广播,每台子网内的主机都获得了一份复制的消息。fanout 类型转发消息是最快的。
2.1.3 Topic Exchange


topic 交换器通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。
它将路由键和绑定键的字符串切分成单词,这些单词之间用点隔开。它同样也会识别两个通配符:符号“#”和符号“*”。
#匹配0个或多个单词,*匹配一个单词。
3.RabbitMQ安装
基于docker的国内镜像安装(3-management带管理界面的rabbitmq),关于docker三分钟上手和常用指令这篇博客有汇总:https://www.cnblogs.com/hlkawa/p/9742015.html
> docker pull registry.docker-cn.com/library/rabbitmq:3-management
启动rabbitmq(-d 后台启动 -p 端口映射 5672 连接rabbirmq的端口 15672访问rabbitmq web管理界面的端口)
> docker run -d -p 5672:5672 -p 15672:15672 --name brian_rabbitmq xxxxxx(镜像name或者镜像ID)
rabbitmq的管理web访问url: ip:15672,默认的账户密码guest/guest

4.RabbitTemplate发送接受消息&序列化机制
4.1 引用依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
4.2 AmqpAdmin创建和删除 Queue, Exchange,Binding
ManageMQService.java
package com.kawa.mq;
import com.kawa.config.Contents;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ManageMQService {
@Autowired
AmqpAdmin amqpAdmin;
public void createExchange(String exchangeName,String mqType){
if(mqType.equals(Contents.DIRECT_EXCHANGE)){
amqpAdmin.declareExchange(new DirectExchange(exchangeName));
}
if(mqType.equals(Contents.FANOUT_EXCHANGE)){
amqpAdmin.declareExchange(new FanoutExchange(exchangeName));
}
if(mqType.equals(Contents.TOPIC_EXCHANGE)){
amqpAdmin.declareExchange(new TopicExchange(exchangeName));
}
}
public void removeExchange(String exchangeName){
amqpAdmin.deleteExchange(exchangeName);
}
public void createQueue(String queueName){
amqpAdmin.declareQueue(new Queue(queueName,true));
}
public void removeQueue(String queueName){
amqpAdmin.deleteQueue(queueName);
}
public void createBinding(String queueName, String exchangeName, String routingKey){
amqpAdmin.declareBinding(new Binding(queueName, Binding.DestinationType.QUEUE,exchangeName,routingKey,null));
}
public void removeBinding(String queueName, String exchangeName, String routingKey){
amqpAdmin.removeBinding(new Binding(queueName, Binding.DestinationType.QUEUE,exchangeName,routingKey,null));
}
}
4.3 使用RabbitTemplate发送消息
SendMessageService.java
package com.kawa.mq; import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; @Service
public class SendMessageService { @Autowired
RabbitTemplate rabbitTemplate; public void sendMessage(String exchange,String routingKey,Object obj){
//Message需要自己构造一个;定义消息体和消息头
//rabbitTemplate.send(exchange,routingKey,message); //object默认当成消息体,只需要传入发送对象,自动序列化发送给rabbitmq
rabbitTemplate.convertAndSend(exchange,routingKey,obj);
} }
4.4 测试创建 Queue, Exchange,Binding和发送消息
SpbDemoApplicationTests.java
@Test
public void sendMessage() {
manageMQService.createQueue("brian.test");
manageMQService.createExchange("brian",Contents.DIRECT_EXCHANGE);
manageMQService.createBinding("brian.test","brian","mymq");
Brian brian = new Brian();
User user = new User();
user.setId((long) 12345678);
user.setUsername("cassiel");
user.setPassword("#fyds");
List<String> list = new ArrayList<>();
list.add("我");
list.add("爱");
list.add("你");
list.add("中");
list.add("国");
Map<String,Object> map = new HashMap<>();
map.put("123","包邮");
brian.setKawadate(new Date());
brian.setLists(list);
brian.setObj(map);
brian.setUser(user);
sendMessageService.sendMessage("brian","mymq",brian);
}
查看结果


4.5 添加@RabbitListener监听和处理消息
在使用RabbitListener注解接收消息时,需要在启动类上加上数据@EnableRabbit
BrianService.java
package com.kawa.sercice; import com.kawa.pojo.Brian;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service; @Service
public class BrianService { @RabbitListener(queues = "brian.test")
public void receiveMessage(Brian brian){
System.out.println("接收到的消息体:" + brian);
}
}
4.6 启动工程查看测试结果

查看到队列里面消息已经没有了

springboot(十)SpringBoot消息中间件RabbitMQ的更多相关文章
- SpringBoot(十):SpringBoot的简单事务管理
SpringBoot集成Mybatis之后,进行事务管理.SpringBoot使用事务非常简单,底层依然采用的是Spring本身提供的事务. 1.在入口类中使用注解@EnableTransaction ...
- 消息中间件——RabbitMQ(十)RabbitMQ整合SpringBoot实战!(全)
前言 1. SpringBoot整合配置详解 publisher-confirms,实现一个监听器用于监听Broker端给我们返回的确认请求:RabbitTemplate.ConfirmCallbac ...
- 消息中间件——RabbitMQ(五)快速入门生产者与消费者,SpringBoot整合RabbitMQ!
前言 本章我们来一次快速入门RabbitMQ--生产者与消费者.需要构建一个生产端与消费端的模型.什么意思呢?我们的生产者发送一条消息,投递到RabbitMQ集群也就是Broker. 我们的消费端进行 ...
- springboot(十四):springboot整合shiro-登录认证和权限管理(转)
springboot(十四):springboot整合shiro-登录认证和权限管理 .embody{ padding:10px 10px 10px; margin:0 -20px; border-b ...
- springboot(十九)使用actuator监控应用【转】【补】
springboot(十九)使用actuator监控应用 微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台的业务流会经过很多个微服务的 ...
- IDEA SpringBoot+JPA+MySql+Redis+RabbitMQ 秒杀系统
先放上github地址:spike-system,可以直接下载完整项目运行测试 SpringBoot+JPA+MySql+Redis+RabbitMQ 秒杀系统 技术栈:SpringBoot, MyS ...
- 消息中间件——RabbitMQ(六)理解Exchange交换机核心概念!
前言 来了解RabbitMQ一个重要的概念:Exchange交换机 1. Exchange概念 Exchange:接收消息,并根据路由键转发消息所绑定的队列. 蓝色框:客户端发送消息至交换机,通过路由 ...
- 消息中间件——RabbitMQ(七)高级特性全在这里!(上)
前言 前面我们介绍了RabbitMQ的安装.各大消息中间件的对比.AMQP核心概念.管控台的使用.快速入门RabbitMQ.本章将介绍RabbitMQ的高级特性.分两篇(上/下)进行介绍. 消息如何保 ...
- 消息中间件——RabbitMQ(八)高级特性全在这里!(下)
前言 上一篇消息中间件--RabbitMQ(七)高级特性全在这里!(上)中我们介绍了消息如何保障100%的投递成功?,幂等性概念详解,在海量订单产生的业务高峰期,如何避免消息的重复消费的问题?,Con ...
随机推荐
- hdu 3237
dp 状态压缩 #include <cstdio> #include <cstdlib> #include <cmath> #include <map> ...
- 210 Course ScheduleII
/* * 210 Course ScheduleII * 2016-6-9 by Mingyang * http://www.jyuan92.com/blog/leetcode-course-sche ...
- html5开发手机打电话发短信功能
原文:http://www.open-open.com/code/view/1449843459332 在很多的手机网站上,有打电话和发短信的功能,对于这些功能是如何实现的呢.其实不难,今天我们就用h ...
- HDU3926Hand in Hand(搜索 或 并查集)
Problem Description In order to get rid of Conan, Kaitou KID disguises himself as a teacher in the k ...
- CSDN-markdown基本的语法说明
文件夹 概述 简介Markdown CSDN Markdown的功能支持 标题 Setext形式 atx形式 区块引用 分隔线 强调 列表 无序列表 有序列表 注意事项 链接 自己主动链接 普通文本链 ...
- win8 metro 自己写摄像头录像项目
这是要求不适用CameraCaptureUI等使用系统自带的 camera UI界面.要求我们自己写调用摄像头摄像的方法,如今我把我的程序贴下: UI界面的程序: <Page x:Class= ...
- Hdfs的ACL測试
Hadoop从2.4.0版本号開始支持hdfs的ACL,在CDH5.0其中也集成了该特性,以下对其进行一些測试: unnamed user (file owner) 文件的拥有者 unnamed gr ...
- 单片机远程控制步进电机、LED灯和蜂鸣器
通过採用C#语言实现的上位机控制单片机的步进电机模块.LED灯和蜂鸣器模块,使步进电机进行正.反转和停止并控制转速:LED灯模块进行有选择的呼吸式表达:蜂鸣器模块的開始和终止. 上位机通过串口和自己定 ...
- GridView根据一列自动计算(转载)
<%@ Page Language="C#" %> <%@ Import Namespace="System.Xml" %> <! ...
- iOS开发——高级篇——iOS开发之网络安全密码学
一.非对称加密 - RSA : + 公钥加密,私钥解密: + 私钥加密,公钥解密: + 只能通过因式分解来破解 二.对称加密 - DES - 3DES - AES (高级密码标准,美国国家安全局使用, ...