电商平台的秒杀、抢购开发总结
日期:2018-09-16
来源:程序思维浏览:2612次
您可能已经开发了一个具有高并发性或尖峰程序的系统,但您必须已经与它联系,例如电子商务平台加速器、抢购和其他活动,以及12306春节门票。

活动周期短,瞬时流量大(高并发),技术将在这种情况下发生。
第一:高并发性
技术要做的是优化程序并优化程序性能。单个请求时间可以从50ms优化到25ms,并且它可以在一秒内成功响应双重请求。
另一方面,添加服务器和处理具有更大集群的用户请求更为重要。设计可靠灵活的分布式解决方案更为重要。
第二:时间短
火热的秒杀活动,它真的会在一秒之内买断货,大多数用户觉得提交订单的过程必须等待几秒钟、甚至十几秒,更糟糕的是,请求是一个错误。
然后一个好的秒杀经验,当然希望最小化用户等待时间,并准确提示用户是否还有商品库存。而这些,还需要有出色的编程才能确保。
第三:系统容量估算
在设计系统时,有必要进行容量估算,即预先计算我们运载系统的顺序。
如果在线前端服务器规范是8核16G内存服务器并且提交订单的处理需要100ms,那么您可以简单地计算:
每秒可处理的订单请求数= 1000ms / 100ms * 8 = 80qps
上述结果对于尖峰系统来说绝对不是理想的。
如果您可以优化处理时间并将其缩短到10毫秒,则可以达到800qps。
如果我们可以继续优化程序并快速区分库存和无库存处理,那么在没有库存的情况下处理可能长达1ms或更短。这样,您可以在没有库存的情况下获得更好的性能,并且可以实现数万个qps。
以上估算是针对单台机器的,所以只需增加前端服务器,你能有更好的并发处理吗?
它肯定不是那么简单,因为数据库、缓存系统甚至计算机房网络带宽都将成为瓶颈。
所以有一个更好的分布式解决方案。
第四:良好的分布式解决方案
当然,一个好的分布式解决方案是稳定可靠的,不会弄乱,然后扩展方便。最好的效果当然是添加服务器,并发处理能力可以1:1线性增长。
例如,如果单机qps是1k,那么10台服务器可以做1w,100台可以做到每秒10w。
为了达到这种线性增长效果,有必要消除瓶颈,否则会花费太多。拒绝错误分发尤为重要。例如,前端服务器可以独立存在,但它们都依赖于集中式数据库或缓存系统。最后,集中式数据库或缓存系统必须无法承受相同的效果。分散式。
第五:关注系统的瓶颈
每个人都有一些基本的共识,即系统的处理速度。
程序内数据读写>Redis>Mysql>磁盘
独立网络请求>局域网请求>跨机房要求
当我们优化程序时,尽可能以最快的方式使用最短的逻辑。
使用redis而不是mysql来保存依赖于订单处理的数据,并将从redis获得的数据替换为程序中提交的数据,例如:商品库存信息,用户订单信息。
在逻辑处理中,快速和早期中断的逻辑被置于最前沿,例如:验证登录,验证问题和答案。
当我们执行分布式解决方案时,尝试将资源调用放在最近的位置。
前端服务器所依赖的数据尽可能靠近LAN。如果可以在一台机器上读取redis服务,则程序响应数据响应将更加复杂。
没有跨机房网络请求,没有跨机房网络请求,不出现跨机房网络请求,重要的事情说三次。
第六:什么语言更适合这种类型的系统
在课程中使用PHP语言,开发这样的系统没有问题。
当然,就像使用golang一样,ngx_lua在高并发性和性能方面可能更有利。
如果你使用java、.net,当然作为一个系统,语言只是一个工具,更好的设计和优化,以达到最终的预期效果。
通过上面的基本概念,我们来看看特定运行时旁边会发生什么。
以下是一些具体问题:
问题1:积压
只有10个库存,但一秒钟就有1k个订单。你怎么能不夸大?
核心思想是确保库存减少是原子操作,10 - 返回9,9 - 返回8,8 - 返回7。
它无法读取缺货10,10-1 = 9然后更新回来。由于此读取和更新是同时执行的,因此1k订单可能会成功,而库存实际上只有10个。
那么你如何保证原子操作?
1.数据库:
更新产品集left_numleft_num = left_num-1其中left_num>0;
这里使用的是left_num = left_num-1,如果是left_num>0可以成功执行,数据库查询、更新对锁定很有用,就是保证更新操作的原子性。
数据库性能很差,不推荐使用。
2.分布式锁
使用redis创建分布式锁,reids->Setnx('lock',1)设置一个锁,并执行程序以完成del锁。
锁定过程不利于并发执行。每个人都在等待锁定解锁。不推荐。
3.消息队列
所有订单请求都放在消息队列中,另一个守护程序逐个处理队列中的订单请求。
并发不受影响,但用户等待很长时间,并且有许多订单进入队列。经验不好,不推荐。
4. redis减量
通过redis->Incrby('product', - 1)减少后获得股票数量。
表现非常好,而且经验也很好。在PHP spike过程中,在优化之后,使用此方法,并且不使用上面提到的其他方法,每个人都应该能够比较它。
问题2:如何规划群集
由于前端服务器彼此不相关,因此群集数量不受影响。
redis的性能每秒可以达到数万个响应,因此群集的大小,即可以携带的redis服务的数量。
例如:前端服务器是1~2k qps(有库存时),那么10 + 1 redis可以是一个单独的集群,每秒可以支持1~2w的订单。
上述10个集群可以在一秒内处理10w~20w的有效指令。
如果加标活动的库存小于1w,并且参与者数量预计约为一百万,则可以修复一个群集。
如果涉及的峰值数超过1000万,则将使用多个集群。
问题3:多个集群中的数据如何保持一致?
不使用多集群数据同步,而是使用散列,并且每个集群的数据是独立的。
假设有10个项目,每个项目有1w库存,计划10个集群。然后每个集群有10种商品,每种商品都有1k库存。
每个集群只需负责销售自己的库存。至于那个,会有用户知道有10个集群,然后每个集群都会抓住它。
在这种情况下,请不要使用程序来处理它,使用操作规则,然后在事件结束后处理订单。
如果您担心哈希的不合理性,例如特别少量的群集用户,则可以引入中央控制服务来监视每个群集的清单,然后进行平衡。
问题4:机器人抢断时该怎么办:没有什么比DDOS攻击更好,它只会使自己更强大王道。
在操作策略中,可以严格控制用户注册,必须进行登录,并在提交订单时引入图像验证码,问答,交互验证等。

