Java高并发秒杀API

来源:互联网 发布:淘宝详情页怎么切图 编辑:程序博客网 时间:2024/05/22 00:20

一、业务分析

1.秒杀系统业务流程

这里写图片描述

2.秒杀业务的核心:

库存的处理

3.针对库存业务分析:

事务(1>.减内存 2>.记录购买明细)

这里写图片描述

4.记录秒杀成功信息

(1)购买成功的对象
(2)成功的时间/有效期
(3)付款/发货信息

二、异常情况分析

(1)减库存没有记录购买明细
(2)记录明细但没有减库存
(3)出现超卖/少卖

三、难点分析

MySQL:事务 + 行级锁
start transaction -> update 库存数量 -> insert购买明细 -> commit
难点在update库存时会出现行级锁的竞争,秒杀的难点在于如何高效的处理竞争。
行锁: 当一个事务开启的时候, 另一个事务进来的时候发现他们锁定的是同一行数据, 之前的事务如果没有提交或回滚的话, 这个行级锁是不会释放的. 这是mysql事务的实现方案.
这里写图片描述
这里写图片描述

四、功能模块

1.秒杀接口暴露(Exposer,封装的DTO)- 防止人为提前知道秒杀接口地址, 使用工具自动进行秒杀
2.用户执行秒杀
3.用户相关查询

五、开发流程

1.DAO设计编码

(1) insert ignore - 主键冲突的时候不报错, 而是返回0, 方便业务处理
(2) 根据id查询SuccessKilled并携带Seckill实体
需要配置列的别名转换:

<setting name="userColumnLabel" value="true">

告诉MyBatis把结果映射到SuccessKilled同时映射seckill属性:

SELECT          sk.seckill_id,          sk.user_phone,          sk.create_time,          sk.state,          s.seckill_id "seckill.seckill_id",          s.name "seckill.name",          s.number "seckill.number",          s.start_time "seckill.start_time",          s.end_time "seckill.end_time",          s.create_time "seckill.create_time"        FROM success_killed sk        INNER JOIN seckill s on sk.seckill_id = s.seckill_id        WHERE sk.seckill_id = #{seckillId} AND sk.user_phone = #{userPhone}

2.Service设计编码

(1) dto和entity
dto: web和service数据的传递
entity: 业务封装

(2) spring声明式事务
a.只接受运行期异常回滚策略
b.使用try catch将编译时异常要转变为运行期异常, 小心不当的try catch
c.默认为propergation_required,有就加入当前事务没有就创建新事务

3.Web设计编码(restful接口和前端交互等)

(1) restful接口设计
一种优雅的url表示方式(最后一个词为名字)
/模块/{资源标识}/操作类型

GET /seckill/list (查询操作)
POST /seckill/{seckillId}/execution (添加/修改操作 - 非幂等)
DELETE /seckill/{seckillId}/delete (删除操作)
PUT (修改操作 - 幂等)

(2) controller层作用:
a.接受请求参数, 并做跳转控制
b.post请求不能直接在浏览器中敲地址

(3) js中模块化编程, 分包思想

4.高并发优化与分析

1.前端控制:控制接口暴露, 按钮防重复

2.动静态数据分离, 前端CDN缓存, 后端Redis缓存
DCN是一个加速用户获取数据的系统, 它部署在离用户最近的网络节点上
, 命中CDN后不需要再访问后端的服务器
这里写图片描述
3.java控制事务存在排队等锁, 和数据库通信存在网络延迟和GC
优化方向: 减少行级锁的持有时间(使用存储过程, 避免网络延迟和GC影响)
这里写图片描述

原创粉丝点击