RabbitMQ解耦订单模块

rabbitmq 可用于解耦、削峰、异步
异步处理 - 相比于传统的串行、并行方式,提高了系统吞吐量。
应用解耦 - 系统间通过消息通信,不用关心其他系统的处理。
流量削锋 - 可以通过消息队列长度控制请求量;可以缓解短时间内的高并发请 求。
日志处理 - 解决大量日志传输。
消息通讯 - 消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通 讯。比如实现点对点消
息队列,或者聊天室等。

在项目中遇到服务间耦合度过高的问题可以使用RabbitMQ 来解决。

A 系统的代码需要调用 B 系统的接口才能完成一个任务,假设 B 两个系统崩溃了,那么 A 系统就会出现超
时,导致整个系统不可用。如果使用消息队列可以将 A 调用 B 接口的参数放到队列里面, A 代码里面不再
直接去调用 B 系统的接口,而是让 B 系统订阅消费 A 发送过来的的消息(参数), B 系统根据这些消息
(参数)修改自己的逻辑即可, B 系统维护时,不会影响 A 系统的使用。

实现想法

把实际调用的 controller 当作提供者,订单模块开一个监听当作消费者,往通道里传输两个参数 1. 方法
标识(增上改方法) 2. 实际参数(增删改的参数)让消费者调用即可。消息报错处理我认为可以直接丢
弃这个消息,不处理的话报错会循环调用消费。手动应答应该也不需要。

操作代码

导入依赖

都是引用的 common 的core模块,在里面导入就行

业务代码

配置操作

给两个模块都加载rabbitmq的配置

先看看提供者 (也就是 yry 服务下的 bill 模块吧)
我新建了一个类用于区分原本的调用

实际代码
看添加方法的注解

java 复制代码
package com.ruoyi.yey.bill;
import com.alibaba.fastjson2.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.LinkedHashMap;
/**
* 解耦后的增删改订单操作
*/
@Api(tags = "订单管理")
@RequestMapping("/api/sys/fenBill")
@RestController
public class FenBillController {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private BillService billService ;
/**
* 测试方法,没有用
*/
@ApiOperation("MQ查询")
@GetMapping("/findAllByPageMQ")
public void findAllByPageMQ() {
BillEntity billEntity = new BillEntity();
billEntity.setId(1);
billEntity.setGoodsId(2222);
billEntity.setGoodsDesc("队列调用商品描述测试");
rabbitTemplate.convertAndSend("bill_queues",
JSON.toJSONString(billEntity));
}
@ApiOperation("添加")
@PostMapping("/add")
public void saveUser(@RequestBody @Validated BillEntity customAdmin) {
LinkedHashMap<Object,Object> map = new LinkedHashMap<>();
map.put("method", 1); //方法表示 添加
map.put("param",customAdmin); //传入参数
//放入通道等待监听消费
rabbitTemplate.convertAndSend("bill_queues", JSON.toJSONString(map));
}
@ApiOperation("修改")
@PostMapping("/edit")
public void editcl(@RequestBody @Validated BillEntity customAdmin) {
LinkedHashMap<Object,Object> map = new LinkedHashMap<>();
map.put("method", 2);
map.put("param",customAdmin);
rabbitTemplate.convertAndSend("bill_queues", JSON.toJSONString(map));
}
@ApiOperation("删除")
@DeleteMapping(value = "/delByIds/{ids}")
public void delByIds(@PathVariable int ids) {
LinkedHashMap<Object,Object> map = new LinkedHashMap<>();
map.put("method", 0);
map.put("param",ids);
rabbitTemplate.convertAndSend("bill_queues", JSON.toJSONString(map));
}
}

然后看看消费者模块怎么处理的

就是把原本模块给搬过来了主要注意 RabbitConfig 和 BillController 这俩类,其他没啥改动
自己看看代码吧,注解里写的都有。
RabbitConfig

java 复制代码
package com.ruoyi.yrybill.config;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* rabbitmq初始化队列,用于异步解耦
*/
@Configuration
public class RabbitConfig {
@Bean
public Queue limitQueue() {
//设置队列的初始化参数
Map<String, Object> map = new HashMap<String, Object>();
//指定消息队列的长度
map.put("x-max-length", 10);
//当队列满时,多余的消息直接拒绝接收,多余的消息被丢弃
map.put("x-overflow", "reject-publish");
/*
* 参数1:队列的名字
* 参数2:是否为持久队列,及时rabbitmq服务停机,之后在开机该队列也存在 一般队列默认
都是持久的
* 参数3:是否为排他队列,是否只能由自己可见(admin),其他用户看不到该队列
* 参数4:是否在不适用该队列是删除该队列
* 参数5:队列初始化的参数
*/
return new Queue("bill_queues",false,false,false,map);
}
}

BillController

java 复制代码
package com.ruoyi.yrybill.bill;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.web.controller.BaseController;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.io.IOException;
import java.util.LinkedHashMap;
@Repository
public class BillController extends BaseController {
@Autowired
private BillService billService ;
@RabbitListener(queues = "bill_queues")
public void billListener(Channel channel, Message message,String s) {
try{
//获取队列传入的JSON数据和标识
LinkedHashMap map = JSONObject.parseObject(s, LinkedHashMap.class);
//什么方法
Integer method = (Integer) map.get("method");
//判断一下掉什么方法处理业务,并转换为相应对象
if(1==method){
//参数转换为json
String param = JSON.toJSONString(map.get("param"));
add(JSON.parseObject(param,BillEntity.class));
}
if(0==method){
//数字直接强转了
delByIds((Integer)map.get("param"));
}
if(2==method){
//参数转换为json
String param = JSON.toJSONString(map.get("param"));
editcl(JSON.parseObject(param,BillEntity.class));
}
}catch (Exception e){
//处理失败报错抛弃消息并返回报错信息
try {
channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
throw new ServiceException("操作异常了捏!");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
/**
* 订单添加
* @param customAdmin
*/
public void add(BillEntity customAdmin) {
billService.add(customAdmin);
}
/**
* 订单修改
* @param customAdmin
*/
public void editcl(BillEntity customAdmin) {
billService.edit(customAdmin);
}
/**
* 订单删除
* @param
*/
public void delByIds(int ids) {
billService.delByIds(ids);
}
}
相关推荐
编程、小哥哥几秒前
spring之添加freemarker模版熏染
java·后端·spring
hong_zc9 分钟前
Spring 拦截器与统一功能的处理
java·后端·spring
User_芊芊君子11 分钟前
【Java】——数组深度解析(从内存原理到高效应用实践)
java·开发语言
珹洺1 小时前
C++从入门到实战(十)类和对象(最终部分)static成员,内部类,匿名对象与对象拷贝时的编译器优化详解
java·数据结构·c++·redis·后端·算法·链表
一 乐1 小时前
网红酒店|基于java+vue的网红酒店预定系统(源码+数据库+文档)
java·开发语言·数据库·毕业设计·论文·springboot·网红酒店预定系统
ai大师2 小时前
给聊天机器人装“短期记忆“:Flask版实现指南
后端·python·gpt·flask·oneapi·中转api·apikey
galileo20162 小时前
rust服务应用开发框架
后端·rust
xyliiiiiL3 小时前
从责任链模式聊到aware接口
java·开发语言
码农老起6 小时前
与Aspose.pdf类似的jar库分享
java·pdf·jar
程序猿小D7 小时前
第三百八十九节 JavaFX教程 - JavaFX WebEngine
java·eclipse·intellij-idea·vr·javafx