如何使用RabbitMQ實現(xiàn)異步秒殺
搭建RabbitMQ
在虛擬機上用docker搭建RabbitMQ,首先拉取鏡像
docker run --privileged=true -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management mkdir -p /usr/local/docker/rabbitmq
再創(chuàng)建rabbitmq容器,下面的命令已經(jīng)能夠創(chuàng)建之后直接啟動了
docker run --privileged=true -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management
啟動之后,在瀏覽器中輸入
http://192.168.200.130:15672/#/
->也就是http://你的虛擬機地址:15672
登錄的密碼以及賬號默認都是guest
創(chuàng)建交換機以及queues
創(chuàng)建交換機

創(chuàng)建queues,名字為seckill.order.queue

創(chuàng)建好queue以及交換機后,回到交換機處,為交換機綁定一個queue,以便以后交換機接受到指定Rounting key的消息后,能夠?qū)⑿畔⒔唤o指定queue來消費信息,實現(xiàn)消息隊列(也就是將訂單消息交給交換機,交換機將消息給到queue,queue收到消息后就能消費信息,使用訂單信息完成扣減庫存等)

在項目中應用RabbitMQ
1 引入amqp依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>2 配置連接信息
rabbitmq:
host: 192.168.238.128 # 你的虛擬機IP
port: 5672 # 端口
virtual-host: /dianping # 虛擬主機
username: guest # 用戶名
password: guest # 密碼
listener:
direct:
acknowledge-mode: manual3 添加序列化配置
自定義RabbitMQ中json格式的消息的序列化機制
@Configuration
public class RabbitMQConfig {
@Bean
public MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
}修改業(yè)務代碼
直接將訂單交給消息隊列RabbitMQ
消息發(fā)送者
@Resource
private RabbitTemplate rabbitTemplate; @Transactional
public void handleVoucherOrder(VoucherOrder voucherOrder) {
//1.所有信息從當前消息實體中拿
Long voucherId = voucherOrder.getVoucherId();
//2.扣減庫存
boolean success = seckillVoucherService.update().setSql("stock=stock-1")
.eq("voucher_id", voucherId)
//======判斷當前庫存是否大于0就可以決定是否能搶池子中的券了
.gt("stock", 0)
.update();
//3.創(chuàng)建訂單
save(voucherOrder);
}
@Override
public Result seckillVoucher(Long voucherId) {
//1.執(zhí)行l(wèi)ua腳本,判斷當前用戶的購買資格
Long userId = ThreadLocalUtls.getUser().getId();
Long result = stringRedisTemplate.execute(
SECKILL_SCRIPT,
Collections.emptyList(),
voucherId.toString(), userId.toString());
if (result != 0) {
//2.不為0說明沒有購買資格
return Result.fail(result==1?"庫存不足":"不能重復下單");
}
//3.走到這一步說明有購買資格,將訂單信息存到阻塞隊列
VoucherOrder voucherOrder = new VoucherOrder();
long orderId = redisIdWorker.nextId("order");
voucherOrder.setId(orderId);
voucherOrder.setUserId(ThreadLocalUtls.getUser().getId());
voucherOrder.setVoucherId(voucherId);
//存入消息隊列等待異步消費
rabbitTemplate.convertAndSend("seckill.direct","seckill.order",voucherOrder);
return Result.ok(orderId);
}消費者
創(chuàng)建一個Listener文件夾,創(chuàng)建消費者專門監(jiān)聽交換器,收到信息傳來的訂單就執(zhí)行處理訂單方法,調(diào)用VoucherOrderService中的handleVoucherOrder來處理訂單,下單并修改數(shù)據(jù)庫
@Component
public class SeckillOrderListener {
@Autowired
VoucherOrderServiceImpl voucherOrderService;
@RabbitListener(queues = {"seckill.order.queue"})
public void recieveMessage(Message message, Channel channel, VoucherOrder voucherOrder){
try {
voucherOrderService.handleVoucherOrder(voucherOrder);
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (IOException e) {
throw new RuntimeException(e);
}
}到此這篇關(guān)于使用RabbitMQ實現(xiàn)異步秒殺的文章就介紹到這了,更多相關(guān)RabbitMQ異步秒殺內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java的帶GUI界面猜數(shù)字游戲的實現(xiàn)示例
這篇文章主要介紹了Java的帶GUI界面猜數(shù)字游戲的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-12-12
SpringBoot中MyBatis-Plus 查詢時排除某些字段的操作方法
這篇文章主要介紹了SpringBoot中MyBatis-Plus 查詢時排除某些字段的操作方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08
springboot+mybatis plus實現(xiàn)樹形結(jié)構(gòu)查詢
實際開發(fā)過程中經(jīng)常需要查詢節(jié)點樹,根據(jù)指定節(jié)點獲取子節(jié)點列表,本文主要介紹了springboot+mybatis plus實現(xiàn)樹形結(jié)構(gòu)查詢,感興趣的可以了解一下2021-07-07
springboot使用注解實現(xiàn)鑒權(quán)功能
這篇文章主要介紹了springboot使用注解實現(xiàn)鑒權(quán)功能,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-12-12
解決SpringBoot啟動過后不能訪問jsp頁面的問題(超詳細)
這篇文章主要介紹了解決SpringBoot啟動過后不能訪問jsp頁面的問題,文中通過示例代碼介紹的非常詳細,有需要的朋友可以參考一下,希望對你有所幫助。2020-05-05
springboot對象為null的屬性在json中不顯示的解決
這篇文章主要介紹了springboot對象為null的屬性在json中不顯示的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
深入理解Spring MVC的數(shù)據(jù)轉(zhuǎn)換
這篇文章主要給大家介紹了關(guān)于Spring MVC數(shù)據(jù)轉(zhuǎn)換的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起看看吧。2017-09-09

