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 ...
随机推荐
- 学习Redis(一)
一.NoSQL 1.NoSql介绍 1.not only SQL,非关系型数据库,它能解决常规数据库的并发.IO与性能的瓶颈 2.解决以下问题: ① 对数据库的高并发读写需求 ② 大数据的高效存储和访 ...
- CSS自定义属性 —— 别说你懂CSS相对单位
前段时间试译了Keith J.Grant的CSS好书<CSS in Depth>,其中的第二章<Working with relative units>,书中对relative ...
- API的自动化测试
传统的测试工具在测试一个API的时候,必须手动填写这个API所需要接收的所有信息,比如一个查询航班动态的API,他接收两个输入字段,一个叫flight, 一个叫date,那么测试这个API的用户,需要 ...
- H5页面实现下载文件(apk、txt等)的三种方式
需求描述 接到的原始需求是这样的,有一个H5页面,页面中有个"点击下载"的按钮,点击之后,完成下载特定的apk.大概是下面这样的: 需求分析 接到需求的时候我偷乐了一下,这个H5页 ...
- C++中的算法头文件<algorithm>,<numeric>和<functional>
算法部分主要由头文件<algorithm>,<numeric>和<functional>组成.<algorithm>是所有STL头文件中最大的一个,它是 ...
- spring总览
Spring 概述 1. 什么是spring? Spring 是个java企业级应用的开源开发框架.Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用.Spring ...
- Tsunami: A Learned Multi-dimensional Index for Correlated Data and Skewed Workloads 论文解读(VLDB 2021)
Tsunami: A Learned Multi-dimensional Index for Correlated Data and Skewed Workloads 论文解读(VLDB 2021) ...
- SpringBoot利用自定义注解实现通用的JWT校验方案
利用注解开发一个通用的JWT前置校验功能 设计的预期: 系统中并不是所有的应用都需要JWT前置校验,这就需要额外设计一个注解Annotation来标识这个方法需要JWT前置校验.例如: @GetMap ...
- 纯css 实现动画的暂停和运动
<template> <div> <input id="stop" type="radio" name="p ...
- optimoptions requires Optimization Toolbox(optimoptions 需要 Optimization Toolbox)解决方法
问题:在下载版的matlab中做coursera的machine learning里的ex2,做到 1.2.3 Learning parameters using fminunc 时出现optimop ...