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);
}
}
相关推荐
橙序员小站3 小时前
Agent Skill 是什么?一文讲透 Agent Skill 的设计与实现
前端·后端
怒放吧德德3 小时前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆5 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
开心就好20256 小时前
UniApp开发应用多平台上架全流程:H5小程序iOS和Android
后端·ios
悟空码字6 小时前
告别“屎山代码”:AI 代码整洁器让老项目重获新生
后端·aigc·ai编程
小码哥_常7 小时前
大厂不宠@Transactional,背后藏着啥秘密?
后端
奋斗小强7 小时前
内存危机突围战:从原理辨析到线上实战,彻底搞懂 OOM 与内存泄漏
后端
小码哥_常7 小时前
Spring Boot接口防抖秘籍:告别“手抖”,守护数据一致性
后端
心之语歌7 小时前
基于注解+拦截器的API动态路由实现方案
java·后端
None3217 小时前
【NestJs】基于Redlock装饰器分布式锁设计与实现
后端·node.js