hbnnmall秒杀服务
一、细节总结
需要关注的几个问题:
- 流控;
- 降级熔断;
- 风控;
- 库存设计;
- 高并发处理;
1、流控
限流是保护秒杀系统的重中之重,对于瞬时并发量巨大的情况下,如何保证系统不崩是关键,防止超大规模的流量打到秒杀后端,导致系统挂掉。
1)无用(多余)请求;
比如秒杀商品只有2000件,但预约数高达1000千万,可能有%80的流量都是无用的,就不必要再进来了。
2)负载均衡
后段服务部署多台机器,上层通过软件实现负载均衡,一般通过LVS+Nginx两层分别实现负载均衡。
3)服务限流
1) 采用限流算法。
之前专门写过一篇文章分析过: 限流算法
2) 消息队列
通过队列实现消峰,其实从严格意义上来讲,这个不算是限流。算是导流,将流量都打到消息队列,消费者异步串行处理减小瞬时并发请求。
3)缓存
通过设置不同层级的缓存,避免流量重复打入。
- 前端静态文件缓存,Nginx以及CDN;
- 后端服务器本地缓存;
- 后段服务Redis缓存
2、熔断降级
就是将一些服务进行熔断降级,保证高并发情况下,系统仍然是OK的。可以在开始前就行降级。也可以在服务异常了,实时进行熔断或者降级。
针对这部分,可以和上面的限流一起做,目前比较成熟的框架有很多,比如阿里的sentinel,参考连接: 扛住阿里双十一高并发流量,Sentinel是怎么做到的?
在hbnnmall的秒杀设计中,对于服务端限流以及降级熔断,我直接使用了阿里的sentinel,没必要自己重复造轮子,这个已经非常成熟了。
3、风控
风控主要是屏蔽所有想要通过作弊手段进行抢购的请求。
最基本的是同一个用户的多次请求,除了第一次都是无效的。
其次,就是调用风控dubbo服务,根据某些规则进行风控,比如IP黑名单,用户黑名单等等。
4、库存设计
库存就是不要超卖,可以少卖。通过预设置来控制,使用Redis+Lua实现。总库存的校验在下单的时候直接走总流程即可。
5、高并发处理
有效的用户通过限流服务后进行抢购后端,多个用户进行抢购的设计也是很重要的,golang是最适合做这个工作的。
二、整体设计
前端: Vue+Django+云存储CDN;
Java后端:主要实现限流、风控等功能。
Go后端:实现抢购秒杀。
三、秒杀流程图
测试工具:
库存设置成100个,模拟共1万个用户取抢购
import requests
import json
import time
import random
from multiprocessing.dummy import Pool as ThreadPool
pool = ThreadPool(6)
def seckill(uid):
url = "http://127.0.0.1:7878/seckill"
data = {
"uid":uid,
"act_id":10,
}
# headers = {
# "Content-Type":"application/json"
# }
resp = requests.post(url=url,data=json.dumps(data))
resp = resp.text
# print(resp)
resp = json.loads(resp)
# time.sleep(random.randint(0,1))
if "data" not in resp or resp["data"] == "false":
return False
return resp["data"]
urls = range(1,10000)
results = pool.map(seckill,urls)
results = filter(lambda x: x, list(results))
print(list(results))
print(len(list(results)))
pool.close()
pool.join()
参考资料:
Sentinel: The Flow Sentinel of Your Services
这个注解一次搞定限流与熔断降级:@SentinelResource
微信分享/微信扫码阅读