分析java高并发秒杀系统(后端)实现思路

本文探讨了在高并发环境下,如何利用消息队列、Redis和多线程来构建秒杀系统,以减轻数据库压力。通过将请求写入消息队列,预减Redis库存,以及原子性事务处理,确保系统的稳定性和效率。详细介绍了从初始化库存到订单创建的整个流程。
摘要由CSDN通过智能技术生成

秒杀系统实现思路

秒杀系统,系统瞬间要处理大量并发,核心问题在于如何在大并发的情况下能保证 DB能扛得住压力,因为高并发的瓶颈就在于DB。如果说请求直接从前端透传到DB,显然,DB是无法承受几十万上百万甚至上千万的并发量的,这里就用到了另外一个非常重要的组件:消息队列。我们不是把请求直接去访问数据库,而是先把请求写到消息队列中,做一个缓存,然后再去慢慢的更新数据库。

思路

  1. 系统初始化,把商品库存数量加载到Redis上面来。
  2. 后端收到秒杀请求,Redis预减库存,如果库存已经到达临界值的时候,就不需要继续请求下去,直接返回失败,即后面的大量请求无需给系统带来压力。
  3. 判断这个秒杀订单形成没有,判断是否已经秒杀到了,避免一个账户秒杀多个商品,判断是否重复秒杀。
  4. 库存充足,且无重复秒杀,将秒杀请求封装后消息入队,同时给前端返回一个code (0),即代表返回排队中。(返回的并不是失败或者成功,此时还不能判断)前端接收到数据后,显示排队中,并根据商品id轮询请求服务器(考虑200ms轮询一次)。
  5. 后端RabbitMQ监听秒杀的订单信息,获取到传入的信息,执行真正的秒杀之前,要判断数据库的库存,判断是否重复秒杀,然后执行秒杀事务(秒杀事务是一个原子操作:库存减1,下订单,写入秒杀订单)。

代码实现

1.将要秒杀的商品生成对应商品数量token存储到 redis,减轻数据库压力

/**
	 * 采用redis数据库类型为 list类型 key为 商品库存id list 多个秒杀token
	 * 
	 * @param seckillId  商品id
	 * @param tokenQuantity 令牌数量,对应商品数量
	 * @return
	 */
	// 采用redis数据库类型为 list类型 key为 商品库存id list 多个秒杀token
	@RequestMapping("/addSpikeToken")
	public BaseResponse<JSONObject> addSpikeToken(Long seckillId, Long tokenQuantity) {
		// 1.验证参数
		if (seckillId == null) {
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
java实现秒杀系统@Controller @RequestMapping("seckill")//url:/模块/资源/{id}/细分 /seckill/list public class SeckillController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private SeckillService seckillService; @RequestMapping(value="/list",method = RequestMethod.GET) public String list(Model model){ //获取列表页 List list=seckillService.getSeckillList(); model.addAttribute("list",list); //list.jsp+model = ModelAndView return "list";//WEB-INF/jsp/"list".jsp } @RequestMapping(value = "/{seckillId}/detail",method = RequestMethod.GET) public String detail(@PathVariable("seckillId") Long seckillId, Model model){ if (seckillId == null){ return "redirect:/seckill/list"; } Seckill seckill = seckillService.getById(seckillId); if (seckill == null){ return "forward:/seckill/list"; } model.addAttribute("seckill",seckill); return "detail"; } //ajax json @RequestMapping(value = "/{seckillId}/exposer", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) @ResponseBody public SeckillResult exposer(@PathVariable("seckillId") Long seckillId){ SeckillResult result; try { Exposer exposer =seckillService.exportSeckillUrl(seckillId); result = new SeckillResult(true,exposer); } catch (Exception e) { logger.error(e.getMessage(),e); result = new SeckillResult(false,e.getMessage()); } return result; } @RequestMapping(value = "/{seckillId}/{md5}/execution", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"} ) @ResponseBody public SeckillResult execute(@PathVariable("seckillId")Long seckillId,
Java后端实现秒杀系统的步骤如下: 1.设计数据库表结构 秒杀系统需要设计两个表,一个是商品表,另一个是秒杀订单表。商品表包含商品的id、名称、库存、价格等信息;秒杀订单表包含订单id、用户id、商品id、数量、金额、订单状态等信息。 2.实现商品列表展示 在Java代码中,通过查询商品表的数据,将商品列表展示在页面上。需要注意的是,为了防止商品被重复购买,需要在商品表中设置一个库存字段,每次购买成功后需要将库存减1。 3.实现秒杀接口 为了保证秒杀的公平性,需要在后端实现一个秒杀接口。在Java代码中,可以使用Redis等缓存工具来限制每个用户的秒杀请求频率,并且通过减少库存来防止超卖。同时,在秒杀订单表中插入一条订单记录。 4.实现订单支付 用户在秒杀成功后需要进行支付操作。可以通过调用第三方支付接口来完成支付操作。支付成功后,需要将订单状态修改为已支付,并将商品表中的库存减1。 5.实现订单查询 用户可以在页面上查询自己的订单信息。可以通过查询秒杀订单表的数据,将订单信息展示在页面上。 6.实现订单取消 用户可以在一定时间内取消订单。在Java代码中,可以通过修改订单状态为已取消来实现订单的取消操作。同时,需要将商品表中的库存加1。 以上就是Java后端实现秒杀系统的步骤,需要注意的是,为了保证系统的并发性和稳定性,需要使用高并发的技术,例如分布式缓存、消息队列等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值