MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。
1、MQ特点: MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取或者订阅队列中的消息。MQ和JMS类似,但不同的是JMS是SUN JAVA消息中间件服务的一个标准和API定义,而MQ则是遵循了AMQP协议的具体实现和产品。
2、含义:RabbitMQ是一个在AMQP基础上完成的,可复用的企业消息系统。他遵循Mozilla Public License开源协议。
3、概念:RabbitMQ是流行的开源消息队列系统,用erlang语言开发。RabbitMQ是AMQP(高级消息队列协议)的标准实现。如果不熟悉AMQP,直接看RabbitMQ的文档会比较困难。不过它也只有几个关键概念,这里简单介绍。
RabbitMQ的结构图如下:
Broker:简单来说就是消息队列服务器实体。
消息队列的使用过程大概如下:
exchange接收到消息后,就根据消息的key和已经设置的binding,进行消息路由,将消息投递到一个或多个队列里。
exchange也有几个类型,完全根据key进行投递的叫做Direct交换机,例如,绑定时设置了routing key为”abc”,那么客户端提交的消息,只有设置了key为”abc”的才会投递到队列。对key进行模式匹配后进行投递的叫做Topic交换机,符号”#”匹配一个或多个词,符号”*”匹配正好一个词。例如”abc.#”匹配”abc.def.ghi”,”abc.*”只匹配”abc.def”。还有一种不需要key的,叫做Fanout交换机,它采取广播模式,一个消息进来时,投递到与该交换机绑定的所有队列。
RabbitMQ支持消息的持久化,也就是数据写在磁盘上,为了数据安全考虑,我想大多数用户都会选择持久化。消息队列持久化包括3个部分:
如果exchange和queue都是持久化的,那么它们之间的binding也是持久化的。如果exchange和queue两者之间有一个持久化,一个非持久化,就不允许建立绑定。
4、安装(Centos7):https://blog.csdn.net/typ1805/article/details/82744899
访问:http://192.168.0.132:15672/#/queues
1、添加pom.xml依赖
4.0.0
com.example.demo.rabbitmq
rabbitmq-demo
0.0.1-SNAPSHOT
jar
rabbitmq-demo
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.0.5.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-amqp
org.springframework.boot
spring-boot-maven-plugin
2、application.yml配置文件主要是对rabbimq的配置信息
server:
port: 8081
spring:
application:
name: rabbitmq-demo
rabbitmq:
host: 192.168.0.132
port: 5672
username: admin
password: admin
3、初始化创建队列、转发器,并把队列绑定到转发器(RabbitConfig.java)
package com.example.demo.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 路径:com.example.demo.rabbitmq.config
* 类名:
* 功能:队列配置
* 备注:
* 创建人:typ
* 创建时间:2018/9/23 21:46
* 修改人:
* 修改备注:
* 修改时间:
*/
@Configuration
public class RabbitConfig {
@Bean
public Queue helloQueue() {
return new Queue("hello");
}
@Bean
public Queue userQueue() {
return new Queue("user");
}
//===============以下是验证topic Exchange的队列==========
@Bean
public Queue queueMessage() {
return new Queue("topic.message");
}
@Bean
public Queue queueMessages() {
return new Queue("topic.messages");
}
//===============以上是验证topic Exchange的队列==========
//===============以下是验证Fanout Exchange的队列==========
@Bean
public Queue AMessage() {
return new Queue("fanout.A");
}
@Bean
public Queue BMessage() {
return new Queue("fanout.B");
}
@Bean
public Queue CMessage() {
return new Queue("fanout.C");
}
//===============以上是验证Fanout Exchange的队列==========
@Bean
TopicExchange exchange() {
return new TopicExchange("exchange");
}
@Bean
FanoutExchange fanoutExchange() {
return new FanoutExchange("fanoutExchange");
}
/**
* 将队列topic.message与exchange绑定,binding_key为topic.message,就是完全匹配
* @param queueMessage
* @param exchange
* @return
*/
@Bean
Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
}
/**
* 将队列topic.messages与exchange绑定,binding_key为topic.#,模糊匹配
* @param queueMessage
* @param exchange
* @return
*/
@Bean
Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {
return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
}
@Bean
Binding bindingExchangeA(Queue AMessage,FanoutExchange fanoutExchange) {
return BindingBuilder.bind(AMessage).to(fanoutExchange);
}
@Bean
Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(BMessage).to(fanoutExchange);
}
@Bean
Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(CMessage).to(fanoutExchange);
}
}
4、最简单的hello生产和消费实现(单生产者和单消费者)
生产者:
package com.example.demo.rabbitmq.service.oneToOne;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 路径:com.example.demo.rabbitmq.service
* 类名:
* 功能:生产者
* 备注:单生产者-单消费者
* 创建人:typ
* 创建时间:2018/9/23 21:49
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class HelloSender {
private static final Logger log = LoggerFactory.getLogger(HelloSender.class);
@Autowired
public AmqpTemplate amqpTemplate;
public void send(){
String context = "hello " + new Date();
log.info("Sender:" + context);
this.amqpTemplate.convertAndSend("hello",context);
}
}
消费者:
package com.example.demo.rabbitmq.service.oneToOne;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service
* 类名:
* 功能:消费者
* 备注:单生产者-单消费者
* 创建人:typ
* 创建时间:2018/9/23 22:14
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class HelloReceiver {
private static final Logger log = LoggerFactory.getLogger(HelloReceiver.class);
//监听器监听指定的Queue
@RabbitListener(queues="hello")
public void process(String hello){
log.info("Receiver:"+hello);
}
}
controller测试:
package com.example.demo.rabbitmq.controller;
import com.example.demo.rabbitmq.service.oneToOne.HelloSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 路径:com.example.demo.rabbitmq.controller
* 类名:
* 功能:《用一句描述一下》
* 备注:单生产者-单消费者
* 创建人:typ
* 创建时间:2018/9/23 22:35
* 修改人:
* 修改备注:
* 修改时间:
*/
@RestController
public class RabbitOneToOneTest {
@Autowired
private HelloSender helloSender;
@PostMapping("/hello")
public void hello(){
helloSender.send();
}
}
启动程序,执行:
http://localhost:8081/hello
结果如下:
Sender : hello1 Thu September 24 17:23:31 CST 2018
Receiver : hello1 Thu September 24 17:23:31 CST 2018
5、单生产者-多消费者
生产者:
package com.example.demo.rabbitmq.service.oneToMany;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 路径:com.example.demo.rabbitmq.service
* 类名:
* 功能:生产者
* 备注:单生产者-多消费者
* 创建人:typ
* 创建时间:2018/9/23 21:49
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class HelloSender1 {
private static final Logger log = LoggerFactory.getLogger(HelloSender1.class);
@Autowired
public AmqpTemplate amqpTemplate;
public void send(String msg){
String context = msg + new Date();
log.info("Sender1:" + context);
this.amqpTemplate.convertAndSend("hello",context);
}
}
消费者1:
package com.example.demo.rabbitmq.service.oneToMany;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service
* 类名:
* 功能:消费者1
* 备注:单生产者-多消费者
* 创建人:typ
* 创建时间:2018/9/23 22:14
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class HelloReceiver1 {
private static final Logger log = LoggerFactory.getLogger(HelloReceiver1.class);
//监听器监听指定的Queue
@RabbitListener(queues="hello")
public void process(String hello){
log.info("Receiver1:"+hello);
}
}
消费者2:
package com.example.demo.rabbitmq.service.oneToMany;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service
* 类名:
* 功能:消费者2
* 备注:单生产者-多消费者
* 创建人:typ
* 创建时间:2018/9/23 22:14
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class HelloReceiver2 {
private static final Logger log = LoggerFactory.getLogger(HelloReceiver2.class);
//监听器监听指定的Queue
@RabbitListener(queues="hello")
public void process(String hello){
log.info("Receiver2:"+hello);
}
}
controller测试:
package com.example.demo.rabbitmq.controller;
import com.example.demo.rabbitmq.service.oneToMany.HelloSender1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 路径:com.example.demo.rabbitmq.controller
* 类名:
* 功能:《用一句描述一下》
* 备注:单生产者-多消费者
* 创建人:typ
* 创建时间:2018/9/23 22:35
* 修改人:
* 修改备注:
* 修改时间:
*/
@RestController
public class RabbitOneToManyTest {
@Autowired
private HelloSender1 helloSender;
/**
* 方法名:
* 功能:单生产者-多消费者
* 描述:
* 创建人:typ
* 创建时间:2018/9/23 22:46
* 修改人:
* 修改描述:
* 修改时间:
*/
@PostMapping("/oneToMany")
public void ontToMany(){
for (int i=0;i<10;i++){
helloSender.send("hello smg:"+i);
}
}
}
6、多生产者-多消费者
生产者1:
package com.example.demo.rabbitmq.service.manyToMany;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 路径:com.example.demo.rabbitmq.service
* 类名:
* 功能:生产者1
* 备注:多生产者-多消费者
* 创建人:typ
* 创建时间:2018/9/23 21:49
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class HelloSenderA {
private static final Logger log = LoggerFactory.getLogger(HelloSenderA.class);
@Autowired
public AmqpTemplate amqpTemplate;
public void send(String msg){
String context = msg + new Date();
log.info("SenderA:" + context);
this.amqpTemplate.convertAndSend("hello",context);
}
}
生产者2:
package com.example.demo.rabbitmq.service.manyToMany;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 路径:com.example.demo.rabbitmq.service
* 类名:
* 功能:生产者2
* 备注:多生产者-多消费者
* 创建人:typ
* 创建时间:2018/9/23 21:49
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class HelloSenderB {
private static final Logger log = LoggerFactory.getLogger(HelloSenderB.class);
@Autowired
public AmqpTemplate amqpTemplate;
public void send(String msg){
String context = msg + new Date();
log.info("SenderB:" + context);
this.amqpTemplate.convertAndSend("hello",context);
}
}
消费者1:
package com.example.demo.rabbitmq.service.manyToMany;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service
* 类名:
* 功能:消费者1
* 备注:多生产者-多消费者
* 创建人:typ
* 创建时间:2018/9/23 22:14
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class HelloReceiverA {
private static final Logger log = LoggerFactory.getLogger(HelloReceiverA.class);
//监听器监听指定的Queue
@RabbitListener(queues="hello")
public void process(String hello){
log.info("ReceiverA:"+hello);
}
}
消费者2:
package com.example.demo.rabbitmq.service.manyToMany;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service
* 类名:
* 功能:消费者2
* 备注:多生产者-多消费者
* 创建人:typ
* 创建时间:2018/9/23 22:14
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class HelloReceiverB {
private static final Logger log = LoggerFactory.getLogger(HelloReceiverB.class);
//监听器监听指定的Queue
@RabbitListener(queues="hello")
public void process(String hello){
log.info("ReceiverB:"+hello);
}
}
controller测试:
package com.example.demo.rabbitmq.controller;
import com.example.demo.rabbitmq.service.manyToMany.HelloSenderA;
import com.example.demo.rabbitmq.service.manyToMany.HelloSenderB;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 路径:com.example.demo.rabbitmq.controller
* 类名:
* 功能:《用一句描述一下》
* 备注:多生产者-多消费者
* 创建人:typ
* 创建时间:2018/9/23 22:35
* 修改人:
* 修改备注:
* 修改时间:
*/
@RestController
public class RabbitManyToManyTest {
@Autowired
private HelloSenderA helloSenderA;
@Autowired
private HelloSenderB helloSenderB;
/**
* 方法名:
* 功能:多生产者-多消费者
* 描述:
* 创建人:typ
* 创建时间:2018/9/23 22:46
* 修改人:
* 修改描述:
* 修改时间:
*/
@PostMapping("/manyToMany")
public void ontToMany(){
for (int i=0;i<10;i++){
helloSenderA.send("hello smg:"+i);
helloSenderB.send("hello smg:"+i);
}
}
}
7、实体类传输,springboot完美的支持对象的发送和接收,不需要格外的配置。
实体类(必须实现序列化接口):
package com.example.demo.rabbitmq.service.entity;
import java.io.Serializable;
/**
* 路径:com.example.demo.rabbitmq.service.entity
* 类名:
* 功能:《用一句描述一下》
* 备注:
* 创建人:typ
* 创建时间:2018/9/24 19:59
* 修改人:
* 修改备注:
* 修改时间:
*/
public class User implements Serializable{
private String name;
private String pass;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
生产者:
package com.example.demo.rabbitmq.service.entity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service.entity
* 类名:
* 功能:实体类传输
* 备注:生产者
* 创建人:typ
* 创建时间:2018/9/24 20:01
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class UserSender {
private static final Logger log = LoggerFactory.getLogger(UserSender.class);
@Autowired
private AmqpTemplate amqpTemplate;
public void send() {
User user = new User();
user.setName("test");
user.setPass("123456");
log.info("user Sender:" + user.getName() + "," + user.getPass());
amqpTemplate.convertAndSend("user", user);
}
}
消费者:
package com.example.demo.rabbitmq.service.entity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service.entity
* 类名:
* 功能:实体类传输
* 备注:消费者
* 创建人:typ
* 创建时间:2018/9/24 20:07
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
@RabbitListener(queues = "user")
public class UserReceiver {
private static final Logger log = LoggerFactory.getLogger(UserReceiver.class);
@RabbitHandler
public void process(User user) {
log.info("user Receive:" + user.getName() + "," + user.getPass());
}
}
controller测试:
package com.example.demo.rabbitmq.controller;
import com.example.demo.rabbitmq.service.entity.UserSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 路径:com.example.demo.rabbitmq.controller
* 类名:
* 功能:实体类传输测试
* 备注:
* 创建人:typ
* 创建时间:2018/9/24 20:09
* 修改人:
* 修改备注:
* 修改时间:
*/
@RestController
public class RabbitUserTest {
@Autowired
private UserSender userSender;
@PostMapping("/userTest")
public void userTets(){
userSender.send();
}
}
8、topic ExChange示例
topic 是RabbitMQ中最灵活的一种方式,可以根据binding_key自由的绑定不同的队列。首先对topic规则配置,这里使用两个队列来测试(也就是在Application类中创建和绑定的topic.message和topic.messages两个队列),其中topic.message的bindting_key为“topic.message”,topic.messages的binding_key为“topic.#”。
生产者:
package com.example.demo.rabbitmq.service.topic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service.topic
* 类名:
* 功能:topic ExChange示例------生产者
* 备注:topic 是RabbitMQ中最灵活的一种方式,可以根据binding_key自由的绑定不同的队列
* 创建人:typ
* 创建时间:2018/9/24 20:12
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class TopicSender {
private static final Logger log = LoggerFactory.getLogger(TopicSender.class);
@Autowired
private AmqpTemplate rabbitTemplate;
public void send() {
String msg1 = "I am topic.mesaage msg1!";
log.info("sender1 : " + msg1);
this.rabbitTemplate.convertAndSend("exchange", "topic.message", msg1);
String msg2 = "I am topic.mesaages msg2!";
log.info("sender2 : " + msg2);
this.rabbitTemplate.convertAndSend("exchange", "topic.messages", msg2);
}
}
消费者1:
package com.example.demo.rabbitmq.service.topic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service.topic
* 类名:
* 功能:topic ExChange示例
* 备注:消费者1(topic.message)
* 创建人:typ
* 创建时间:2018/9/24 20:12
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
@RabbitListener(queues = "topic.message")
public class TopicReceiver1 {
private static final Logger log = LoggerFactory.getLogger(TopicReceiver1.class);
@RabbitHandler
public void process(String msg) {
log.info("topicReceiver1: " +msg);
}
}
消费者2:
package com.example.demo.rabbitmq.service.topic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service.topic
* 类名:
* 功能:topic ExChange示例
* 备注:消费者2(topic.messages)
* 创建人:typ
* 创建时间:2018/9/24 20:12
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
@RabbitListener(queues = "topic.messages")
public class TopicReceiver2 {
private static final Logger log = LoggerFactory.getLogger(TopicReceiver2.class);
@RabbitHandler
public void process(String msg) {
log.info("topicReceiver2 : " +msg);
}
}
controller测试:
package com.example.demo.rabbitmq.controller;
import com.example.demo.rabbitmq.service.topic.TopicSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 路径:com.example.demo.rabbitmq.controller
* 类名:
* 功能:topic ExChange示例
* 备注:
* 创建人:typ
* 创建时间:2018/9/24 20:21
* 修改人:
* 修改备注:
* 修改时间:
*/
@RestController
public class RabbitTopicTest {
@Autowired
private TopicSender topicSender;
@PostMapping("/topicTest")
public void topicTest(){
topicSender.send();
}
}
9、fanout ExChange示例
Fanout 就是我们熟悉的广播模式或者订阅模式,给Fanout转发器发送消息,绑定了这个转发器的所有队列都收到这个消息。
生产者:
package com.example.demo.rabbitmq.service.fanout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service.fanout
* 类名:
* 功能:fanout ExChange示例---生产者
* 备注:Fanout 就是我们熟悉的广播模式或者订阅模式,给Fanout转发器发送消息,绑定了这个转发器的所有队列都收到这个消息。
* 创建人:typ
* 创建时间:2018/9/24 21:10
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class FanoutSender {
private static final Logger log = LoggerFactory.getLogger(FanoutSender.class);
@Autowired
private AmqpTemplate rabbitTemplate;
public void send() {
String msg="fanoutSender :hello i am fanout";
log.info(msg);
this.rabbitTemplate.convertAndSend("fanoutExchange","abcd.ee", msg);
}
}
消费者1:
package com.example.demo.rabbitmq.service.fanout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service.fanout
* 类名:
* 功能:fanout ExChange示例
* 备注:消费者A
* 创建人:typ
* 创建时间:2018/9/24 21:10
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
@RabbitListener(queues = "fanout.A")
public class FanoutReceiverA {
private static final Logger log = LoggerFactory.getLogger(FanoutReceiverA.class);
@RabbitHandler
public void process(String msg) {
log.info("FanoutReceiverA : " + msg);
}
}
消费者2:
package com.example.demo.rabbitmq.service.fanout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service.fanout
* 类名:
* 功能:fanout ExChange示例
* 备注:消费者B
* 创建人:typ
* 创建时间:2018/9/24 21:10
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
@RabbitListener(queues = "fanout.B")
public class FanoutReceiverB {
private static final Logger log = LoggerFactory.getLogger(FanoutReceiverB.class);
@RabbitHandler
public void process(String msg) {
log.info("FanoutReceiverB : " + msg);
}
}
消费者3:
package com.example.demo.rabbitmq.service.fanout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service.fanout
* 类名:
* 功能:fanout ExChange示例
* 备注:消费者C
* 创建人:typ
* 创建时间:2018/9/24 21:10
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
@RabbitListener(queues = "fanout.C")
public class FanoutReceiverC {
private static final Logger log = LoggerFactory.getLogger(FanoutReceiverC.class);
@RabbitHandler
public void process(String msg) {
log.info("FanoutReceiverC : " + msg);
}
}
controller测试:
package com.example.demo.rabbitmq.controller;
import com.example.demo.rabbitmq.service.fanout.FanoutSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 路径:com.example.demo.rabbitmq.controller
* 类名:
* 功能:fanout ExChange示例
* 备注:
* 创建人:typ
* 创建时间:2018/9/24 22:11
* 修改人:
* 修改备注:
* 修改时间:
*/
@RestController
public class RabbitFanoutTest {
@Autowired
private FanoutSender fanoutSender;
@PostMapping("/fanoutTest")
public void fanoutTest() {
fanoutSender.send();
}
}
10、callback的消息发送
增加回调处理,这里不再使用application.properties默认配置的方式,会在程序中显示的使用文件中的配置信息。
rabbitmq配置类:
package com.example.demo.rabbitmq.service.callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
/**
* 路径:com.example.demo.rabbitmq.service.callback
* 类名:
* 功能:增加回调处理,这里不再使用application.properties默认配置的方式,会在程序中显示的使用文件中的配置信息。
* 备注:
* 创建人:typ
* 创建时间:2018/9/24 20:09
* 修改人:
* 修改备注:
* 修改时间:
*/
public class RabbitConfig {
private static final Logger log = LoggerFactory.getLogger(RabbitConfig.class);
@Value("${spring.rabbitmq.host}")
private String addresses;
@Value("${spring.rabbitmq.port}")
private String port;
@Value("${spring.rabbitmq.username}")
private String username;
@Value("${spring.rabbitmq.password}")
private String password;
@Value("${spring.rabbitmq.virtual-host}")
private String virtualHost;
@Value("${spring.rabbitmq.publisher-confirms}")
private boolean publisherConfirms;
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(addresses+":"+port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
//如果要进行消息回调,则这里必须要设置为true
connectionFactory.setPublisherConfirms(publisherConfirms);
return connectionFactory;
}
//因为要设置回调类,所以应是prototype类型,如果是singleton类型,则回调类为最后一次设置
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public RabbitTemplate rabbitTemplatenew() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
return template;
}
}
生产者:
package com.example.demo.rabbitmq.service.callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.UUID;
/**
* 路径:com.example.demo.rabbitmq.service.callback
* 类名:CallBackSender
* 功能:callback的消息发送-----生产者
* 创建人:typ
* 创建时间:2018/9/24 20:09
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
public class CallBackSender implements RabbitTemplate.ConfirmCallback{
private static final Logger log = LoggerFactory.getLogger(CallBackSender.class);
@Autowired
private RabbitTemplate rabbitTemplatenew;
public void send() {
rabbitTemplatenew.setConfirmCallback(this);
String msg="callbackSender : i am callback sender";
log.info(msg);
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
log.info("callbackSender UUID: " + correlationData.getId());
this.rabbitTemplatenew.convertAndSend("exchange", "topic.messages", msg, correlationData);
}
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
log.info("callbakck confirm: " + correlationData.getId());
}
}
消费者:
package com.example.demo.rabbitmq.service.callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.rabbitmq.service.callback
* 类名:
* 功能:callback的消息发送
* 备注:消费者
* 创建人:typ
* 创建时间:2018/9/24 20:12
* 修改人:
* 修改备注:
* 修改时间:
*/
@Component
@RabbitListener(queues = "topic.messages")
public class CallBackReceiver {
private static final Logger log = LoggerFactory.getLogger(CallBackReceiver.class);
@RabbitHandler
public void process(String msg) {
log.info("CallBackReceiver : " +msg);
}
}
controller测试:
package com.example.demo.rabbitmq.controller;
import com.example.demo.rabbitmq.service.callback.CallBackSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 路径:com.example.demo.rabbitmq.controller
* 类名:
* 功能:callback的消息发送
* 备注:
* 创建人:typ
* 创建时间:2018/9/24 22:20
* 修改人:
* 修改备注:
* 修改时间:
*/
@RestController
public class RabbitCallBackTest {
@Autowired
private CallBackSender callBackSender;
//执行代码可以看出callbackSender发出的UUID,收到了回应,又传回来了。
@PostMapping("/callback")
public void callbak() {
callBackSender.send();
}
}
欢迎关注