(重要)100W请求秒杀架构体系

1、架构设计及说明(热点、非热点数据隔离)

说明:

(1)商品详情页做成静态页,通过nginx直接调用,使用freemaker生成静态页,以sku表的id+.html做为静态页名称,使用canal监听数据库表sku(即商品详情表),有变化则更新静态页。(新增数据则生成一个新的静态页,修改数据则覆盖原来的静态页,删除则删除静态页)

(2)秒杀开始前,用户浏览详情页时,记录商品的信息发送到kafka集群,   Apache Druid大数据实时分析数据库消费kafka数据,进行实时热点数据分析,每5秒执行定时任务从druid中查询最近1小时商品的访问量,将请求数大于10000(假设)的商品信息存入redis。

(3)秒杀开始后,用户对商品下单,通过lvs+nginx,采用openresty+lua脚本从redis中获取该商品信息,如何获取不到,说明是非热点商品,直接调用后台微服务走正常逻辑下单即可。

如果获取到,说明是热点商品,此时有两种方案:

方案一、返回给前端,前端弹出验证码输入框,这样每秒20万并发请求分散成4-5秒内,每秒差不多5万并发。假如总共20万并发量,则需要部署lvs3台,nginx每台可承载3万并发,部署8台,经验输入验证码后,有差不多5万并发量,(1)如果按照应用3秒响应,后台应用差不多200tps,承载5万并发的话,需要部署250台服务器,太多也太贵了,所以在nginx处依然要进行限流,现在部署50台服务器,整个后台应用集群能承受10000的并发量,所以需要在nginx处限流每秒10000并发,也就是每台nginx需要限流1250,剩余的40000个请求直接返回请稍后重试。这8000请求进入后台应用,使用redis预减库存,假如库存有5000个,看是否能获取信号量,否直接返回结果秒杀失败,是则递减库存,返回秒杀成功,5000个请求生成订单,扣减库存等处理。

(2)如果是使用redis预减库存后进入mq,再消费mq,慢慢处理后面的逻辑的方式(使用分布式锁,防止库存线程安全问题)。此时应用tomcat的tps就很大了,假设tomcat线程数是500,每个线程执行的时间是100毫秒(其实可能更快,因为redis和mq处理很快),则500个线程1秒钟就可以处理5000个请求,也就是tps=5000,此时只需要部署200000/5000=40台服务器即可。此时就不需要秒杀开始时前端输入验证码,nginx也无需进行限流,用户体验更好。

方案二、直接在nginx中使用lua脚本做预减库存操作,看是否能获取信号量,否直接返回结果秒杀失败,是则递减库存,返回秒杀成功并进入mq,后台应用消费mq,慢慢处理后面的逻辑即可(使用分布式锁,防止库存线程安全问题)。

(4)下单后通过状态通知系统websocket+netty将状态返回给用户。

(5)openresty+lua脚本解析jwttoken,无效则直接返回,无需经过后端服务,过滤掉大量请求。

真实:

4核8G;

后端服务部署20台;

lvs部署3台,nginx部署10台(单台3万并发量);

redis-cluster集群部署4台(单台2万并发);

kafka集群部署5台,两个分区,每个分区5个副本。

qps大约20万,tps大约4000,(也就是说一个请求过来,差不多会经历2000000/4000=50个查询),每天订单量大约1万,高峰期5-6万,限流采用令牌桶算法,每秒限制3000个请求。

并发量=QPS✖平均响应时间,比如秒杀,一秒处理20万查询,那么系统的并发量就是20万。




最终方案:

