国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

鄭州七彩網(wǎng)站建設(shè)公司怎么樣常熟網(wǎng)絡(luò)推廣

鄭州七彩網(wǎng)站建設(shè)公司怎么樣,常熟網(wǎng)絡(luò)推廣,小程序代做,成都網(wǎng)站建設(shè) urkejiSpringCloud 大型系列課程正在制作中,歡迎大家關(guān)注與提意見。 程序員每天的CV 與 板磚,也要知其所以然,本系列課程可以幫助初學(xué)者學(xué)習(xí) SpringBooot 項目開發(fā) 與 SpringCloud 微服務(wù)系列項目開發(fā) 1 項目準(zhǔn)備 SpringBoot 整合 RabbitMQ 消息隊…

SpringCloud 大型系列課程正在制作中,歡迎大家關(guān)注與提意見。
程序員每天的CV 與 板磚,也要知其所以然,本系列課程可以幫助初學(xué)者學(xué)習(xí) SpringBooot 項目開發(fā) 與 SpringCloud 微服務(wù)系列項目開發(fā)

1 項目準(zhǔn)備

  1. SpringBoot 整合 RabbitMQ 消息隊列【SpringBoot系列11】本文章 基于這個項目來開發(fā)

本文章是系列文章 ,每節(jié)文章都有對應(yīng)的代碼,每節(jié)的源碼都是在上一節(jié)的基礎(chǔ)上配置而來,對應(yīng)的視頻講解課程正在火速錄制中。

訂單系統(tǒng),用戶下單,即要保存即時性,也要保證流暢性,同時還要防止超賣,本文章是基于 RabbitMQ 消息隊列 + Redis 實現(xiàn)的下單,當(dāng)然后續(xù)還會的秒殺系統(tǒng)設(shè)計 以及后續(xù)的微服務(wù)以及熔斷控制等等

如這里 我的商品 庫存有 10 個
在這里插入圖片描述
然后我使用 apache-jmeter-5.5 壓測,200個用戶1秒內(nèi)請求完成,每個用戶請求2次,也就是1秒有400次下單請求
在這里插入圖片描述
測試完成后,商品庫存為0,然后訂單生成10個,完美解決并發(fā)問題
在這里插入圖片描述
這是實現(xiàn)的普通訂單,基本實現(xiàn)邏輯是
1、redis 校驗庫存,預(yù)下單
2、消息隊列減庫存 生成 訂單 (數(shù)據(jù)庫、redis、es)
3、用戶查詢到訂單成功,發(fā)起支付
4、支付回調(diào) 修改訂單數(shù)據(jù) (數(shù)據(jù)庫、redis 、es)

1 預(yù)下單接口

