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的更多相关文章

  1. SpringBoot(十):SpringBoot的简单事务管理

    SpringBoot集成Mybatis之后,进行事务管理.SpringBoot使用事务非常简单,底层依然采用的是Spring本身提供的事务. 1.在入口类中使用注解@EnableTransaction ...

  2. 消息中间件——RabbitMQ(十)RabbitMQ整合SpringBoot实战!(全)

    前言 1. SpringBoot整合配置详解 publisher-confirms,实现一个监听器用于监听Broker端给我们返回的确认请求:RabbitTemplate.ConfirmCallbac ...

  3. 消息中间件——RabbitMQ(五)快速入门生产者与消费者,SpringBoot整合RabbitMQ!

    前言 本章我们来一次快速入门RabbitMQ--生产者与消费者.需要构建一个生产端与消费端的模型.什么意思呢?我们的生产者发送一条消息,投递到RabbitMQ集群也就是Broker. 我们的消费端进行 ...

  4. springboot(十四):springboot整合shiro-登录认证和权限管理(转)

    springboot(十四):springboot整合shiro-登录认证和权限管理 .embody{ padding:10px 10px 10px; margin:0 -20px; border-b ...

  5. springboot(十九)使用actuator监控应用【转】【补】

    springboot(十九)使用actuator监控应用 微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台的业务流会经过很多个微服务的 ...

  6. IDEA SpringBoot+JPA+MySql+Redis+RabbitMQ 秒杀系统

    先放上github地址:spike-system,可以直接下载完整项目运行测试 SpringBoot+JPA+MySql+Redis+RabbitMQ 秒杀系统 技术栈:SpringBoot, MyS ...

  7. 消息中间件——RabbitMQ(六)理解Exchange交换机核心概念!

    前言 来了解RabbitMQ一个重要的概念:Exchange交换机 1. Exchange概念 Exchange:接收消息,并根据路由键转发消息所绑定的队列. 蓝色框:客户端发送消息至交换机,通过路由 ...

  8. 消息中间件——RabbitMQ(七)高级特性全在这里!(上)

    前言 前面我们介绍了RabbitMQ的安装.各大消息中间件的对比.AMQP核心概念.管控台的使用.快速入门RabbitMQ.本章将介绍RabbitMQ的高级特性.分两篇(上/下)进行介绍. 消息如何保 ...

  9. 消息中间件——RabbitMQ(八)高级特性全在这里!(下)

    前言 上一篇消息中间件--RabbitMQ(七)高级特性全在这里!(上)中我们介绍了消息如何保障100%的投递成功?,幂等性概念详解,在海量订单产生的业务高峰期,如何避免消息的重复消费的问题?,Con ...

随机推荐

  1. Multiply Strings(字符串乘法模拟,包含了加法模拟)

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  2. Java日志框架-Logback手册中文版以及官方配置文档教程

    Logback手册中文版:(链接: https://pan.baidu.com/s/1bpMyasR 密码: 6u5c),虽然版本有点旧,但是大体意思差不多,先用中文版了解个大概,然后一切最新的配置以 ...

  3. 下一代的中间件必须是支持docker规范的

    下一代的中间件必须是支持docker规范的,这是中间件技术走向标准规范化的必经之路. 什么是 Docker? 答案是:Docker 是下一代的云计算模式.Docker 是下一代云计算的主流趋势. Do ...

  4. 【algorithm】尾递归

    尾递归和一般的递归不同在对内存的占用,普通递归创建stack累积而后计算收缩,尾递归只会占用恒量的内存(和迭代一样).SICP中描述了一个内存占用曲线,用以上答案中的Python代码为例(普通递归): ...

  5. curl 中文乱码

    curl 中文乱码 学习了:https://blog.csdn.net/thc1987/article/details/52583789 学习了: http://blog.itpub.net/2903 ...

  6. IntelliJ 中类似于Eclipse ctrl+q的是Ctrl+Shift+Backspace

    IntelliJ 中类似于Eclipse ctrl+q的是Ctrl+Shift+Backspace 回到刚刚编辑的地方: ctrl+alt+Left 是回到刚刚浏览的地方,不一定是编辑的地方,可能已经 ...

  7. 给工作赋予的新意义——Leo鉴书78

    现代社会学三大奠基人有两位名字里有"马克思",他们都是德国人.当中一位就是写<资本论>的卡尔•马克思,另一位就是<新教伦理与资本主义精神>的作者马克思•韦伯 ...

  8. 在Oracle数据库中使用NFS,怎样调优?

    MOS上有好多文章,基本上都跑不了以下三点: Setup can make a big difference 1. Network topology and load 2. NFS mount opt ...

  9. MD5加密解密帮助类

    using System; using System.Security.Cryptography; using System.Text; namespace Maticsoft.DBUtility { ...

  10. docker registry的CI规划

    目前代码全部署在docker中, 考虑用jenkins打包成docker包再推送到docker registry 打包推送过程中自动按照日期打标签,并且刷新latest