【JavaP6大纲】功能设计篇:秒杀场景设计

本文介绍了秒杀场景的设计策略,包括流量过滤、活动校验、非法请求拦截和限流措施。通过前端页面的预加载、验证码、活动校验等方式减少无效流量。采用令牌桶算法进行限流,并对页面进行静态化和活动预热以优化性能。同时,实施熔断、限流降级策略确保系统稳定性,并通过监控和数据统计进行质量保障。
摘要由CSDN通过智能技术生成

秒杀场景设计

流量过滤:

本质上,参与秒杀的用户很多,但是商品的数量是有限的,真正能抢到的用户并不多,那么第一步就是要过滤掉大部分无效的流量。

活动开始前前端页面的Button置灰,防止活动未开始无效的点击产生流量。
前端添加验证码或者答题,防止瞬间产生超高的流量,可以很好的起到错峰的效果,现在的验证码花样繁多,题库有的还要做个小学题,而且题库更新频繁,想暴力破解怕是很难。当然我知道的还有一种人工打码的方式,不过这个也是需要时间的,不像机器无限刷你的接口。
活动校验,既然是活动,那么活动的参与用户,参加条件,用户白名单之类的要首先做一层校验拦截,还有其他的比如用户终端、IP地址、参与活动次数、黑名单用户的校验。比如活动主要针对APP端的用户校验,那么根据参数其他端的用户将被拦截,针对IP、mac地址、设备ID和用户ID可以对用户参与活动的次数做校验,黑名单根据平时的活动经验拦截掉一部分羊毛党等异常用户。
非法请求拦截,做了以上拦截如果还有用户能绕过限制,那不得不说太牛X了。比如双11零点开始还做了答题限制,那么正常人怎么也需要1秒的时间来答题吧,就算单身30年手速我想也不能超过0.5秒了,那么针对刚好0点或者在0.5秒以内的请求就可以完全拦截掉。
限流,使用不同类型的限流器:
1.请求限流器:该限流器限制每个用户每秒可发送 N 个请求。
2.并发请求限流器:限制每秒最高请求数,这种限流器则是限制最高并发请求数。
3.基于使用量的负载降级
4.基于 Worker 利用率的负载降级:worker 太忙,无法处理分配给它的请求,它会缓慢降级非关键请求

有什么限流算法?以及如何实现?
令牌桶算法 来进行流量限制。该算法有一个集中的桶,为每一个请求分配一个令牌,并不断地缓慢地在桶中放入令牌。 如果桶为空,则拒绝该请求。在我们的例子中,每个用户都被分配一个桶,每当他们产生一个请求时,我们从这个桶中移除一个令牌。

性能优化:

页面静态化,参与秒杀活动的商品一般都是已知的,可以针对活动页面做静态化处理,缓存到CDN。假设我们一个页面300K大小,1千万用户的流量是多少?这些请求要请求后端服务器、数据库,压力可想而知,缓存到CDN用户请求不经过服务器,大大减小了服务器的压力。
活动预热,针对活动的活动库存可以独立出来,不和普通的商品库存共享服务,活动库存活动开始前提前加载到redis,查询全部走缓存,最后扣减库存再视情况而定。
独立部署,资源充足的情况下可以考虑针对秒杀活动单独部署一套环境,这套环境中可以剥离一些可能无用的逻辑,比如不用考虑使用优惠券、红包、下单后赠送积分的一些场景,或者这些场景可以活动结束后异步的统一发放。这只是一个举例,实际上单独针对秒杀活动的话你肯定有很多无用的业务代码是可以剥离的,这样可以提高不少性能。

质量保障

为了保证系统的稳定性,防止你的系统被秒杀,一些质量监控就不得不做。
熔断限流降级,老生常谈,根据压测情况进行限流,可以使用sentinel或者hystrix。另外前端后端都该有降级开关。监控,该上的都上,QPS监控、容器监控、CPU、缓存、IO监控等等。演练,大型秒杀事前演练少不了,不能冒冒失失的就上了吧。核对、预案,事后库存订单 金额、数量核对,是否发生超卖了?金额是否正常?都是必须的。预案可以在紧急情况下进行降级。

数据统计

前端埋点
数据大盘,通过后台服务的打点配合监控系统可以通过大盘直观的看到一些活动的监控和数据
离线数据分析,事后活动的数据可以同步到离线数仓做进一步的分析统计

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,
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java程序员廖志伟

赏我包辣条呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值