项目中使用消息队列改进——基于RabbitMQ

使用 RabbitMQ 实现消息队列

  1. 导入依赖
<!--AMQP依赖,包含RabbitMQ-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--防止消息转换时的乱码-->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
</dependency>
  1. 配置RabbitMQ
spring:rabbitmq:host: 192.168.72.100port: 5672 # 端口virtual-host: / # 虚拟主机username: zhl36 # 用户名password: zhl15737979065  # 密码
  1. 定义消息转换器,将 需要发送的消息对象 转成 json,否则在 RabbitMQ 的控制台获取的消息可能乱码
@Configuration
public class MessageConvert {@Beanpublic MessageConverter messageConverter(){return new Jackson2JsonMessageConverter();}
}
  1. 编写生产者和消费者
@Service(value = "VoucherOrderServiceImplPlus")
public class VoucherOrderServiceImplPlus extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {@Autowiredprivate ISeckillVoucherService seckillVoucherService;/*** 全局id生成器*/@Autowiredprivate RedisIdWorker redisIdWorker;@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Autowiredprivate RedissonClient redissonClient;// 使用 RabbitMQ 做消息队列@Autowiredprivate RabbitTemplate rabbitTemplate;private static final DefaultRedisScript<Long> SECKILL_SCRIPT;// 在类加载时加载lua脚本static {SECKILL_SCRIPT = new DefaultRedisScript<>();SECKILL_SCRIPT.setLocation(new ClassPathResource("seckill.lua"));SECKILL_SCRIPT.setResultType(Long.class);}/*** 生产者处理消息* @param voucherOrder*/public void handleVoucherOrder(VoucherOrder voucherOrder) {Long userId = voucherOrder.getUserId();RLock lock = redissonClient.getLock("lock:order:" + userId);boolean isLock = lock.tryLock();if (!isLock){log.error("请勿重复下单");}try {rabbitTemplate.convertAndSend(EXCHANGE_DIRECT,VOUCHERORDER_ROUTE_KEY,voucherOrder);} finally {lock.unlock();}}@Overridepublic Result secKillVoucher(Long voucherId) {/*** 执行lua脚本,判断返回值是否=0* ==0,可以正常下单* ==1,库存不足* ==2,用户重复下单*/Long userId = UserHolder.getUser().getId();Long result = stringRedisTemplate.execute(SECKILL_SCRIPT,Collections.emptyList(),voucherId.toString(),userId.toString());int r = result.intValue();if (r != 0) {return Result.fail(r == 1 ? "库存不足" : "不能重复下单");}long orderId = redisIdWorker.nextId("order");VoucherOrder voucherOrder = new VoucherOrder();voucherOrder.setId(orderId);voucherOrder.setUserId(userId);voucherOrder.setVoucherId(voucherId);// 把有购买资格的,把下单信息保存到 RabbitMQhandleVoucherOrder(voucherOrder);return Result.ok(orderId);}/*** 消费者处理优惠券订单 * 交换机使用的是默认的 DIRECT 方式* @param voucherOrder*/@RabbitListener(bindings = @QueueBinding(value = @Queue("voucherOrder.queue1"),exchange = @Exchange(name = EXCHANGE_DIRECT, type = ExchangeTypes.DIRECT),key = {VOUCHERORDER_ROUTE_KEY}))@Overridepublic void createVocherOrder(VoucherOrder voucherOrder) {Long userId = voucherOrder.getUserId();// 查询订单int count = query().eq("user_id", userId).eq("voucher_id", voucherOrder.getVoucherId()).count();if (count > 0) {log.error("您已购买过");}// 库存--boolean success = seckillVoucherService.update().setSql("stock = stock - 1")// 实际上 stock > 0 是 CAS 以乐观锁的方式防止超卖  where voucher_id = ? and stock > 0 ?.eq("voucher_id", voucherOrder.getVoucherId()).gt("stock", 0).update();if (!success) {log.error("库存不足");}// 订单++save(voucherOrder);}

基于Redis实现消息队列

基于List 的消息队列

Redis 的List 数据结构是一个双向链表,很容易模拟出队列效果。

https://redis.io/docs/latest/commands/?group=list

可以使用 BLPOP 或 BRPOP 实现阻塞效果,当有消息时就处理并返回。BLPOP 结合 RPUSH 或 BRPOP 结合 LPUSH 来实现。
在这里插入图片描述

基于List的消息队列的优缺点

优点:

