spring boot 集成 rabbitmq 指南
先决条件
- rabbitmq server 安装参考
- 一个添加了 web 依赖的 spring boot 项目 我的版本是
2.5.2
添加 maven 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
配置 application.yml
spring:
rabbitmq:
host: [此处填写 rabbitmq 服务地址(ip/domain),不包括[]]
port: [此处填写 rabbitmq 服务端口(默认是 5672),不包括[]]
username: [此处填写用户名,不包括[]]
password: [此处填写密码,不包括[]]
添加 config bean
这里面只需要配置 MessageConverter,其他的可以不用配置,它的作用是:
- 发布消息时,将 java bean 序列化为 rabbitmq 的消息
- 消费消息时,将 rabbitmq 消息反序列化为 java bean
如果你只用简单类型发布和接收消息,就大可不必配置这个了
package com.xx.config;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
/**
* MessageConverter用于将Java对象转换为RabbitMQ的消息。
*
* 默认情况下,Spring Boot使用SimpleMessageConverter,只能发送String和byte[]类型的消息,不太方便。
* 使用Jackson2JsonMessageConverter,我们就可以发送JavaBean对象,由Spring Boot自动序列化为JSON并以文本消息传递。
*
*
* convertAndSend 可以发送 java bean,接收方也可也自动反序列化
* https://www.liaoxuefeng.com/wiki/1252599548343744/1282385960239138
* http://www.ityouknow.com/springboot/2016/11/30/spring-boot-rabbitMQ.html
*
* @return
*/
@Bean
MessageConverter createMessageConverter() {
return new Jackson2JsonMessageConverter();
}
配置队列
- 配置 exchange
- 配置 queue
- 配置 binding
配置好之后,会自动创建 exchange、queue、binding,不需要手动在 rabbitmq web management ui 中手动操作了。
这块配置代码如下:
Constant 类根据自己情况,要不要看你自己
package com.xx.constant;
public final class Constant {
/**
* rabbitmq
*/
public static final class MQ {
/**
* XX 消息采用 Direct Exchange 模式
*/
public static final class XX {
private static final String namePrefix = "company-module-";
private static final String routingKeyPrefix = "company_module_";
private static final String create = "create";
private static final String update = "update";
public static final String exchange = namePrefix + "events";
public static final class Queue {
public static final String create = namePrefix + XX.create;
public static final String update = namePrefix + XX.update;
}
public static final class RoutingKey {
public static final String create = routingKeyPrefix + XX.create;
public static final String update = routingKeyPrefix + XX.update;
}
}
}
}
package com.xx.message.receiver.xx;
import com.xx.constant.Constant;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQXXConfig {
@Bean
public DirectExchange xxExchange() {
return new DirectExchange(Constant.MQ.XX.exchange, true, false);
}
@Bean
public Queue xxCreateQueue() {
return new Queue(Constant.MQ.XX.Queue.create, true, false, false);
}
@Bean
public Queue xxUpdateQueue() {
return new Queue(Constant.MQ.XX.Queue.update, true, false, false);
}
@Bean
public Binding xxCreateBinding() {
return BindingBuilder
.bind(xxCreateQueue())
.to(xxExchange())
.with(Constant.MQ.XX.RoutingKey.create);
}
@Bean
public Binding xxUpdateBinding() {
return BindingBuilder
.bind(xxUpdateQueue())
.to(xxExchange())
.with(Constant.MQ.XX.RoutingKey.update);
}
}
编写 messageReceiver
这里为了测试,把 create、update 的消息接收器写了两个,实际一个就可以了
package com.xx.message.receiver.xx;
import com.xx.constant.Constant;
import com.xx.exception.ServiceException;
import com.xx.vo.xx.XXVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* XX 消息接收器
*/
@Slf4j
@Component
public class RabbitMQXXMessageReceiver {
@RabbitListener(queues = Constant.MQ.XX.Queue.create)
public void onCreate1Message(XXVo message) {
log.info("mq:xx-create1 received <{}>", message);
// throw new ServiceException("报错模拟");
}
@RabbitListener(queues = Constant.MQ.XX.Queue.create)
public void onCreate2Message(XXVo message) {
log.info("mq:xx-create2 received <{}>", message);
// throw new ServiceException("报错模拟");
}
@RabbitListener(queues = Constant.MQ.XX.Queue.update)
public void onUpdate1Message(XXVo message) {
log.info("mq:xx-update1 received <{}>", message);
}
@RabbitListener(queues = Constant.MQ.XX.Queue.update)
public void onUpdate2Message(XXVo message) {
log.info("mq:xx-update2 received <{}>", message);
}
}
发布消息
你可以用自己喜欢的方式发送,我这里用 RestController
package com.xx.controller;
import com.xx.constant.Constant;
import com.xx.vo.xx.XXVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
@Slf4j
@RestController()
@RequestMapping("mq")
public class MQController {
private final RabbitTemplate rabbitTemplate;
public MQController(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
@GetMapping("create")
public ResponseEntity<String> create(){
final XXVo message = new XXVo()
.setName("myesn");
rabbitTemplate.convertAndSend(
Constant.MQ.XX.exchange,
Constant.MQ.XX.RoutingKey.create,
message);
// log.info("pub: send create message");
return ResponseEntity.ok("create pub");
}
@GetMapping("update")
public ResponseEntity<String> update(){
final XXVo message = new XXVo()
.setName("myesn");
rabbitTemplate.convertAndSend(
Constant.MQ.XX.exchange,
Constant.MQ.XX.RoutingKey.update,
message);
// log.info("pub: send update message");
return ResponseEntity.ok("update pub");
}
测试
现在可以通过 http://ip:port/mq/create 或 http://ip:port/mq/update 来测试消息的发布与消费
总结
示例中只使用了 direct exchange 模式,并且最终是 point to point 的通道类型(channel)。
在消息系统标准协议中,一个队列只能被一个消费者消费,如果想一个消息被多个消费者同时消费(发布消息后,所有消费者都能收到),那么就需要多个 queue 了。
测试总结(归纳文章要点):
- 自动创建 exchange、queue、binding,不需要手动在 web 上创建
- exchange、queue 持久化,rabbitmq 重启或无客户端时都不会自动删除 exchange、queue
- 消费者消费过程中报错,消息不会丢失,会自动切换到其他监听此队列的消费者(如果没有消息就一直被持久化),如果网站做了负载均衡,它也会自动让其他实例消费,如果负载均衡中所有节点中的消费者都报错,它也会一直循环在各个节点中消费消息,消息不会丢失,只有消费者成功消费消息(没有任何抛错),它才会从队列中移除此消息,点赞
文章参考
我自己也整理了一份 xmind 放在 github,但 repo 目前是 private 的,就不开放了。
spring boot 集成 rabbitmq 指南的更多相关文章
- Spring Boot 集成 RabbitMQ 实战
Spring Boot 集成 RabbitMQ 实战 特别说明: 本文主要参考了程序员 DD 的博客文章<Spring Boot中使用RabbitMQ>,在此向原作者表示感谢. Mac 上 ...
- Spring boot集成RabbitMQ(山东数漫江湖)
RabbitMQ简介 RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出 ...
- 85. Spring Boot集成RabbitMQ【从零开始学Spring Boot】
这一节我们介绍下Spring Boot整合RabbitMQ,对于RabbitMQ这里不过多的介绍,大家可以参考网络上的资源进行安装配置,本节重点是告诉大家如何在Spring Boot中使用Rabbit ...
- RabbitMQ(3) Spring boot集成RabbitMQ
springboot集成RabbitMQ非常简单,如果只是简单的使用配置非常少,springboot提供了spring-boot-starter-amqp项目对消息各种支持. 资源代码:练习用的代码. ...
- spring boot集成RabbitMQ
原文:https://www.jianshu.com/p/e1258c004314 RabbitMQ作为AMQP的代表性产品,在项目中大量使用.结合现在主流的spring boot,极大简化了开发过程 ...
- Spring Boot 集成RabbitMQ
在Spring Boot中整合RabbitMQ是非常容易的,通过在Spring Boot应用中整合RabbitMQ,实现一个简单的发送.接收消息的例子. 首先需要启动RabbitMQ服务,并且add一 ...
- spring boot 集成 rabbitmq
1.使用默认的AmqpTemplate生产消费pojo时,pojo需要implement Serializable,否则会抛出org.springframework.amqp.AmqpExceptio ...
- spring boot 集成RabbitMQ的异常
com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.clos ...
- Spring boot集成Rabbit MQ使用初体验
Spring boot集成Rabbit MQ使用初体验 1.rabbit mq基本特性 首先介绍一下rabbitMQ的几个特性 Asynchronous Messaging Supports mult ...
随机推荐
- ctfhub 过滤运算符 综合过滤练习 读取源代码 远程包含 eval执行 文件包含 php://input
过滤运算符 过滤了\和&那么尝试; 成功那么将flag cat出来 127.0.0.1;cat flag_27249269530391.php 得到flag 综合过滤练习 这次过滤有点多过滤了 ...
- HTTP-完整状态码表
HTTP状态码列表: 状态码 状态码英文名称 中文描述 100 Continue 继续.客户端应继续其请求 101 Switching Protocols 切换协议.服务器根据客户端的请求切换协议.只 ...
- 国际化相对时间格式化API:Intl.RelativeTimeFormat
原文:The Intl.RelativeTimeFormat API 作者:Mathias Bynens(@mathias) 现代 Web 应用程序通常使用"昨天","4 ...
- python-查找鞍点
[题目描述]对于给定5X5的整数矩阵,设计算法查找出所有的鞍点的信息(包括鞍点的值和行.列坐标,坐标从1开始). 提示:鞍点的特点:列上最小,行上最大. [练习要求]请给出源代码程序和运行测试结果 ...
- Android 动态控制OptionMenu的显示与隐藏
在有些场景下,可能需要动态的显示和隐藏optionmenu,可以这样实现:如果在activity中默认实现了方法: onCreateOptionsMenu(Menu menu) 那么该OptionMe ...
- java中Array(数组)的用法
8.Array(数组) 数组是作为对象来实现的.(really occupy the memopry,真实的占用内存 ) An array is a data structure that st ...
- CCF201812-2小明放学
题目背景 汉东省政法大学附属中学所在的光明区最近实施了名为"智慧光明"的智慧城市项目.具体到交通领域,通过"智慧光明"终端,可以看到光明区所有红绿灯此时此刻的状 ...
- mysql的下载和安装详细教程(windows)
Windows下安装MySQL详细教程 1.安装包下载 2.安装教程 (1)配置环境变量 (2)生成data文件 (3)安装MySQL (4)启动服务 (5)登录MySQL (6)查询用户密码 ...
- CommonsCollection6反序列化链学习
CommonsCollection6 1.前置知识 1.1.HashSet HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合.继承了序列化和集合 构造函数参数为空的话创建一 ...
- 关键字static、extern、volatile、详解及举例
一.预备知识 1. 什么是局部变量?什么是全局变量? 所谓局部变量,就是指在函数内部定义的变量的,只在该函数范围内有效. 全局变量是指,在函数外部定义的变量为外部变量,即全局变量.它 ...