秒杀系统

2019-07-26  本文已影响0人  HamletSunS

Maven建立工程,管理jar包

jar包依赖
日志、数据库、数据库连接池(生疏点)、DAO相关、Servlet web相关、Spring系列

DAO层的设计
表结构设计、实体类的定义、DAO接口的定义,使用mybatis实现接口,spring实现IOC

1. 秒杀业务分析

<del>展示界面、需要的信息(库存、开始时间、结束时间)、业务逻辑(开始前倒计时、活动期间可以秒杀、结束后显示活动结束)、登陆注册、对高并发场景的处理</del>

库存

减库存、记录购买明细、完整事务、数据落地

购买行为

谁购买成功、购买时间与有效期、付款时间和发货信息

事务的意义

原子性,保证减库存后必然会记录购买明细,否则会发生多卖(记录、没减库存)或少卖的情况(减库存、没记录)

数据落地

mysql vs nosql(高可用、分布式,不支持事务)

2. mysql实现秒杀功能的难点分析

<del>同数据库建立连接比较消耗时间,qps低</del>

并发处理秒杀行为时各个用户之间竞争访问数据库

事务+行级锁
会导致一个用户访问db时别的用户排队等待,变成串行操作,qps低

3.实现哪些秒杀功能

<del>对重复提交的秒杀的处理</del>
秒杀接口的暴露 执行秒杀 相关查询

4.代码开发阶段

  1. DAO层 设计编码
  2. Service层 设计编码
  3. Web层 设计编码

整体梳理

技术栈

日志、数据库、数据库缓存池、Spring、SpringMVC、服务器、Redis

项目结构

DAO层、业务层、WEB层

优化分析

瓶颈点 -- 竞争(数据库的事务、行级锁)
优化思路
流量分流(动静分离、读写分离--redis缓存、接口隐藏减少流量、集群化处理、深度优化--减少行级锁占用时间、使用存储过程)

秒杀页面优化(频繁刷新)
CDN(Content Delivery Network)
静态页面可以放在CDN上,动静分离,分流流量,较少服务器压力

秒杀地址接口优化
为什么秒杀API不能放CDN?
因为CDN放的内容适合放不变化的,秒杀处理会导致数据变化,比如返回值,没开始、活动期间、活动结束的返回值是不同的
适合放在服务端的Redis缓存服务器

  1. 单机10万QPS,集群可达百万QPS,适合处理高并发场景
  2. 一致性维护成本低(超时穿透、主动更新)

秒杀操作优化
难点:
无法放CDN
因为最核心的东西不能放CDN,大部分写操作都不会放CDN
后端缓存也比较困难
因为有库存的问题,若命中缓存即返回,可能不会及时更新数据库
一行数据竞争问题
MySQL事务机制、行级锁机制
优化思路:深度优化 比如设计存储过程。减少行级锁占用时间

其他方案分析:
执行秒杀
原子计数器(记录库存,Redis) --》 记录行为(消息队列) --》消费消息并落地(数据库库)
优势:QPS高,性能好
劣势:开发和维护成本很高,幂等性难以保证,技术难点高

MySQL作为解决方案的分析

  1. 尽快的让事务提交或回滚,减少行级锁的占用时间
  2. update的处理逻辑由Java客户端转移到MySQL服务器上去执行,避免网络延迟和GC的影响
    如何实现2?

优化总结:
前端控制:隐藏秒杀接口、按钮防重复
动静数据分离:CDN、后端缓存
事务竞争优化:减少事务锁的时间

部署

CDN WebServicer Redis MySQL


DAO编码与设计

Spring的使用:

上一篇下一篇

猜你喜欢

热点阅读