从高维度出发,从总体上思考问题。秒杀其实主要解决两个问题,一个是并发读,一个是并发写。数据库
并发读的核心优化理念是尽可能减小用户到服务端来读数据,或者让他们读更少的数据;浏览器
并发写的处理原则页同样,它要求咱们在数据库层面独立出来一个库,作特殊的处理。缓存
咱们还要针对秒杀系统作一些保护,针对意料以外的状况设计兜底方案,以防止最坏的状况发生。性能优化
要打造并维护一个超大流量并发读写、高性能、高可用的系统,在整个用户请求路径上从浏览器到服务端咱们要遵循几个原则,就是要保证用户请求的数据尽可能少,请求数尽可能少,路径尽可能端,依赖尽可能少,而且不要有单点。服务器
秒杀的总体架构能够归纳为"稳、准、快"几个关键字。网络
技术角度地看"稳、准、快",就对应了咱们架构上地高可用、一致性和高性能地要求。架构
首先是指用户请求的数据能少就少。由于这些数据传输需哟啊事件,服务器在写网络时要作压缩和字符编码,很是消耗CPU。其次,系统依赖的数据能少就少,包括系统完成某些业务逻辑须要读取和保存的数据,调用其余服务会设计数据的序列化和反序列化,会很是消耗cpu,与数据库打交道越少越好,数据越简单,越小则越好。并发
所谓"路径",就是用户发出请求到返回数据这个过程当中,需求通过的中间节点数。一般,这些节点能够表示为一个系统或者一个新的socket连接。每通过一个几点,通常都会产生一个新的Socket连接。每增长一个连接都会增长新的不肯定性。缩短请求路径不只能够增长可用性,一样能够有效提高性能(减小数据的序列化与反序列化),并减小延时(能够减小网络传输耗时)。socket
缩短访问路径有一种办法,就是多个相互强依赖的应用合并部署在一块儿,把远程过程调用变成JVM内部之间的方法调用。分布式
所谓依赖,指的是要完成一次用户请求必须依赖的系统或者服务,这里的依赖指的是强依赖。
举个例子,好比说你要是展现秒杀页面,而这个页面必须强依赖商品信息、用户信息,还有其余如优惠券、成交列表等这些对秒杀不是非要不可的信息(弱依赖),这些弱依赖在紧急状况下就能够去掉。
要减小依赖,咱们能够给系统进行分级,好比0级系统、1级系统、2级系统、3级系统,0级系统若是是最重要的系统,那么0级系统强依赖的系统也一样是最重要的系统,以此类推。
注意,0级系统要尽可能减小对1级系统的强依赖,防止重要的系统被不重要的系统拖垮。例如支付系统是0级系统,而优惠券是1级系统的话,在极端状况下能够把优惠券降级,防止支付系统被优惠券这个1级系统给拖垮。
设计分布式系统最重要的原则就是"消除单点"。
如何避免单点,我认为关键点是避免将服务的状态和机器绑定,即把服务无状态化,这样服务就能够在机器中随意移动。
商品购买页面增长一个"定时上架"功能,仅在秒杀开始时才让用户看到购买按钮,当商品的库存卖完了就结束了。
随着请求量的加大,这个简单的架构很快就遇到瓶颈。须要架构改造,包括:
当访问量超百万的并发,须要进一步提高秒杀系统的性能,进一步升级,好比:
在这里,咱们对页面进行了进一步的静态化,秒杀过程当中不须要刷新整个页面,而只须要服务端请求不多的动态数据。并且,最关键的详情和交易系统都增长了本地缓存,来提早缓存秒杀商品的信息,热点数据库也作了独立部署,等等。
每次升级都须要定制不少地方,也就是越"不通用"。例如,秒杀商品缓存在每台机器的内存中,这种方式显然不太适合太多商品同时进行秒杀的状况,由于单机的内存始终有限。因此要取得极致的性能,就要在其余地方(好比,通用性、易用性、成本等方面)有所牺牲。