高并发设计方案二(秒杀架构)

优化方向:

1)将请求尽量拦截在系统上游(不要让锁冲突落到数据库上去)。传统秒杀系统之所以挂,请求都压倒了后端数据层,数据读写锁冲突严重,并发高响应慢,几乎所有请求都超时,流量虽大,下单成功的有效流量甚小。以12306为例,一趟火车其实只有2000张票,200w个人来买,基本没有人能买成功,请求有效率为0。

2)充分利用缓存,秒杀买票,这是一个典型的读多写少的应用场景,大部分请求是车次查询,票查询,下单和支付才是写请求。一趟火车其实只有2000张票,200w个人来买,最多2000个人下单成功,其他人都是查询库存,写比例只有0.1%,读比例占99.9%,非常适合使用缓存来优化。

常见秒杀架构:

(1)浏览器端,最上层,会执行到一些JS代码 
(2)站点层,这一层会访问后端数据,拼html页面返回给浏览器 
(3)服务层,向上游屏蔽底层数据细节,提供数据访问 
(4)数据层,最终的库存是存在这里的,mysql是一个典型(当然还有会缓存)

各层次优化细节:

第一层,客户端怎么优化(浏览器层,APP层)

问大家一个问题,大家都玩过微信的摇一摇抢红包对吧,每次摇一摇,就会往后端发送请求么?回顾我们下单抢票的场景,点击了“查询”按钮之后,系统那个卡呀,进度条涨的慢呀,作为用户,我会不自觉的再去点击“查询”,对么?继续点,继续点,点点点。。。有用么?平白无故的增加了系统负载,一个用户点5次,80%的请求是这么多出来的,怎么整?

(a)产品层面,用户点击“查询”或者“购票”后,按钮置灰,禁止用户重复提交请求;

(b)JS层面,限制用户在x秒之内只能提交一次请求;

(c)APP层面,可以做类似的事情,虽然你疯狂的在摇微信,其实x秒才向后端发起一次请求。

  • 1
  • 2
  • 3

这就是所谓的“将请求尽量拦截在系统上游”,越上游越好,浏览器层,APP层就给拦住,这样就能挡住80%+的请求,这种办法只能拦住普通用户(但99%的用户是普通用户)对于群内的高端程序员是拦不住的。firebug一抓包,http长啥样都知道,js是万万拦不住程序员写for循环,调用http接口的,这部分请求怎么处理?

第二层,站点层面的请求拦截

怎么拦截?怎么防止程序员写for循环调用,有去重依据么?ip?cookie-id?…想复杂了,这类业务都需要登录,用uid即可。在站点层面,对uid进行请求计数和去重,甚至不需要统一存储计数,直接站点层内存存储(这样计数会不准,但最简单)。一个uid,5秒只准透过1个请求,这样又能拦住99%的for循环请求。 
5s只透过一个请求,其余的请求怎么办?缓存,页面缓存,同一个uid,限制访问频度,做页面缓存,x秒内到达站点层的请求,均返回同一页面。同一个item的查询,例如车次,做页面缓存,x秒内到达站点层的请求,均返回同一页面。如此限流,既能保证用户有良好的用户体验(没有返回404)又能保证系统的健壮性(利用页面缓存,把请求拦截在站点层了)。 
页面缓存不一定要保证所有站点返回一致的页面,直接放在每个站点的内存也是可以的。优点是简单,坏处是http请求落到不同的站点,返回的车票数据可能不一样,这是站点层的请求拦截与缓存优化。

第三层服务层来拦截(反正就是不要让请求落到数据库上去)

服务层怎么拦截?大哥,我是服务层,我清楚的知道小米只有1万部手机,我清楚的知道一列火车只有2000张车票,我透10w个请求去数据库有什么意义呢?没错,请求队列! 
对于写请求,做请求队列,每次只透有限的写请求去数据层(下订单,支付这样的写业务) 
1w部手机,只透1w个下单请求去db 
3k张火车票,只透3k个下单请求去db 
如果均成功再放下一批,如果库存不够则队列里的写请求全部返回“已售完”。

对于读请求,怎么优化?cache抗,不管是memcached还是redis,单机抗个每秒10w应该都是没什么问题的。如此限流,只有非常少的写请求,和非常少的读缓存mis的请求会透到数据层去,又有99.9%的请求被拦住了。

当然,还有业务规则上的一些优化。回想12306所做的,分时分段售票,原来统一10点卖票,现在8点,8点半,9点,…每隔半个小时放出一批:将流量摊匀。 
其次,数据粒度的优化:你去购票,对于余票查询这个业务,票剩了58张,还是26张,你真的关注么,其实我们只关心有票和无票?流量大的时候,做一个粗粒度的“有票”“无票”缓存即可。 
第三,一些业务逻辑的异步:例如下单业务与 支付业务的分离。这些优化都是结合 业务 来的,我之前分享过一个观点“一切脱离业务的架构设计都是耍流氓”架构的优化也要针对业务。

