秒杀系统优化思路
将请求尽量拦截在系统上游
充分利用缓存
客户端层
- 按钮置灰、禁止重复提交
js控制,在X 秒内只能提交一次请求
站点层
通过用户唯一标识uid进行统计和去重,在X 秒内 同一个uid只能透过一次请求
- 做页面缓存在X 秒内同一个uid请求均返回同样的数据
服务层
- 将请求转化为队列,像秒杀这类业务的数量固定的,可以把多余的请求直接拦截在队列之外
- 对于写请求,我们可以通过队列进行分段处理,每次只透有限的写请求到数据层,处理完了再处理下一批,如果库存不足则队列里的都返回已抢光
- 对于读请求,可以加缓存
- 业务规则上,可以将用户分时分段,将流量均摊到不同时段
数据库层
- 可以进行分库分表
- 归档
- 主从
- 集群
分布式ID生成
- 数据库的ID自增
- 增加主库,每个主库设置不同的初始值和步长
- 单点批量ID生成服务
- UUID,缺点是不能保证递增,作为主键建索引效率低
- 取当前毫秒数,并发超过1000会重复
- 类snowflake算法(雪花算法)

线程数究竟设多少合理
N核服务器,通过执行业务的单线程分析出本地计算时间为x,等待时间为y,则工作线程数(线程池线程数)设置为 N*(x+y)/x,能让CPU的利用率最大化。
单点系统架构的可用性与性能优化
单点系统存在的问题
- 非高可用:既然是单点,master一旦发生故障,服务就会受到影响
- 性能瓶颈:既然是单点,不具备良好的扩展性,服务性能总有一个上限,这个单点的性能上限往往就是整个系统的性能上限
如何高可用
- shadow-master它能够解决高可用的问题,并且故障的转移是自动的,不需要人工介入,但不足是它使服务资源的利用率降为了50%,业内经常使用keepalived+vip的方式实现这类单点的高可用。
负载均衡
- 负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据【均匀】分摊到多个操作单元上执行,负载均衡的关键在于【均匀】。
客户端层->反向代理层
- 通过“DNS轮询”: DNS-server对于一个域名配置了多个解析ip,每次DNS解析请求来访问DNS-server,会轮询返回这些ip,保证每个ip的解析概率是相同的。这些ip就是nginx的外网ip,以做到每台nginx的请求分配也是均衡的。
反向代理层->站点层
- 通过nginx 配置实现负载均衡到具体的站点
站点层->服务层
- 通过Ribbon实现进程内的负载均衡
DNS轮询
- nginx:一个高性能的web-server和实施反向代理的软件
- lvs:Linux Virtual Server,使用集群技术,实现在linux操作系统层面的一个高性能、高可用、负载均衡服务器
- keepalived:一款用来检测服务状态存活性的软件,常用来做高可用
- f5:一个高性能、高可用、负载均衡的硬件设备(听上去和lvs功能差不多?)
- DNS轮询:通过在DNS-server上对一个域名设置多个ip解析,来扩充web-server性能及实施负载均衡的技术
接入层负载均衡演变
- DNS轮询

- 通过一个域名匹配多个服务IP来达到负载均衡
- 缺点:不能保证服务可用性
- 暴露了太多IP
- nginx反向代理

- 站点层与浏览器层之间加入了一个反向代理层,利用高性能的nginx来做反向代理,nginx将http请求分发给后端多个web-server
- 缺点:nginx单点问题
- keepalived

- 做两台nginx组成一个集群,分别部署上keepalived,设置成相同的虚IP,保证nginx的高可用
- 当一台nginx挂了,keepalived能够探测到,并将流量自动迁移到另一台nginx上,整个过程对调用方透明
- 缺点:资源利用率只有50%
- lvs/f5

- 如果通过nginx可以扩展多个tomcat一样,可以通过lvs来扩展多个nginx
- 通过keepalived+VIP的方案可以保证可用性
接入层架构要考虑的问题域为:高可用、扩展性、反向代理+扩展均衡 nginx、keepalived、lvs、f5可以很好的解决高可用、扩展性、反向代理+扩展均衡的问题 水平扩展scale out是解决扩展性问题的根本方案,DNS轮询是不能完全被nginx/lvs/f5所替代的
异构服务器如何负载均衡和过载保护
动态权重设置
- 用一个动态权重来标识每个service的处理能力,默认初始处理能力相同,即分配给每个service的概率相等;
- 每当service成功处理一个请求,认为service处理能力足够,权重动态+1;
- 每当service超时处理一个请求,认为service处理能力可能要跟不上了,权重动态-10(权重下降会更快);
- 为了方便权重的处理,可以把权重的范围限定为[0, 100],把权重的初始值设为60分。
过载保护
什么是过载保护?
- 互联网软件架构设计中所指的过载保护,是指当系统负载超过一个service的处理能力时,如果service不进行自我保护,可能导致对外呈现处理能力为0,且不能自动恢复的现象。而service的过载保护,是指即使系统负载超过一个service的处理能力,service让能保证对外提供有损的稳定服务。
如何进行过载保护?
- 通过动态权重,针对那些超时次数到达一定阀值的服务提供一定时间段的请求间隙
高并发优化方案
- 反向代理层可以通过“DNS轮询”的方式来进行水平扩展;
- 站点层可以通过nginx来进行水平扩展;
- 服务层可以通过服务连接池来进行水平扩展;
- 数据库可以按照数据范围,或者数据哈希的方式来进行水平扩展;
高可用优化方案
(1)【客户端层】到【反向代理层】的高可用,是通过反向代理层的冗余实现的,常见实践是keepalived + virtual IP自动故障转移
(2)【反向代理层】到【站点层】的高可用,是通过站点层的冗余实现的,常见实践是nginx与web-server之间的存活性探测与自动故障转移
(3)【站点层】到【服务层】的高可用,是通过服务层的冗余实现的,常见实践是通过service-connection-pool来保证自动故障转移
(4)【服务层】到【缓存层】的高可用,是通过缓存数据的冗余实现的,常见实践是缓存客户端双读双写,或者利用缓存集群的主从数据同步与sentinel保活与自动故障转移;更多的业务场景,对缓存没有高可用要求,可以使用缓存服务化来对调用方屏蔽底层复杂性
(5)【服务层】到【数据库“读”】的高可用,是通过读库的冗余实现的,常见实践是通过db-connection-pool来保证自动故障转移
(6)【服务层】到【数据库“写”】的高可用,是通过写库的冗余实现的,常见实践是keepalived + virtual IP自动故障转移