活动周期短,瞬时流量大(高并发),技术将在这种情况下发生。
第一:高并发性
技术要做的是优化程序并优化程序性能。单个请求时间可以从50ms优化到25ms,并且它可以在一秒内成功响应双重请求。
另一方面,添加服务器和处理具有更大集群的用户请求更为重要。设计可靠灵活的分布式解决方案更为重要。
第二:时间短
火热的秒杀活动,它真的会在一秒之内买断货,大多数用户觉得提交订单的过程必须等待几秒钟、甚至十几秒,更糟糕的是,请求是一个错误。
然后一个好的秒杀经验,当然希望最小化用户等待时间,并准确提示用户是否还有商品库存。而这些,还需要有出色的编程才能确保。
第三:系统容量估算
在设计系统时,有必要进行容量估算,即预先计算我们运载系统的顺序。
如果在线前端服务器规范是8核16G内存服务器并且提交订单的处理需要100ms,那么您可以简单地计算:
每秒可处理的订单请求数= 1000ms / 100ms * 8 = 80qps
上述结果对于尖峰系统来说绝对不是理想的。
如果您可以优化处理时间并将其缩短到10毫秒,则可以达到800qps。
如果我们可以继续优化程序并快速区分库存和无库存处理,那么在没有库存的情况下处理可能长达1ms或更短。这样,您可以在没有库存的情况下获得更好的性能,并且可以实现数万个qps。
以上估算是针对单台机器的,所以只需增加前端服务器,你能有更好的并发处理吗?
它肯定不是那么简单,因为数据库、缓存系统甚至计算机房网络带宽都将成为瓶颈。
所以有一个更好的分布式解决方案。
第四:良好的分布式解决方案
当然,一个好的分布式解决方案是稳定可靠的,不会弄乱,然后扩展方便。最好的效果当然是添加服务器,并发处理能力可以1:1线性增长。
例如,如果单机qps是1k,那么10台服务器可以做1w,100台可以做到每秒10w。
为了达到这种线性增长效果,有必要消除瓶颈,否则会花费太多。拒绝错误分发尤为重要。例如,前端服务器可以独立存在,但它们都依赖于集中式数据库或缓存系统。最后,集中式数据库或缓存系统必须无法承受相同的效果。分散式。
第五:关注系统的瓶颈
每个人都有一些基本的共识,即系统的处理速度。
程序内数据读写>Redis>Mysql>磁盘
独立网络请求>局域网请求>跨机房要求
当我们优化程序时,尽可能以最快的方式使用最短的逻辑。
使用redis而不是mysql来保存依赖于订单处理的数据,并将从redis获得的数据替换为程序中提交的数据,例如:商品库存信息,用户订单信息。
在逻辑处理中,快速和早期中断的逻辑被置于最前沿,例如:验证登录,验证问题和答案。
当我们执行分布式解决方案时,尝试将资源调用放在最近的位置。
前端服务器所依赖的数据尽可能靠近LAN。如果可以在一台机器上读取redis服务,则程序响应数据响应将更加复杂。
没有跨机房网络请求,没有跨机房网络请求,不出现跨机房网络请求,重要的事情说三次。
第六:什么语言更适合这种类型的系统
在课程中使用PHP语言,开发这样的系统没有问题。
当然,就像使用golang一样,ngx_lua在高并发性和性能方面可能更有利。
如果你使用java、.net,当然作为一个系统,语言只是一个工具,更好的设计和优化,以达到最终的预期效果。
通过上面的基本概念,我们来看看特定运行时旁边会发生什么。
以下是一些具体问题:
问题1:积压
只有10个库存,但一秒钟就有1k个订单。你怎么能不夸大?
核心思想是确保库存减少是原子操作,10 - 返回9,9 - 返回8,8 - 返回7。
它无法读取缺货10,10-1 = 9然后更新回来。由于此读取和更新是同时执行的,因此1k订单可能会成功,而库存实际上只有10个。
那么你如何保证原子操作?
1.数据库:
更新产品集left_numleft_num = left_num-1其中left_num>0;
这里使用的是left_num = left_num-1,如果是left_num>0可以成功执行,数据库查询、更新对锁定很有用,就是保证更新操作的原子性。
数据库性能很差,不推荐使用。
2.分布式锁
使用redis创建分布式锁,reids->Setnx('lock',1)设置一个锁,并执行程序以完成del锁。
锁定过程不利于并发执行。每个人都在等待锁定解锁。不推荐。
3.消息队列
所有订单请求都放在消息队列中,另一个守护程序逐个处理队列中的订单请求。
并发不受影响,但用户等待很长时间,并且有许多订单进入队列。经验不好,不推荐。
4. redis减量
通过redis->Incrby('product', - 1)减少后获得股票数量。
表现非常好,而且经验也很好。在PHP spike过程中,在优化之后,使用此方法,并且不使用上面提到的其他方法,每个人都应该能够比较它。
问题2:如何规划群集
由于前端服务器彼此不相关,因此群集数量不受影响。
redis的性能每秒可以达到数万个响应,因此群集的大小,即可以携带的redis服务的数量。
例如:前端服务器是1~2k qps(有库存时),那么10 + 1 redis可以是一个单独的集群,每秒可以支持1~2w的订单。
上述10个集群可以在一秒内处理10w~20w的有效指令。
如果加标活动的库存小于1w,并且参与者数量预计约为一百万,则可以修复一个群集。
如果涉及的峰值数超过1000万,则将使用多个集群。
问题3:多个集群中的数据如何保持一致?
不使用多集群数据同步,而是使用散列,并且每个集群的数据是独立的。
假设有10个项目,每个项目有1w库存,计划10个集群。然后每个集群有10种商品,每种商品都有1k库存。
每个集群只需负责销售自己的库存。至于那个,会有用户知道有10个集群,然后每个集群都会抓住它。
在这种情况下,请不要使用程序来处理它,使用操作规则,然后在事件结束后处理订单。
如果您担心哈希的不合理性,例如特别少量的群集用户,则可以引入中央控制服务来监视每个群集的清单,然后进行平衡。
问题4:机器人抢断时该怎么办:没有什么比DDOS攻击更好,它只会使自己更强大王道。
在操作策略中,可以严格控制用户注册,必须进行登录,并在提交订单时引入图像验证码,问答,交互验证等。