京东商城交易系统的演进( 三 )


京东商城交易系统的演进

文章插图
 
关于订单中心的异步异构,订单中心原来都是从订单表直接调出的 。随着体量增大,系统无法承载访问,我们异构出订单中心的存储,支付台帐存储等 。异构出来数据都具有业务针对性存储 。数据体量会变小,这样对整体的优化提升提供很好的基础 。
这样的存储隔离,对订单状态更新压力也会减小,对支付的台帐、对外部展示的性能也会提升 。大家会疑问,这些数据可能会写丢 。我们从第一项提交开始,直接异步写到订单中心存储,到后面订单状态机会补全 。如果拆分不出来,后面就生产不了 。也就是说,到不了订单中心,数据生产不了,一些异步没成功的数据就会在这个环节补全 。
京东商城交易系统的演进

文章插图
 
然后是商品的异步异构 。2013年,商品团队面临的访问量,已经是几十亿 。如何去应对这个情况呢?很多商品数据贯穿了整个交易,包括交易的分析、各个订单的系统都会调商品系统 。我们会针对系统优化 。比如,针对促销系统调用,促销系统主要调用特殊属性,我们把这些属性存到促销系统的特有存储 。库存系统也类推 。调用的特殊属性的方法也不一样 。譬如大家电的长宽高这些特有属性,不像前端商品页里只是基本属性 。这样就把所有的属性异构处理,针对商品纬度、商品ID等所有数据会异构一份到库存、促销、单品页,后面进行改造的时候,又将数据分A包、B包、C包 。京东的业务很复杂,有自营,又有平台数据,A包可能是基础数据,B包可能是扩展数据,C包可能是更加偏的扩展数据 。这样,促销系统可能调用的是B包的扩展属性,也有可能调用的是A包的基础属性 。单品页访问A包、B包,调的集群是不一样的 。这样存储的容量就可以提高两倍,系统的容灾承载力也会提高 。
商品原来是一个单表,后来慢慢发展成为了一个全量的商品系统,包括前端、后端整个一套的流程 。异步异构完了之后,系统可进行各方面的优化,这样系统的容量也会慢慢接近预期值 。然后找到系统容量的最大值,如果超过这个值,整个系统就会宕机 。那么,我们会做分流和限流,来保证系统的可用性 。否则,这种大流量系统一旦倒下去,需要很长的时间才能恢复正常,会带来很大的损失 。
分流限流
在618、双11时候,手机、笔记本会有很大力度的促销,很多人都会去抢去刷 。有很多商贩利用系统去刷,系统流量就不像用户一秒钟点三四次,而是一分钟可以刷到一两百万 。怎样预防这部分流量?我们会优先限掉系统刷的流量 。
Nginx层: 通过用户IP、Pin,等一下随机的key进行防刷 。Web 层: 第一层,Java应用实列中单个实列每分钟,每秒只能访问多少次;第二层,业务规则防刷,每秒单用户只能提交多少次,促销规则令牌防刷 。
从Nginx,到Web层、业务逻辑层、数据逻辑层,就会分流限流,真正落到实际上的流量是很小的,这样就会起到保护作用,不会让后端的存储出现崩溃 。从前面开始,可能访问价格或者购物车的时间是10毫秒,保证20台的机器一分钟的流量是一百万、两百万 。如果是40台机器的话,承载能力会很强,会透过Java的服务,压倒存储,这样会引发更大的问题,庞大存储一旦出现问题很难一下恢复 。如果从前面开始一层一层往下限,就可以起到保护底层的作用 。中间层出问题比较容易处理,如Web层,限流会消耗很多CPU,会一步步加入更多机器,这样就能够解决这个问题 。
我们需要降级分流限流 。
京东商城交易系统的演进

文章插图
 
下面结合秒杀系统来讲讲如何限流分流 。2014年才产生秒杀系统 。当时,在同一时刻可能有1500万人预约抢一件商品,抢到系统不能访问 。后端服务都没有出现这些问题,有的服务费不能正常展现 。后来就专为抢购设计了一个秒杀系统 。正常情况下,有大批量用户需要在同一时间访问系统,那么就从系统结构上分出去这些流量 。秒杀系统尽量不影响主流层的入口,这样就分离出来一部分数据 。
京东商城交易系统的演进

文章插图
 
接下来讲讲促销和价格 。主力调用价格的服务主要在促销引擎,限流主要是通过购物车服务,购物车到促销引擎又会限流,促销引擎里面会有令牌 。比如,有5000个库存,发50万个令牌到前端去,肯定这5000个库存会被抢完,不可能再把其他服务的量打到后面,这样会保护促销引擎,这是一种总令牌模式的保护 。后面的分流性能,会分集群式、重要程度去做 。另外,一些广告的价格服务,我们会优先降级,如果出问题的话会限制 。另外,有一部分刷引擎刷价格服务的数据,正常情况下是保证它正常使用,但是一旦出现问题,我们会直接把它降级,这样就保护了真实用户的最好体验,而不是直接清除程序的应用 。


推荐阅读