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. 2887 Big String

    splay瞎搞一下,正解是分块数组或分块链表,但是学不会啊! #include<cstdio> #include<cstdlib> #include<iostream&g ...

  2. maven 新建项目时修改默认jre路径

    新建maven项目时,JRE System Library默认为J2SE-1.5 如果想修改为1.7,修改maven的settings.xml ,在profiles中添加 <profile> ...

  3. Maven+mybatis教程

    首先,配置maven 在eclipse中把maven路径和settings.xml文件配置好之后,否则后续会有一些问题 可以设一个环境变量M2_HOME指向你的maven安装目录 M2_HOME=G: ...

  4. BZOJ 1091([SCOI2003]分割多边形-分割直线)

    1091: [SCOI2003]分割多边形 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 223  Solved: 82 [Submit][id=10 ...

  5. js 终止执行的实现方法

    终止JS运行有如下几种可能: 1.终止函数的运行的方式有两种 (1)在函数中使用return,则当遇到return时,函数终止执行,控制权继续向下运行 (2)在函数中使用try-catch异常处理,需 ...

  6. IO流(字节流复制)01

    package ioDemo; import java.io.*; /** * IO流(字节流复制) * Created by lcj on 2017/11/2. */ public class bu ...

  7. Servlet访问Javabean并传结果给jsp

    1.先建立包名: 2.建立实体类 参考二维表,考虑各个字段名字.类型 在entity包里面建立一个类,代码如下: public class House { private String id; pri ...

  8. MySQL 高可用架构在业务层面细化分析研究

    相对于传统行业的相对服务时间9x9x6或者9x12x5,由于互联网电子商务以及互联网游戏的实时性,所以服务要求7*24小时,业务架构无论是应用还是数据库,都须要容灾互备.在mysql的体系中,最好通过 ...

  9. .NET的委托和匿名函数应用一例

    闲话休提,大家都是成年人,直接上代码.有代码有J8: delegate string dlgGetTotal(); void TongJi() { dlgGetTotal getTotalInt = ...

  10. (八)Java 修饰符

    Java 修饰符 Java语言提供了很多修饰符,主要分为以下两类: 访问修饰符 非访问修饰符 修饰符用来定义类.方法或者变量,通常放在语句的最前端.我们通过下面的例子来说明: public class ...