问题说明:

问题1、按你的架构,其实压力最大的反而是站点层,假设真实有效的请求数有1000万,不太可能限制请求连接数吧,那么这部分的压力怎么处理?

答:每秒钟的并发可能没有1kw,假设有1kw,解决方案2个:

(1)站点层是可以通过加机器扩容的,最不济1k台机器来呗。

(2)如果机器不够,抛弃请求,抛弃50%(50%直接返回稍后再试),原则是要保护系统,不能让所有用户都失败。

问题2控制了10w个肉鸡,手里有10wuid,同时发请求这个问题怎么解决哈?
答:上面说了,服务层写请求队列控制
 
问题3:限制访问频次的缓存,是否也可以用于搜索?例如A用户搜索了手机B用户搜索手机,优先使用A搜索后生成的缓存页面?
答:这个是可以的,这个方法也经常用在动态运营活动页,例如短时间推送4kw用户app-push运营活动,做页面缓存。
 
问题4:如果队列处理失败,如何处理?肉鸡把队列被撑爆了怎么办?
答:处理失败返回下单失败,让用户再试。队列成本很低,爆了很难吧。最坏的情况下,缓存了若干请求之后,后续请求都直接返回无票(队列里已经有100w请求了,都等着,再接受请求也没有意义了)
问题5:站点层过滤的话,是把uid请求数单独保存到各个站点的内存中么?如果是这样的话,怎么处理多台服务器集群经过负载均衡器将相同用户的响应分布到不同服务器的情况呢?还是说将站点层的过滤放到负载均衡前?
答:可以放在内存,这样的话看似一台服务器限制了5s一个请求,全局来说(假设有10台机器),其实是限制了5s 10个请求,解决办法:
1)加大限制(这是建议的方案,最简单)
2)在nginx层做7层均衡,让一个uid的请求尽量落到同一个机器上
 
问题6:服务层过滤的话,队列是服务层统一的一个队列?还是每个提供服务的服务器各一个队列?如果是统一的一个队列的话,需不需要在各个服务器提交的请求入队列前进行锁控制?
答:可以不用统一一个队列,这样的话每个服务透过更少量的请求(总票数/服务个数),这样简单。统一一个队列又复杂了。
 
问题7:秒杀之后的支付完成,以及未支付取消占位,如何对剩余库存做及时的控制更新?
答:数据库里一个状态,未支付。如果超过时间,例如45分钟,库存会重新会恢复(大家熟知的回仓),给我们抢票的启示是,开动秒杀后,45分钟之后再试试看,说不定又有票哟~
 
问题8:不同的用户浏览同一个商品 落在不同的缓存实例显示的库存完全不一样 请问老师怎么做缓存数据一致或者是允许脏读?
答:目前的架构设计,请求落到不同的站点上,数据可能不一致(页面缓存不一样),这个业务场景能接受。但数据库层面真实数据是没问题的。
 
问题9:就算处于业务把优化考虑3k张火车票,只透3k个下单请求去db”那这3K个订单就不会发生拥堵了吗?
答:(1)数据库抗3k个写请求还是ok的;(2)可以数据拆分;(3)如果3k扛不住,服务层可以控制透过去的并发数量,根据压测情况来吧,3k只是举例;
 
问题10;如果在站点层或者服务层处理后台失败的话,需不需要考虑对这批处理失败的请求做重放?还是就直接丢弃?
答:别重放了,返回用户查询失败或者下单失败吧,架构设计原则之一是fail fast”
 
问题11.对于大型系统的秒杀,比如12306,同时进行的秒杀活动很多,如何分流?
答:垂直拆分
 
问题12、额外又想到一个问题。这套流程做成同步还是异步的?如果是同步的话,应该还存在会有响应反馈慢的情况。但如果是异步的话,如何控制能够将响应结果返回正确的请求方?
答:用户层面肯定是同步的(用户的http请求是夯住的),服务层面可以同步可以异步。
 
问题13、秒杀群提问:减库存是在那个阶段减呢?如果是下单锁库存的话,大量恶意用户下单锁库存而不支付如何处理呢?
答:数据库层面写请求量很低,还好,下单不支付,等时间过完再回仓,之前提过了。
 
用户提交订单后减库存,加入队列,若加入成功跳转到支付,支付成功移出队列,记入数据库
(队列可记录库存数   并且  队列限制插入订单数,若插入数大于库存数插入失败,插入太多也没有意义)
(插入失败原因分两块   没库存提示已售罄    有库存但队列已满提示业务繁忙请稍后再试)加入购物车不减库存,只做记录,已加入队列但在规定时间内未支付订单,在超时后移出队列,恢复库存,记入数据库(未支付状态)

延伸阅读:

https://blog.csdn.net/luozhonghua2014/article/details/80362614   秒杀系统搭建与部署(1)---开篇
https://blog.csdn.net/luozhonghua2014/article/details/80384061   1万+QPS秒杀最低成本架构与实现
https://blog.csdn.net/luozhonghua2014/article/details/80387285   10万+QPS秒杀限流组件设计与实现 
https://blog.csdn.net/luozhonghua2014/article/details/80396035   秒杀系统架构设计与实现(2)--15万QPS
https://blog.csdn.net/luozhonghua2014/article/details/80404386   秒杀系统架构设计与实现(3)--20万QPS

jmeter高并发设计方案(转)的更多相关文章

  1. jmeter(高并发测试)

    1.首先jmeter需要JDK8以上得运行环境 2.下载jmeter,官方网址:http://jmeter.apache.org/download_jmeter.cgi 3.安装jmeter.jmet ...

  2. JMeter高并发场景下存在请求无数据

  3. 如何使用jMeter对某个OData服务进行高并发性能测试

    For project reason I have to measure the performance of OData service being accessed parallelly. And ...

  4. springboot2.0+线程池+Jmeter以模拟高并发

    声明:原创在这里https://blog.csdn.net/u011677147/article/details/80271174,在此也谢谢哥们. 1.目录结构 2.BusinessThread.j ...

  5. Jmeter之仿真高并发测试-集合点

    场景: 大家在使用Jmeter测试的时候应该发现了, (1)线程启动了就会直接发送测试请求:--如果要模拟在一瞬间高并发量测试的时候,需要调高线程数量,这很耗测试机器的性能,往往无法支持较大的并发数, ...

  6. jmeter性能测试-高并发分布式部署

    jmeter什么要做分布式部署? jmeter是运行在JVM虚拟机上的,当模拟大量并发时,对运行机器的性能/网络负载会很大. 此时就需要使用jmeter的分布式部署功能,实现多台被控机器同时并发访问被 ...

  7. 高并发&高可用系统的常见应对策略

    解耦神器:MQ MQ是分布式架构中的解耦神器,应用非常普遍.有些分布式事务也是利用MQ来做的.由于其高吞吐量,在一些业务比较复杂的情况,可以先做基本的数据验证,然后将数据放入MQ,由消费者异步去处理后 ...

  8. 高并发&高可用系统的常见应对策略 秒杀等-(阿里)

    对于一个需要处理高并发的系统而言,可以从多个层面去解决这个问题. 1.数据库系统:数据库系统可以采取集群策略以保证某台数据库服务器的宕机不会影响整个系统,并且通过负载均衡策略来降低每一台数据库服务器的 ...

  9. 高并发场景-请求合并(一)SpringCloud中Hystrix请求合并

    背景 在互联网的高并发场景下,请求会非常多,但是数据库连接池比较少,或者说需要减少CPU压力,减少处理逻辑的,需要把单个查询,用某些手段,改为批量查询多个后返回. 如:支付宝中,查询"个人信 ...

随机推荐

  1. March 11th, 2018 Week 11th Sunday

    All good things must come to an end. 好景无常. Love is when the other person's happiness is more importa ...

  2. sci-hub免费下载论文

    作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ sci-hub网址: https://gfsoso.99lb.net/sci-hub.html 免费下载 ...

  3. 5255 -- 【FJOI2016】神秘数

    5255 -- [FJOI2016]神秘数 Description 一个可重复数字集合\(S\) 的神秘数定义为最小的不能被 \(S\) 的子集的和表示的正整数.例如: \(S = {1,1,1,4, ...

  4. Scrapy 框架 安装 五大核心组件 settings 配置 管道存储

    scrapy 框架的使用 博客: https://www.cnblogs.com/bobo-zhang/p/10561617.html 安装: pip install wheel 下载 Twisted ...

  5. SQLite事务、错误与自动回滚

    BEGIN TRANSACTION begin-stmt: hide commit-stmt: hide rollback-stmt: hide No changes can be made to t ...

  6. Jmeter-csv文件参数化

    本文以登录的用户名和密码为例 1    创建csv文件 创建.csv文件,用户名和密码中间以逗号隔开 图 1 创建csv文件 2    在线程组中添加并配置CSV Data Set Config 添加 ...

  7. jquery懒加载插件 jquery_lazyload 下载

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code https://pan.baidu.com/s/1UbOeyL_AaSNN_KMA4M ...

  8. 总结一下linux中的分段机制

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 这篇文章主要说一下linux对于分段机制的处理,虽然都说linux不使用分段机制,但是分段机制属于CPU的一个功 ...

  9. 《Python神经网络编程》中文版PDF+英文版PDF+源代码,业界良心书

    下载:https://pan.baidu.com/s/1hI6wMPq4UFvEmpgF3ZV1jg 关于内容 这本书主要揭示神经网络背后的概念,并介绍如何通过Python实现神经网络.全书主要讲了三 ...

  10. java OOM还在看log日志,兄弟你错的的很严重,正确方式是分析dump文件

    目录 OOM异常--intsmaze 正确姿势dump文件分析--intsmaze 正确的姿势--intsmaze dump丢失打印--intsmaze 哪些内存溢出会产生dump文件--intsma ...