用户层:用户端展现的部分,主要涉及商品的相关信息及当前 “秒杀活动的信息”
CDN层:缓存 “秒杀” 活动的静态资源文件。
负载均衡层:拦截请求及分发路由等。
服务层:“秒杀” 活动的相关逻辑处理。
基础设施层:数据存储、大数据计算及消息推送等操作。
业务特点:
在“秒杀”活动还没开始的时候,流量一直是很平稳的状态;
当“秒杀”活动活动结束的后,流量又会急速下落。
限时、限量、限价
活动预热
持续时间短
技术特点:
顺时并发量高:“秒杀”活动商品限时、限量、限价的特性,决定了“秒杀”活动一开始就会出现流量洪峰,即瞬间并发量达到峰值。
并发读写:“读”比“写”要多得多,是“读多写少”的场景。
注意:在应对“秒杀”活动时,需要进行限流操作,利用流量的时间分片来缓冲瞬时的大流量。
数据量应该尽量少。
简化“秒杀”页面大小,去除一些不必要页面装饰。
尽量提前预热。
发送“秒杀”时只带上最有用的信息。
在服务端返回数据时,返回最简数据体。
减少依赖外部服务。
请求数应该尽量少(用户进入商品秒杀详情页时,浏览器会渲染各种额外数据,如CSS,文件图片等,这些信息需要减少)
请求路径尽量短
尽量使用异步化
避免单节点(将服务完全无状态化??)
将静态页面和动态页面(静态数据和动态数据)解耦分离,用不同系统承载对应流量。提升整个副武的访问性能和可维护性。
页面中几乎不怎么变化的数据(即补一句用户的Cookie、基本信息、地域、时间、等各种属性来生成的数据),如:
CSS和 JS 文件中静态数据
活动页中的 HTML 静态文件
图片等相关资源
依据当前用户属性动态生成的数据。。
处理动态数据体现在技术架构上采用:
清晰的分层架构
服务架构
缓存架构
分而治之,动态数据和静态数据解耦,分别使用各自的架构系统来承载对应的流量。
访问静态数据快,访问动态数据慢,提前生成好需要动态获取的数据,然后使用静态页面加速技术来访问这些数据。
页面静态化数据的介绍:直接缓存HTTP连接,而不是缓存数据。
适用场景:动态数据总量不是很大,生成的静态页面数量不多的业务
例如:微博热点信息,淘宝热门商品
在一定时间内被大量用户访问的数据。
热点数据又分为:“静态热点数据” 和 “动态热点数据”:
静态热点数据:可以被提前预知的热点数据。
动态热点数据:不能被提前预知的数据。
发现热点数据后一般做法是:优化、限制和隔离
热点数据的优化:直接将发现的热点数据写入分布式缓存,并且根据业务情况对其设置缓存过期时间。
热点数据的限制:热点数据的限制是一种保护系统的机制,目的是不让热点数据抢占其他请求的资源。
例如:线程池隔离技术,将每个热点数据的处理放在独立的线程池内,这样可以避免大流量的冲击而影响其他请求使用机器资源。
热点数据的隔离:热点数据的隔离也是一种保护机制,不能因为数据量访问过大造成业务崩溃。
例如:先将“秒杀”业务和其他主线业务隔离开,防止他们互相影响;然后,将“秒杀”系统独立部署,且使用独立的域名,最后,“秒杀”系统使用独立的数据库。
由于瞬时的流量洪峰会带来严重的服务端 读/写 性能问题、数据库锁,以及服务器资源占用问题。
CDN层流量控制
由动静分离联系 —> 应该提前生成尽可能多的数据,然后将其放入到 CDN 节点缓存中(CDN在物理架构上离用户比较近)
反向代理层流量控制
通过后端服务 Job 的方式定时提前生成好前端需要的静态数据,然后将其发送到内容分发服务上,内容分发服务会将这些静态数据分发给所有反向代理服务器。
程序开发上,代码独立,不要与平台其他项目合在一起。
在部署时,独立部署,分散流量,避免不适合的流量影响主题业务。
使用独立域名,或按照一定的 URL 规则在反向代理层进行路由。
做好系统保护和限流。
请求量超过最大请求限制,可以直接拒绝超过请求返回至 “秒杀” 结束信息。
此处需要对数据库进行IO说明是下单成功的流量,有如下建议:
如果不是临时的活动,建议使用独立数据库作为“秒杀”活动的数据库。
将数据库配置成读写分离。
尝试去除行锁。
对于高并发的秒杀活动来说,这种行锁的机制可能会导致大量的线程阻塞,降低系统的吞吐量。特别是当秒杀活动开始时,大量的用户会同时请求同一条商品数据,如果使用行锁,那么每次只能有一个用户的请求被处理,其他的用户都需要等待,这会导致用户体验非常差,也会使得系统的响应时间大大增加。
使用分布式锁
对于一般的购买过程,用户是不需要关心库存的。但是高并发情况下用户争抢库存,如果没有控制好就会出现超卖情况。
下单后扣减库存:
最简单,最好理解。
用户下单后不付款,利用 “秒杀器” 恶意大量抢购商品。
支付后扣减库存:
用户付完款后再扣减库存。
也存在 “超卖” 问题,大部分付款之后也不会抢到。
预扣减库存:
用户下完单后,系统会为其锁定库存一段时间;超过锁定时间后自动释放锁定的库存,让其他用户抢购。用户付款时会校验是否在有效期内,如果在则可以进行支付,若过期则会重新锁定,若库存不足,则返回提醒。
由于在秒杀中使用 “下单后扣减库存” 这种方式更为合适,利用数据库的事务特性,可以保证订单和库存扣减数量的一致性
采用更新 “结果值” 的操作而并非直接更新 “扣减” 操作。“扣减” 不是幂等性的,如果接口设计不够完整,没考虑到“幂等性”就会由于网络原因或者其他原因造成重试后,会出现重复“扣减”,即“超卖”甚至库存为负值情况出现。
利用好缓存(Redis)
异步处理