前言
面试问项目经验主要是想了解所做项目用到的技术,以及自己在项目中扮演的角色。
一、秒杀系统
秒杀系统往往不是咱的项目经验,但是面试可能会问,在说自己项目经验的时候也可以往秒杀和高并发上面带。
可能遇到的问题
-
高并发
一般就是比如10w人去抢购100个礼品,供不应求,而且并发量是超高的,可能几秒内就几千几万个并发。
-
超卖
需要保证秒杀售卖的商品数量正好等于或者小于设定的值,而肯定不能超过。比如商家预算可以便宜售卖100个产品,如果卖出了200个就是很严重的事故了。
-
恶意请求
比如黄牛的售票软件频繁发送请求,比人速度快多了。 -
链接暴露
我理解就是泄露了网页源码,或者能被看到接口地址然后直接绕开前端进行请求,或者被抓包了。 -
数据库压力
这应该包括数据库和缓存的压力,是比较容易想到的。
解决问题的方法
1. 系统架构
分布式部署,分布式架构,服务采用单一职责。秒杀相关的服务和代码单独部署,也可以单独使用一个数据库。
单一职责的好处就是就算秒杀没抗住,秒杀库崩了,服务挂了,也不会影响到其他的服务。
2.接口校验
为了防止接口链接暴露之后,黄牛通过程序获取北京时间,在时间到的一瞬间秒杀,这样比人手点快多了。
个人认为可以采用登录认证,动态链接的方式,动态生成口令让后端校验,或者增加接口签名
3.Redis集群
edis集群,主从同步、读写分离,我们还搞点哨兵,开启持久化直接无敌高可用!
4.Nginx
Nginx大家想必都不陌生了吧,这玩意是高性能的web服务器,并发也随便顶几万不是梦,但是我们的Tomcat只能顶几百的并发呀,那简单呀负载均衡嘛,一台服务几百,那就多搞点,在秒杀的时候多租点流量机。
通过Nginx将流量分发给不同的服务。
恶意请求拦截也需要用到它,一般单个用户请求次数太夸张,不像人为的请求在网关那一层就得拦截掉了,不然请求多了他抢不抢得到是一回事,服务器压力上去了,可能占用网络带宽或者把服务器打崩、缓存击穿等等。
5.资源静态化
前端有自己的服务器,不通过后端来获取图片等资源。
6.按钮控制
前端定时请求后端获取最新的北京时间,等时间到了也可以再过几秒再给请求。
7.限流
- 前端限流:这个很简单,一般秒杀不会让你一直点的,一般都是点击一下或者两下然后几秒之后才可以继续点击,这也是保护服务器的一种手段。
- 后端限流:秒杀的时候肯定是涉及到后续的订单生成和支付等操作,但是都只是成功的幸运儿才会走到那一步,那一旦100个产品卖光了,return了一个false,前端直接秒杀结束,然后你后端也关闭后续无效请求的介入了。
8.库存预热
我们要开始秒杀前你通过定时任务或者运维同学提前把商品的库存加载到Redis中去,让整个流程都在Redis里面去做,然后等秒杀介绍了,再异步的去修改库存就好了。
但是用了Redis就有一个问题了,我们上面说了我们采用主从,就是我们会去读取库存然后再判断然后有库存才去减库存,正常情况没问题,但是高并发的情况问题就很大了。
Lua脚本
Lua脚本是类似Redis事务,有一定的原子性,不会被其他命令插队,可以完成一些Redis事务性的操作。这点是关键。知道原理了,我们就写一个脚本把判断库存扣减库存的操作都写在一个脚本丢给Redis去做,那到0了后面的都Return False了是吧,一个失败了你修改一个开关,直接挡住所有的请求,然后再做后面的事情嘛。
9.限流&降级&熔断&隔离
熔断是不影响别的系统,隔离是自己不行了也不去调其他系统服务了。限流是顶不住了挡一部分流量,降级就是当系统的容量达到一定程度时,限制或者关闭系统的某些非核心功能,从而把有限的资源保留给更核心的业务。降级可以有个开关去实现。
10.削峰填谷
把请求放消息队列,然后一点点消费去改库存,不过单个商品其实一次修改就够了,我这里说的是某个点多个商品一起秒杀的场景,像极了双十一零点。