秒杀场景_解决秒杀超卖问题_04

在这里插入图片描述

文章目录

          • 一、商品微服务改造
          • 二、秒杀微服务改造
            • 2.1. SkillGoodService 改造
            • 2.2. MutilThreadOrder 改造

一、商品微服务改造

SkillGoodService改造

package com.gblfy.service;import com.gblfy.dao.SkillGoodRepository;
import com.gblfy.entity.SkillGood;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;import java.util.ArrayList;
import java.util.List;
import java.util.Set;@Component
public class SkillGoodService {@Autowiredprivate RedisTemplate redisTemplate;public static final String SKILL_GOODS_PHONE = "SKILL_GOODS_PHONE";public static final String SKILL_GOODS_QUEUE = "SKILL_GOODS_QUEUE";@Autowiredprivate SkillGoodRepository skillGoodRepository;/*** 每五秒执行一次 将需要参与秒杀的商品列表加载到内存*/@Scheduled(cron = "0/5 * * * * ?")public void prepareGood() {System.out.println("开始加载商品");//获取所有已经在内存当中的商品ID列表Set<Long> set = redisTemplate.boundHashOps(SKILL_GOODS_PHONE).keys();List<Long> ids = new ArrayList<>();for (Long id : set) {ids.add(id);}List<SkillGood> list = null;//只查询出不在内存当中的商品信息,并加载到内存if (CollectionUtils.isEmpty(ids)) {list = skillGoodRepository.findSkillAll();} else {list = skillGoodRepository.findSkill(ids);}if (!CollectionUtils.isEmpty(list)) {for (SkillGood skillGood : list) {redisTemplate.boundHashOps(SKILL_GOODS_PHONE).put(skillGood.getId(), skillGood);redisTemplate.boundListOps(SKILL_GOODS_QUEUE+skillGood.getId()).leftPushAll(convertoArry(skillGood.getStockCount(),skillGood.getId()));}}// 查看当前缓存中所有的商品信息Set keys = redisTemplate.boundHashOps(SKILL_GOODS_PHONE).keys();for (Object s : keys) {SkillGood skillGood = (SkillGood) redisTemplate.boundHashOps(SKILL_GOODS_PHONE).get(s);System.out.println(skillGood.getName() + " 库存剩余:" + skillGood.getStockCount());}}private Long[] convertoArry(Integer stockCount, Long id) {Long[] idslong=new Long[stockCount];for(int i=0;i<stockCount;i++){idslong[i]=id;}return idslong;}// 提供查询商品信息的方法public SkillGood queryProduct(Long productId) {return (SkillGood) redisTemplate.boundHashOps(SKILL_GOODS_PHONE).get(productId);}// 更新商品信息public void update(SkillGood skillGood) {skillGoodRepository.save(skillGood);}
}
二、秒杀微服务改造
2.1. SkillGoodService 改造
package com.gblfy.service;import com.gblfy.dao.SkillOrderRepository;
import com.gblfy.entity.SkillEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import javax.transaction.Transactional;
import java.util.UUID;@Service
public class SkillGoodService {public static final String SKILL_GOODS_PHONE = "SKILL_GOODS_PHONE";public static final String SKILL_GOODS_LIST = "SKILL_GOODS_LIST";public static final String SKILL_GOODS_ONLY = "SKILL_GOODS_ONLY";public static final String SKILL_GOODS_QUEUE = "SKILL_GOODS_QUEUE";@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate SkillOrderRepository skillOrderRepository;@Autowiredprivate ProductService productService;@Autowiredprivate MutilThreadOrder mutilThreadOrder;@Transactionalpublic void add(Long productId, String userId) throws Exception {//判断这个用户是否参加过抢单userId = UUID.randomUUID().toString();Long time = redisTemplate.boundHashOps(SKILL_GOODS_ONLY).increment(userId, 1L);if (time > 1) {throw new Exception("重复抢单,不要太贪心");}// 先封装对象 并且放入redis 队列SkillEntity skillEntity = new SkillEntity();skillEntity.setProductId(productId);skillEntity.setUserId(userId);redisTemplate.boundListOps(SKILL_GOODS_LIST).leftPush(skillEntity);mutilThreadOrder.createOrder();}
}
2.2. MutilThreadOrder 改造
package com.gblfy.service;import com.gblfy.dao.SkillOrderRepository;
import com.gblfy.entity.SkillEntity;
import com.gblfy.entity.SkillGood;
import com.gblfy.entity.SkillOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class MutilThreadOrder {@Autowiredprivate ProductService productService;@Autowiredprivate SkillOrderRepository skillOrderRepository;@Autowiredprivate RedisTemplate redisTemplate;@Asyncpublic void createOrder() throws Exception {System.out.println("开始异步抢单");SkillEntity skillEntity = (SkillEntity) redisTemplate.boundListOps(SkillGoodService.SKILL_GOODS_LIST).rightPop();if (skillEntity == null) {return;}Long productId = skillEntity.getProductId();String userId = skillEntity.getUserId();SkillGood skillGood = productService.getGoodById(productId);if (skillGood == null) {throw new Exception("商品已经被抢光拉");}Long stockId = (Long) redisTemplate.boundListOps(SkillGoodService.SKILL_GOODS_QUEUE + productId).rightPop();if (stockId == null) {System.out.println("该商品已被秒杀完毕");redisTemplate.boundHashOps(SkillGoodService.SKILL_GOODS_ONLY).delete(userId);redisTemplate.boundHashOps(SkillGoodService.SKILL_GOODS_PHONE).delete(skillGood.getId());skillGood.setStockCount(0);productService.update(skillGood);return;}SkillOrder skillOrder = new SkillOrder();skillOrder.setMoney(skillGood.getCostPrice());skillOrder.setPayTime(new Date());skillOrder.setStatus("0");skillOrder.setUserId(userId);skillOrder.setCreateTime(new Date());skillOrder.setSkillId(productId);skillOrderRepository.save(skillOrder);System.out.println("结束异步抢单");}
}

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

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

相关文章

初识 Knative: 跨平台的 Serverless 编排框架

Knative 是什么 Knative 是 Google 在 2018 的 Google Cloud Next 大会上发布的一款基于 Kubernetes 的 Serverless 框架。Knative 一个很重要的目标就是制定云原生、跨平台的 Serverless 编排标准。Knative 是通过整合容器构建(或者函数)、工作负载管理(和动态扩缩)以及事件模…

python使用PyMysql连接MySQL实现增删改查

文章目录一、安装PyMysql&#xff1a;1.方式一&#xff1a;使用命令行2.方式二&#xff1a;通过PyCharm编译器二、操作MySQL数据库步骤1. 使用import导入相应的类2.获得数据库的连接3.创建游标对象4.执行SQL语句5.关闭数据库连接三、案例1. 查询单条数据2. 查询多条数据3.创建数…

一分钟解决 Github 访问慢

文章目录1. 获取域名对应的ip2. 复制ip3. 配置hostsgithub.com对应的ip有多个选一个响应快的即可&#xff0c;但是一直在变&#xff0c;用的时候&#xff0c;设置一次即可 1. 获取域名对应的ip https://tool.chinaz.com/dns/?type1&hostgithub.com&ip 2. 复制ip 3. …

做一个高一致性、高性能的Flutter动态渲染,真的很难么?

Flutter动态模板渲染架构升级 ​ 最近小组在尝试使用集团DinamicX的DSL&#xff0c;通过下发DSL模板&#xff0c;实现Flutter端的动态化模板渲染。我们解决了性能方面的问题后&#xff0c;又面临了一个新的挑战——渲染一致性。我们该如何在不降低渲染性能的前提下&#xff0c…

数据科学产业中哪些架构最热门?本文为你盘点了 5 款!

作者 | Sai Krishna译者 | 火火酱&#xff0c;责编 | Carol封图 | CSDN 付费下载自视觉中国地球上的数据量每分每秒都在增加&#xff0c;海量的数据源源不断地从四面八方涌入各种机构组织&#xff0c;而这些数据最终或许会成为能够指引我们做出战略决策的宝贵财富。这就是数据科…

面向云原生的混沌工程工具-ChaosBlade

作者 | 肖长军&#xff08;穹谷&#xff09;阿里云智能事业群技术专家 导读&#xff1a;随着云原生系统的演进&#xff0c;如何保障系统的稳定性受到很大的挑战&#xff0c;混沌工程通过反脆弱思想&#xff0c;对系统注入故障&#xff0c;提前发现系统问题&#xff0c;提升系…

centOS docker容器的安装

文章目录一、docker安装步骤1.卸载旧版本2.安装依赖3.添加镜像源4.查看仓库中的所有docker版本5.安装docker6.启动docker7.设置开机自启动docker8.查看docker是否安装成功9.卸载docker一、docker安装步骤 提示&#xff1a;安装之前可以使用命令&#xff1a;yum check-update检查…

泡着枸杞写bug的三流程序员凭什么逆袭到一线大厂?

大多数互联网的从业者都有一个梦想&#xff1a;进大厂。因为不仅可以享受较好的福利待遇&#xff0c;也能与更优秀的人一起共事&#xff0c;获得更专业、更快速的成长。最近经常有朋友提及想要入门编程学习&#xff0c;该如何学习&#xff1f;关于编程学习&#xff0c;各种语言…

哪种人是软件设计中的稀缺型人才?

阿里妹导读&#xff1a;好的系统架构离不开好的接口设计&#xff0c;因此&#xff0c;真正懂接口设计的人往往是软件设计队伍中的稀缺型人才。 为什么在接口制定标准中说&#xff1a;一流的企业做标准&#xff0c;二流的企业做品牌&#xff0c;三流的企业做产品&#xff1f;依赖…

快速Ubuntu的配置(以ubuntu 20.04桌面版为例)

文章目录一、&#x1f496;更换镜像源二、&#x1f496;安装VMware Tools工具三、&#x1f496;安装Google浏览器四、&#x1f496;安装搜狗输入法五、&#x1f496;安装C/C开发工具Clion&#x1f340;1.安装编译环境&#x1f340;2.安装开发环境一、&#x1f496;更换镜像源 …

阿里工程师太凶残了,竟把服务器泡在“水里”!

万众瞩目的第11个双11要来了&#xff01;这次天猫说要帮大家省500亿&#xff0c;身边加购物车、组队盖楼的同学数不胜数&#xff0c;热闹非凡。 但在阿里&#xff0c;有一位低调的“高冷男”&#xff0c;丝毫不为红红火火的双11所动&#xff0c;依然稳如磐石、淡定自若。 他的…

“我今年 31 岁,工作 7 年,明年退休...”

凌晨 1:30 的北京&#xff0c;商务楼静静地伫立着&#xff0c;街道上的车水马龙&#xff0c;慢慢地停歇了&#xff0c;只有他的工作台灯还没有休息&#xff0c;台灯忽明忽暗地坚持着。凌晨 2:00 的闹钟忍不住提醒他&#xff0c;电脑也偷偷跳出窗口&#xff1a;“主人&#xff0…

据说这是双11前互联网人的一天~

双11前&#xff0c;据说互联网人的一天是这样度过.... 6段故事&#xff0c;6个黑话关键词&#xff0c;生动刻画了双11前互联网人的一天&#xff01; 上午9点&#xff0c;运营找老板汇报双11方案。 运营说&#xff1a;老板&#xff0c;本次营销方案你看需要一些预算资源支持&a…

快速入门docker容器

文章目录&#x1f332;1.拉取一个镜像&#x1f332;2. 在docker里启动一个镜像&#x1f332;3.查看所有的镜像列表&#x1f332;4.删除镜像&#x1f332;5.删除全部image镜像&#x1f332;6.运行tomcat&#x1f332;7.删除所有未运行的容器&#x1f332;8.以守护态运行容器&…

不会玩游戏的程序员不是好作家,《深入理解Java虚拟机》周志明来了!

嘉宾&#xff1a;周志明、杨福川采访、撰文&#xff1a;Satoh_AI这次采访起源来自于我和豆瓣的一位读者有同样的好奇心&#xff0c;为什么网上搜不到周志明老师的更多信息&#xff1f;为什么“80后玩家”可以把本本书都维持在9.0分左右&#xff1f;他的“社恐”到底有多严重?所…

当手机淘宝遇见折叠屏,让购物更随心

华为 5G 新品发布会上&#xff0c;Mate X 正式亮相&#xff0c;淘宝也作为重点展示应用出现在发布会的 PPT 上&#xff0c;同时也成为折叠屏生态联盟应用矩阵的第一位。 现场华为折叠屏上的淘宝多任务演示 伴随手淘技术团队对华为折叠屏适配工作的展开。半年前还只是概念方案的…

SpringBoot2.x 整合 Ueditor

文章目录一、基础准备1. 创建项目并引入依赖2. 下载Ueditor源码3. Java代码整合4. 静态文件整合二、静态页面控制层2.1. index.html2.2. demo1.html2.3. demo2.html2.4. demo3.html2.5. Controller三、配置调整3.1. 图片大小3.2. 修改ueditor.config.js3.3. 修改config.json文件…

无线路由攻击和WiFi密码破解实战[渗透技术]

文章目录一、准备阶段二、攻击阶段1.停止&#x1f6d1;网络管理员2.开启网卡监听模式3. 捕获数据包4.获取数据包5.注入数据包&#xff08;DeAuth洪水攻击&#xff09;5.WiFi密码破解一、准备阶段 攻击主机&#xff1a;kali Linux攻击工具&#xff1a;aircrack-ng、airodump-ng…

支付宝双11狂欢幕后的女程序员:服务全球12亿人,每天和不法分子打攻防战

再过3天&#xff0c;全球最大的购物狂欢节就开始了。 在这个睡不着的午夜&#xff0c;无数男男女女会在闪烁的屏幕前滑屏、抢购、享受秒级付款带来的快感。整个过程大脑分泌的多巴胺&#xff0c;又驱使他们以更快的速度重新填满购物车。 2018年天猫双11成交额2135亿元&#x…

技术直播:程序员副业的修炼指南!(限免报名)

面试造飞机&#xff0c;上班拧螺丝&#xff0c;每天想辞职&#xff0c;但无奈副业还“大器晚成”的样子&#xff01;那可能是你还没有选对副业&#xff01;滴滴 ~福利卡&#xff01;&#xff01;&#xff01;CSDN学院邀请汤小洋老师开设技术直播课《程序员副业之路-三大终极秘籍…