1、前端商品详情页做成静态页,放入nginx,再推送到cdn,cdn购买流量包(1T几百块钱)。

        问题1:如果有人恶意刷流量怎么办? 答:采用云厂商的ddos高防产品。

        问题2:有人拿到路径使用程序恶意请求怎么办?答:商用验证码

        问题3:雇多个人多个手机手刷怎么办?答:反作弊服务,还有可能是有的用户一下子搞多个僵尸账号,然                       后 同一时间一起发送请求,就专门进行刷单,此时可以对历史请求日志进行分析,抽取出哪些IP地址                     是喜欢每个秒杀场次都发请求的,而且每次都超速超标发送过多请求,直接就封杀掉;还有就是可以                     对一些账号的日常行为进行数据分析,如果发现有些账号平时都不怎么浏览,几乎从不登录,每次就                     是到秒杀场次的时候才来拼命抢,也可以判定为是刷单账号,直接封禁掉就可以了;反作弊机制,往                     往都是要依赖大数据分析手段的,对账号过往日常行为进行分析,然后封禁账号,或者是让nginx调用                     反作弊接口,判定请求是否合理,这就可以过滤掉一大批作弊请求了。

2、秒杀商品上架时,将商品信息存入redis,请求经过nginx时,需要进行限流,分为整体限流和业务限流,整体限流是根据后台服务整体承载能力进行设定,业务限流可以根据当前场次商品库存总数进行限流(使用lua脚本从redis中获取各商品总库存),比如12点场的秒杀,商品A有1万件,商品B有2万件,商品C有3万件,则可限制流量为1万+2万+3万=6万请求,为了避免网络或者其他原因导致请求失效,则可将流量增加10%-20%,进入服务后要做合法性校验,是否登录、秒杀时间是否正确,限制数量是否合适。

3、幂等性保证,验证这个人是否已经购买过,去redis中进行占位,使用redistemplete的setIfAbsent方法,key是用户id+商品id,value是购买的商品数量(随意值即可),过期时间设置为活动时间减去当前时间,也就是活动结束,就可以删除该占位。如果占位成功则说明没有购买过,则继续操作,否则返回不可重复秒杀。

4、幂等性验证完成后,需要去进行redis预减库存,商品上架时,会使用redisson的信号量,在redis中保存秒杀库存量,预减库存时,使用redissonClient.getSemaphore获取信号量的方法获取到库存量,使用信号量的tryacquire方法进行库存递减,redisson的信号量可保证原子性,递减成功,则生成订单号(雪花算法),然后将订单号,商品数量,用户id,商品id等发送到mq。递减失败,则直接返回用户秒杀失败。

5、进入mq后,比如kafka,如果使用批量消费数据,为加快处理速度,需要使用多线程进行处理,这时为保证线程安全,可以使用分布式锁,比如数据库扣减等。

6、用户秒杀成功后,进入恭喜你秒杀成功页面,然后进入订单页面,此时如果消费mq还未完成,可返回给用户秒杀订单正在处理中,请稍后再试,前端每隔5秒轮询去查询订单是否生成,消费mq完成后,进入订单页面,然后进行支付、履约等操作。

7、订单支付成功后,需要更新订单支付状态,进行履约等操作,这时还要继续发mq。

部署说明:

1、采用以上方案,完成redis和mq处理后就返回给用户结果,与数据库交互动作在后台慢慢处理。此时应用tomcat的tps就很大了,tomcat调优将线程数是500,这段逻辑每个线程执行的时间是100毫秒(其实可能更快,因为redis和mq处理很快,最多就30毫秒),则500个线程1秒钟就可以处理5000个请求,也就是tps=5000,此时只需要部署200000/5000=40台服务器即可。此时就不需要秒杀开始时前端输入验证码,用户体验更好。

2、为保障20万并发,

nginx:每台3万并发的话,需要8台,做个冗余,部署10台。

后台服务:每台tomcat并发1万,需要20台,部署30台做冗余

redis:每台2万并发, 可部署12台作为一个集群。

mq:由于秒杀商品的数量并不多,经过redis预减库存后,并发量更小了,部署两台即可(kafka)

3、万一突然流量变大,超过20万,会导致服务被压垮,这时需要在nginx进行限流,现在能承载20万的并发,就按20万的承载量进行限流,10台nginx,每台限制2万即可。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容