  • 利用Redis 存储,不受限于JVM内存上限
  • 基于Redis的持久化机制,数据安全性有保证
  • 可以满足消息有序性

缺点:

  • 无法避免消息丢失
  • 只支持单消费者

基于PubSub的消息队列

SUBSCRIBE channel [channel] :订阅一个或多个频道
PUBLISH channel msg :向一个频道发送消息
PSUBSCRIBE pattern[pattern] :订阅与pattern格式匹配的所有频道
在这里插入图片描述

基于PubSub的消息队列的优缺点

优点:

  • 采用发布订阅模型,支持多生产、多消费

缺点:

  • 不支持数据持久化
  • 无法避免消息丢失
  • 消息堆积有上限,超出时数据丢失

基于Stream的消息队列

发送消息的命令:XADD
在这里插入图片描述读取消息的方式之一:XREAD
在这里插入图片描述

个人感觉太麻烦了,不如简单又好用的RabbitMQ😘

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/803674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jmeter如何录制https的系统性能脚本

在使用jmeter录制性能测试脚本时&#xff0c;会遇到网站为http和https两种情况&#xff0c;略有不同&#xff0c;下面介绍一下&#xff1a; 1.Jmeter录制http 1.测试计划–>添加–>非测试元件–>HTTP(S)测试脚本记录器 【HTTP(S)测试脚本记录器】有的版本叫【HTTP代…

基于ES-EKF的LiDAR/GNSS/IMU传感器融合轨迹估计(附项目源码)

基于改进EKF的LiDAR/GNSS/IMU传感器融合轨迹估计&#xff08;附项目源码&#xff09; 算法概述PredictionCorrectionES-EKF算法融合算法实现轨迹估计实验结果 最近在研究传感器融合&#xff0c;看到一个很好的开源项目&#xff0c;适合小白学习&#xff0c;为以后做传感器融合、…

.net 6 集成NLog

.net 6 webapi项目集成NLog 上代码step 1 添加nugetstep 2 添加支持step 3 添加配置文件 结束 上代码 step 1 添加nuget 添加nuget 包 Roc step 2 添加支持 修改program.cs var builder WebApplication.CreateBuilder(args); // 添加NLog日志支持 builder.AddRocNLog();ste…

贪心算法|860.柠檬水找零

力扣题目链接 class Solution { public:bool lemonadeChange(vector<int>& bills) {int five 0, ten 0, twenty 0;for (int bill : bills) {// 情况一if (bill 5) five;// 情况二if (bill 10) {if (five < 0) return false;ten;five--;}// 情况三if (bill …

Lvs+keepalived+nginx搭建高可用负载均衡集群,爱了爱了

检查 最后启动nginx服务 135配置虚拟网卡 检查 最后启动nginx服务 Nginx.conf配置如下 关闭132的keepalived服务后 浏览器能正常访问 132在keepalived配置中加入脚本 脚本内容 132清除ipvsadm中的规则,vip不见 133收到vip 自我介绍一下&#xff0c;小编13年上海交大毕业&…

使用idea运行程序,发现控制台的中文出现乱码

修改UTF-8发现没有效果&#xff0c;寻找.idea文件夹的encodings.xml文件&#xff0c;将里面的UTF-8全部变成GBK.

了解Vue中的 computed 计算属性

目录 1. computed计算属性介绍和基础语法 1.1. 概念 1.2. 语法 2. “计算属性”和“方法”的对比 2.1. computed 计算属性 2.1.1. 作用 2.1.2. 语法 2.2. methods 方法 2.2.1. 作用 2.2.2. 语法 2.2.3. 缓存特性&#xff08;提升性能&#xff09; 3. computed 计算…

云原生:5分钟了解一下Kubernetes是什么

在当今的云计算时代&#xff0c;容器化技术变得越来越重要。它能够帮助开发者更高效地部署和管理应用程序。而Kubernetes&#xff0c;作为容器编排领域的领军者&#xff0c;正逐渐成为企业构建和管理云原生应用的核心工具。 近期将持续为大家分享Kubernetes相关知识&#xff…

sql基础语法

sql基础语法 1. 什么是MySQL1.1 RDBMS 特点1.2 sql分类1.3 数据类型1.4 适应MySQL 2. 代码顺序与后台执行顺序2.1 代码撰写顺序2.2 后台执行顺序 3. 基础查询4. 条件检索5. 分组6. 多表查询6.1 子查询&#xff08;几乎不用&#xff09;6.2 连接查询 7. 常用函数 前同事培训过相…

GitHub 仓库 (repository) Branch - SSH clone URL - Clone in Desktop - Download ZIP

GitHub 仓库 [repository] Branch - SSH clone URL - Clone in Desktop - Download ZIP 1. Branch2. SSH clone URL3. Clone in Desktop4. Download ZIPReferences 1. Branch 显示当前分支的名称。从这里可以切换仓库内分支&#xff0c;查看其他分支的文件。 2. SSH clo…

FreeGPT3.5 开源软件

GPT-3.5不需要付费&#xff0c;也不需要注册用户&#xff0c;可以直接使用了&#xff0c;官方彻底开放了API接口。 该API政策一放开&#xff0c;GitHub很快就已经出现了一个开源项目FreeGPT35&#xff0c;可以自动生成key调用GPT3.5的API接口&#xff0c;再也用不着注册账号和申…

服务器数据恢复—V7000存储raid5数据恢复案例

服务器数据恢复环境&#xff1a; P740AIXSybaseV7000存储阵列柜&#xff0c;阵列柜上有12块SAS机械硬盘&#xff08;包括1块热备盘&#xff09;。 服务器故障&#xff1a; 管理员在日常巡检过程中发现阵列柜中有一块磁盘发生故障&#xff0c;于是更换磁盘并同步数据&#xff0…

快速熟悉torchdiffeq用法,从数理逻辑到完整案例【第二部分】

本系列文章板块规划 提示&#xff1a;以下内容仅为个人学习感悟&#xff0c;无法保证完全的正确和权威&#xff0c;大家酌情食用谢谢。 第一部分 torchdiffeq背后的数理逻辑 第二部分 torchdiffeq的基本用法 第三部分 trochdiffeq的升级用法 第四部分 torchdifffeq的案例和代码…

C++11:function包装器

包装器&#xff0c;体现了C11中的封装性&#xff0c;包装器可以应用于&#xff1a;函数指针&#xff0c;仿函数&#xff0c;lambda 而包装器function的出现刚好也弥补了上述三种语法的不足之处 函数指针写起来较为复杂&#xff0c;而仿函数之间类型不同&#xff0c;lambda则在…

数学建模笔记(10)整数规划和0-1规划

前由 显然通关次数不能是小数&#xff0c;这就涉及到了整数问题。 定义 例题

最新mysql8.3 保姆级 主从复制搭建教程

mysql 主从复制搭建 服务器配置表 机器ip操作系统主机192.168.31.25华为openEuler-22.03-LTS-SP3从机192.168.31.184华为openEuler-22.03-LTS-SP3从机192.168.31.228华为openEuler-22.03-LTS-SP3 1、在3台机器上安装独立的 mysql 1.1 创建myql文件夹用来存放mysql包 mkdir…

python-可视化篇-turtle-画爱心

文章目录 原效果替换关键字5为8&#xff0c;看看效果改下颜色 原效果 import turtle as tt.color(red,pink) t.begin_fill() t.width(5) t.left(135) t.fd(100) t.right(180) t.circle(50,-180) t.left(90) t.circle(50,-180) t.right(180) t.fd(100) t.pu() t.goto(50,-30) t…

【用户案例】太美医疗基于Apache DolphinScheduler的应用实践

大家好&#xff0c;我叫杨佳豪&#xff0c;来自于太美医疗。今天我为大家分享的是Apache DolphinScheduler在太美医疗的应用实践。今天的分享主要分为四个部分&#xff1a; 使用历程及选择理由稳定性的改造功能定制与自动化部署运维巡检与优化 使用历程及选择理由 公司介绍 …

尝试在手机上运行google 最新开源的gpt模型 gemma

Gemma介绍 Gemma简介 Gemma是谷歌于2024年2月21日发布的一系列轻量级、最先进的开放语言模型&#xff0c;使用了与创建Gemini模型相同的研究和技术。由Google DeepMind和Google其他团队共同开发。 Gemma提供两种尺寸的模型权重&#xff1a;2B和7B。每种尺寸都带有经过预训练&a…

【iOS ARKit】AR Quick Look 概述

为更好地传播共享 AR 体验&#xff0c;苹果公司引入了 AR Quick Look&#xff0c;并在iOS 12及以上版本系统中深度集成了 AR Quick Look&#xff0c;因此可以通过iMessage、Mail、Notes、 News、 Safari 和 Files 直接体验 AR&#xff0c;AR Quick Look提供了在 iPhone 和iPad …