聊聊高并发应用中电商秒杀场景的方案实现

秒杀场景需要考虑这些关键词:高并发、响应时效性、流程削峰、恶意流量攻击、秒杀原子操作与数据安全、服务高可用(应对雪崩)等。

面试题:设计一个10000并发的秒杀方案,9.9秒内秒杀100个商品。

【1】秒杀业务场景分析

① 秒杀/抢购业务场景

比如商品秒杀、商品抢购、群红包、抢优惠券、抽奖等等。

② 秒杀/抢购业务特点

秒杀商品价格低廉、抢购商品很好|抢手、大幅推广|广为人知、瞬时售空、一般是定时上架、持续时间短、瞬时并发量高等。

③ 秒杀/抢购技术特点

高并发、读多写少、资源冲突(容易导致超卖问题)。

概览一下技术实现:
聊聊高并发应用中电商秒杀场景的方案实现_第1张图片

削峰利器-异步MQ

如下所示,将用户请求通过消息中间件转发到秒杀服务器,通知秒杀系统一个个处理。
聊聊高并发应用中电商秒杀场景的方案实现_第2张图片
队列

可以使用Java内部队列来控制用户请求并保证公平性–先到先得,然后将队列转发给秒杀系统处理。
聊聊高并发应用中电商秒杀场景的方案实现_第3张图片


④ 系统基本架构与秒杀配套解决方案

不同于OSI的七层架构模型,这里应用系统架构分为五层,如下所示:
聊聊高并发应用中电商秒杀场景的方案实现_第4张图片
其中按钮控制、图形验证码是为了尽可能屏蔽恶意流量,比如机器人请求、脚本自动请求。


【2】秒杀技术方案落地实现

① 秒杀人群、并发规模的预估

为什么要估算?当然是为了确定一个最终的技术选型以及服务器容量。

那么如何估算呢?

平均并发用户数为C=nL/T,秒杀的并发规模就要根据公司活动历时以来的最高峰值再扩容。

② Nginx限流算法

常见限流算法有"漏桶算法"和“令牌桶算法”,Nginx提供了一个叫ngx_http_limit_req_module的模块进行流量控制,Nginx是基于漏桶算法实现。
聊聊高并发应用中电商秒杀场景的方案实现_第5张图片

③ 从前到后流程示意如

聊聊高并发应用中电商秒杀场景的方案实现_第6张图片


④ 乐观锁和悲观锁

乐观锁如使用version控制,悲观锁则如Select count from tb_goods where id=1 for update

乐观锁如下所示:
聊聊高并发应用中电商秒杀场景的方案实现_第7张图片

在高并发秒杀场景中,乐观锁是不太适合的。因为其冲突频率、重试代价所带来的性能消耗是大于悲观锁的。


【3】秒杀技术特点/优化

① 页面/静态资源的优化

动态页面静态化其实就是将传统的jsp或者thymeleaf、freemarker转换HTML+AJAX。静态页面可以缓存到客户端(比如浏览器),通过AJAX发送请求获取数据然后渲染页面。

静态资源优化

  • JS/CSS压缩,减少流量;
  • 多个JS/CSS组合减少连接数(或者说多个JS/CSS请求组合为单个请求-参数Tengine);
  • CDN支持

页面缓存

比如使用thymeleaf时,把页面缓存到redis一段时间,前端请求过来时先去redis获取页面。代码示例如下:

//取缓存,如果有直接返回
String html = redisService.get(GoodsKey.getGoodsDetail, ""+goodsId, String.class);
if(!StringUtils.isEmpty(html)) {
	return html;
}
//如果没有就生成并放入redis
SpringWebContext ctx = new SpringWebContext(request,response,
request.getServletContext(),request.getLocale(), model.asMap(), applicationContext );
//后台自己解析页面并缓存起来
String html = thymeleafViewResolver.getTemplateEngine().process("goods_detail", ctx);
if(!StringUtils.isEmpty(html)) {
 	redisService.set(GoodsKey.getGoodsDetail, ""+goodsId, html);
 }

通常现在项目中都是采用前后端分离模式开发,比如前端的VUE。那么部署的时候采用动静分离分别部署即可。

参考博文:Java 高并发解决方案(电商的秒杀和抢购)

你可能感兴趣的:(分布式架构,分布式应用初探)