@Api(tags="訂單模塊")
@RestController()
@RequestMapping("/orders")
@Slf4j
public class OrderController {@Autowiredprivate OrderService orderService;/*** 下單* @param goodsId 商品ID* @param userId* @return*/@GetMapping("/create/{id}")public R createOrder(@PathVariable("id") Long goodsId,@RequestHeader Long userId) {return orderService.createPreOrder(goodsId,userId);}
}
    @Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate OrderMQSender mqSender;@Overridepublic R createPreOrder(Long goodsId, Long userId) {log.info("預(yù)下單處理 userId:{} goodsId:{} ",userId,goodsId);//獲取redis中的商品庫存 先判斷商品是否有庫存Boolean aBoolean = redisTemplate.hasKey("goodStock:" + goodsId);if(Boolean.FALSE.equals(aBoolean)){return R.error("下單失敗 商品庫存不足");}//獲取商品庫存int goodsStock = Integer.valueOf(redisTemplate.opsForValue().get("goodStock:" +goodsId).toString());if(goodsStock==0){return R.error("下單失敗 商品庫存不足");}//發(fā)送下單消息SecKillMessage message = new SecKillMessage(userId, goodsId);mqSender.sendCommonOrderMessage(JsonUtils.toJson(message));return R.okData("預(yù)下單成功");}

redisTemplate 的 hasKey 可以直接判斷key是否存在,在這里如果商品的key不存在,則商品無庫存,redis 的商品庫存是在服務(wù)啟動后,自動同步進(jìn)入的

@Service
@Slf4j
public class OrderServiceImpl implements OrderService , InitializingBean {@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate GoodsService goodsService;/*** 初始化秒殺商品數(shù)量到 redis 中** @return*/@Overridepublic R startSeckillInit() {List<SeckillGoods> goods = secKillGoodsService.findAllSecKillGoods();if (CollectionUtils.isEmpty(goods)) {return R.error("無秒殺商品");}goods.forEach(g -> {log.info("初始化秒殺商品 goodsId:{} stock: {}", g.getGoodsId(), g.getStockCount());redisTemplate.opsForValue().set("goodStock:" + g.getGoodsId(), g.getStockCount());});return R.ok("初始化完成");}@Overridepublic void afterPropertiesSet() throws Exception {this.startSeckillInit();}

InitializingBean 當(dāng)一個類實現(xiàn)這個接口之后,Spring啟動后,初始化Bean時,若該Bean實現(xiàn)InitialzingBean接口,會自動調(diào)用afterPropertiesSet()方法,完成一些用戶自定義的初始化操作。

2 消息隊列的定義

在這里單獨定義普通下單使用的隊列與交換機(jī)


import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class OrderRabbitMQTopicConfig {private static final String commonOrderQueue = "commonOrderQueue";private static final String commonExchange = "commonOrderExchange";@Beanpublic Queue commonOrderQueue() {return new Queue(commonOrderQueue);}@Beanpublic TopicExchange commonExchange() {return new TopicExchange(commonExchange);}@Beanpublic Binding commonOrderBinding() {return BindingBuilder.bind(commonOrderQueue()).to(commonExchange()).with("commonOrder.#");}
}

然后就是訂單的發(fā)送者

@Service
@Slf4j
public class OrderMQSender {@Autowiredprivate RabbitTemplate rabbitTemplate;/*** 普通訂單走的隊列* @param msg*/public void sendCommonOrderMessage(String msg) {log.info("預(yù)下單發(fā)送消息:{}", msg);rabbitTemplate.convertAndSend("commonOrderExchange", "commonOrder.message", msg);}
}

然后定義普通訂單的消息接收者

@Service
@Slf4j
public class OrderMQReceiver {@Autowiredprivate OrderService orderService;@RabbitListener(queues = "commonOrderQueue")public void receiveCommonOrderMessage(String message) {log.info("接收的秒殺訂單消息:{}", message);SecKillMessage secKillMessage = JsonUtils.toObj(message, SecKillMessage.class);Long userId = secKillMessage.getUserId();Long goodsId = secKillMessage.getGoodsId();//普通下單orderService.createOrder(goodsId, userId);}}

普通下單里,就是減庫存,生成訂單的過程

    @Override@Transactionalpublic R createOrder(Long goodsId, Long userId) {log.info("下單處理 userId:{} goodsId:{} ",userId,goodsId);//查詢商品詳情Goods goods = goodsService.findGoods(goodsId);//商品的實際庫存if (goods.getGoodsStock() < 1) {// 設(shè)置該商品庫存為空redisTemplate.opsForValue().set("goodStock:" + goods.getId(), "0");log.info("庫存不足 下單失敗");return R.error("商品庫存不足");}//減庫存 int currentStock = goods.getGoodsStock() -1;//更新數(shù)據(jù)庫 庫存goods.setGoodsStock(currentStock);int update = goodsService.updateGoodsStock(goods);if(update<=0){log.info("更新庫存失敗 下單失敗");return R.error("商品庫存不足");}//更新redis 緩存redisTemplate.opsForValue().set("goodStock:" + goods.getId(), currentStock);// 下訂單Order order = new Order();order.setUserId(userId);order.setGoodsId(goodsId);order.setDeliveryAddrId(0L);order.setGoodsName(goods.getGoodsName());order.setGoodsCount(1);order.setGoodsPrice(goods.getGoodsPrice());order.setOrderChannel(1);order.setStatus(0); // 訂單創(chuàng)建中order.setCreateDate(new Date());orderMapper.insert(order);log.info("下單成功 userId:{} goodsId:{} orderId:{}",userId,goodsId,order.getId());//緩存普通訂單redisTemplate.opsForValue().set("order:" +userId + ":" + goodsId, order);//保存數(shù)據(jù)到ES中//后續(xù)實現(xiàn)return R.okData(order);}

本文章是系列文章 ,每節(jié)文章都有對應(yīng)的代碼,每節(jié)的源碼都是在上一節(jié)的基礎(chǔ)上配置而來,對應(yīng)的視頻講解課程正在火速錄制中。

本文章只有核心代碼,全部代碼請查看對應(yīng)源碼
項目源碼在這里 :https://gitee.com/android.long/spring-boot-study/tree/master/biglead-api-10-seckill
有興趣可以關(guān)注一下公眾號:biglead


  1. 創(chuàng)建SpringBoot基礎(chǔ)項目
  2. SpringBoot項目集成mybatis
  3. SpringBoot 集成 Druid 數(shù)據(jù)源【SpringBoot系列3】
  4. SpringBoot MyBatis 實現(xiàn)分頁查詢數(shù)據(jù)【SpringBoot系列4】
  5. SpringBoot MyBatis-Plus 集成 【SpringBoot系列5】
  6. SpringBoot mybatis-plus-generator 代碼生成器 【SpringBoot系列6】
  7. SpringBoot MyBatis-Plus 分頁查詢 【SpringBoot系列7】
  8. SpringBoot 集成Redis緩存 以及實現(xiàn)基本的數(shù)據(jù)緩存【SpringBoot系列8】
  9. SpringBoot 整合 Spring Security 實現(xiàn)安全認(rèn)證【SpringBoot系列9】
  10. SpringBoot Security認(rèn)證 Redis緩存用戶信息【SpringBoot系列10】
  11. SpringBoot 整合 RabbitMQ 消息隊列【SpringBoot系列11】
http://aloenet.com.cn/news/27917.html

相關(guān)文章:

  • 黔江網(wǎng)站建設(shè)百度推廣找誰做
  • WordPress積分打賞插件制作企業(yè)seo培訓(xùn)
  • 網(wǎng)站制作一條龍東莞網(wǎng)站建設(shè)快速排名
  • 網(wǎng)站怎么添加廣告代碼鄭州競價代運(yùn)營公司
  • 濟(jì)南網(wǎng)站建設(shè)和網(wǎng)絡(luò)推廣哪個好google 官網(wǎng)入口
  • 江門網(wǎng)站建設(shè)網(wǎng)絡(luò)平臺推廣方案
  • 重慶網(wǎng)站建設(shè)公司排名淘寶指數(shù)查詢?nèi)肟?/a>
  • 商城網(wǎng)站如何建設(shè)方案草根seo視頻大全
  • 高端網(wǎng)站建設(shè) 司法搜索引擎公司排名
  • 服務(wù)器禁止ip訪問網(wǎng)站北京seo公司司
  • 大學(xué)電子商務(wù)網(wǎng)站建設(shè)seo快速優(yōu)化軟件網(wǎng)站
  • 網(wǎng)站的手機(jī)站頁面重復(fù)新聞源軟文發(fā)布平臺
  • 壽光網(wǎng)站開發(fā)種子搜索引擎torrentkitty
  • 日本軟銀集團(tuán)最大股東引擎優(yōu)化
  • 外文網(wǎng)站做t檢驗分析seo數(shù)據(jù)統(tǒng)計分析工具有哪些
  • 網(wǎng)站優(yōu)化一般要怎么做推廣優(yōu)化廠商聯(lián)系方式
  • 免費(fèi)網(wǎng)站服務(wù)seo運(yùn)營
  • 珠寶品牌網(wǎng)站設(shè)計杭州網(wǎng)絡(luò)推廣網(wǎng)絡(luò)優(yōu)化
  • 衡水做wap網(wǎng)站互聯(lián)網(wǎng)培訓(xùn)
  • 物流網(wǎng)站建設(shè)方案ks免費(fèi)刷粉網(wǎng)站推廣
  • 旅游網(wǎng)站做模板素材鏈接轉(zhuǎn)二維碼
  • WordPress 推酷 主題深圳百度推廣排名優(yōu)化
  • 彩票推廣網(wǎng)站如何做今日新聞快報
  • 住房城鄉(xiāng)建設(shè)管理委員官方網(wǎng)站小程序開發(fā)公司哪里強(qiáng)
  • 常州想做個企業(yè)的網(wǎng)站找誰做東莞推廣系統(tǒng)
  • 廣告文化網(wǎng)站建設(shè)2023新聞大事件摘抄
  • 韓國b2c電商網(wǎng)站百度排名點擊器
  • 網(wǎng)站建設(shè)與管理電子教程廣告公司是做什么的
  • 酒店網(wǎng)站開發(fā)合同哈爾濱最新信息
  • 甘肅網(wǎng)站建設(shè)開發(fā)百度大搜推廣開戶