1. 秒杀业务分析
1.1 需求分析
- 所谓“秒杀”,就是网络卖家发布一些超低价格的商品,所有买家在同一时间网上抢购的一种销售方式。通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动。由于商品价格低廉,往往一上架就被抢购一空,有时只用一秒钟。
- 秒杀商品通常有两种限制:库存限制、时间限制。
- 需求:
(1)商家提交秒杀商品申请,录入秒杀商品数据,主要包括:商品标题、原价、秒杀价、商品图片、介绍等信息
(2)运营商审核秒杀申请
(3)秒杀频道首页列出秒杀商品(进行中的)点击秒杀商品图片跳转到秒杀商品详细页。
(4)商品详细页显示秒杀商品信息,点击立即抢购实现秒杀下单,下单时扣减库存。当库存为 0 或不在活动期范围内时无法秒杀。
(5)秒杀下单成功,直接跳转到支付页面(微信扫码),支付成功,跳转到成功页,填写收货地址、电话、收件人等信息,完成订单。
(6)当用户秒杀下单 5 分钟内未支付,取消预订单,调用微信支付的关闭订单接口,恢复库存。
1.2 实现方案
1.2.1 高并发下的优化
如果在高并发下防止超卖,确保线程安全
实现过程如下图
1.2.2 排队优化
上面的方案解决了并发情况下超卖的问题,但其实际秒杀中大量并发情况下,这个下单过程是需要很长等待时间的,所以这里我们建议用异步和多线程实现,最好不要让程序处于阻塞状态,而是在用户一下单的时候确认用户是否符合下单条件,如果符合,则开启线程执行创建订单处理,用户则进入支付页面等待查询订单结果, 扫码支付即可。
实现过程如下图
2. 定时任务
- 定时生成秒杀商品详情页
- 将秒杀商品完整信息入库到 Redis (Hash类型)
- 每个商品的待售数量队列入库到 Redis (List类型)
3. 结算页面
- 展示用户送货地址清单
- 用户选择送货地址
- 选择扫码支付方式 (微信 / 支付宝)
- 展示待结算的秒杀商品明细
3. 秒杀下单
3.1 前端
3.1.1 页面
3.1.2 控制层 orderController.js
/**
* 进入秒杀下单
*/
$scope.submitOrder = function () {
// 从地址栏获去秒杀商品Id
var seckillGoodsId = $location.search()['seckillGoodsId'];
orderService.submitOrder(seckillGoodsId).success(function (response) {
if (response.success) {
//进入支付页面
location.href = "pay.html";
} else {
alert(response.message);
}
}
);
};
3.1.3 服务层 orderService.js
/**
* 进入秒杀下单
*/
this.submitOrder = function (id) {
return $http.get("http://localhost:9007/seckillOrder/submitOrder02/"+ id);
}
3.2 后端
3.2.1 控制层
import com.alibaba.dubbo.config.annotation.Reference;
import com.pyg.seckill.service.SeckillOrderService;
import com.pyg.utils.PygResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/seckillOrder")
public class SeckillOrderController {
@Reference</