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


京东商城交易系统的演进

文章插图
 
压测完之后得到容量,得到交易系统的购物车、结算页大概承受值,之后会进行一轮优化,包括对NoSQL缓存的优化 。京东在2012年的时候自建CDN网络,Nginx层做了很多模块加Nginx+lua的改造 。应用程序层也会做很多缓存,把数据存在JAVA虚拟器里面 。数据层的缓存,主要有redis、 NoSQL的使用,另外会剥离出一些独立的数据存储 。
缓存 压缩
京东商城交易系统的演进

文章插图
 
CDN域名切换的问题,原来外部CDN切换IP,需要15-20分钟,整个CDN才能生效 。我们的运维做了很多的改进,自建了CDN,内网VIP等等进行缓存压缩 。Nginx本身就有介质层的缓存和GZIP压缩功能,把静态js、css文件在Nginx层直接拦掉返回,这样就节省了后面服务的服务器资源 。GZIP压缩能压缩传输的文件以及数据,节省了网络资源的开销(GZIP压缩主力损耗CPU,机器内部资源的平衡) 。前面就直接压缩返回图片、文件系统等静态资源 。流量到部署集群系统时,只需要处理动态资源的计算,这样就将动态静态分离集中处理这些专向优化 。
真正的计算逻辑,服务自身的组装、如购物车的促销商品、服务用户,基本上所有资源都耗费在此 。比如,连接数都会耗费在跟促销,商品,用户服务之间调用,这是真实的数据服务 。如果不分离,你用DOS攻击直接访问JS,然后传一个大的包,就会完全占用带宽,连接和访问速度就会非常慢 。这也是一种防护措施,在大促中会做很多缓存、压缩这些防护 。
京东商城交易系统的演进

文章插图
 
购物车从2010年就开始Java改造,整体结构的划分主体有,促销引擎、商品、用户 。系统结构在2012年已经成型 。到13年,加入了购物车服务的存储 。原来购物车存储的商品是在浏览器端的Cookie里的,用户更换一台设备,之前加入的商品就会丢失掉 。为了解决这个需求,我们做了购物车服务端存储,只要登录,购物车存储就会从服务端拿取 。然后通过购车服务端存储打通了手机端与PC端等的存储结构,让用户在A设备加入商品,在另外一个设备也能结算,提高用户体验 。
异步 异构
京东商城交易系统的演进

文章插图
 
2013年之后,接入了很多其他业务,如跟腾讯合作,有微信渠道,我们会把存储分为几份,容量就会逐步地放大 。这是异步的存储,手机端会部署一套服务,PC端会部署一套服务,微信端会部署一套服务 。就会隔离开来,互不影响 。
购物车就是这么做的 。购物车整个数据异步写的时候都是全量写的 。上一次操作可能异步没写成功,下一次操作就会传导都写成功了 。不会写丢,但是可能会有一下延时,这些数据还是会同步过来 。比如,从PC端加入商品之后没有立即同步到移动端,再勾选下购物车,购物车的存储又会发生变更,就会直接把全部数据同步到移动端 。这样,我们的数据很少会出现丢失的情况 。
异步写的数据是进行了很多的压缩的 。第一层压缩从前端开始,整个前端是一个接口串,到后面购物车服务,先把它压缩为单个字母的接口串,后面又会压缩成字节码,使字节流真正存储到redis层里面 。当存储压缩得很小的时候,性能也会提高 。
缓存压缩只是为提升纵向性能做的改进 。后面还会进行横向异步异构的改进,购物车把移动端存储剥离出去,移动端的存储在一组redis上,PC端的存储在另外一组上 。PC端和移动端是异步去写,这样相互不影响,虽然它们的数据是同步的 。这是针对多中心用户所做的一些改进 。
外层的异步,是做一些不重要的服务的异步,就从购物车前端看到的地址服务、库存状态服务 。库存状态服务在购物车只是一些展示,它不会影响主流层、用户下单 。真正到用户提交的时候,库存数据才是最准确的 。这样,我们会优先保证下单流程 。
京东商城交易系统的演进

文章插图
 
接下来讲讲接单的异步 。提交订单,提交一次订单原来需要写10多张表 。当订单量提高到一分钟10万的时候,系统就无法承受 。我们就把整个提交订单转成XML,这样只写一张表,后面再去做异步 。接单的第一步,先是把整个订单所有信息存储下来,然后再通过状态机异步写原来的10多张表数据 。


推荐阅读