## 电商物流系统技术架构进化史
文/者文明
1998年3月,中国第一笔互联网网上交易成功,标志着中国正式从电子数据交换时代步入互联网电子商务时代,从2003年开始进入迅速发展阶段,到今天,中国电子商务格局已经形成。笔者在传统企业应用和电商互联网公司摸爬滚打了15年,亲历过传统企业应用向互联网转型,以及电商物流系统的架构演进过程。本文是笔者根据多年经验整理的一个小结。
电商物流系统主要包括仓储、预分拣、分拣、配送、干线运输、售后、客服等业务系统。电商物流系统的架构是随着技术的进步一步步进化过来的,最初也和传统企业应用一样,经历过 C/S 和 B/S 时代,后来由于业务规模的快速增长,电商物流系统走出了一条不同于企业应用的进化之路,也就是+互联网时代和 DB+ 时代,本文将重点对京东物流系统的进化过程进行简要阐述。
### C/S 时代
C/S 是一种历史悠久而且技术非常成熟的架构,在电子商务发展的初始阶段(2000年左右),和企业应用一样,由于业务规模很小(每天几百单),加上物流中心(库房、分拣中心、配送中心)的数量也很少,全国就几个甚至一个物流中心,这样系统的部署和运维成本很低。在这样的背景下,自然也就选择了当初最稳定的 C/S 架构,如图1所示。
图1 C/S 架构
C/S 架构的最大优点是能够充分发挥客户端 PC 机的处理能力,很多业务逻辑都可以放在客户端处理,不需要远程通信就可以直接响应,这样客户端的响应速度就比较快。不过 C/S 架构的缺点也是十分明显的,简单概括起来有如下几点:
1. 客户端属于胖客户端,每个客户端都需要安装客户端软件,导致开发、上线部署、以及维护和升级成本非常高;
2. 不支持跨平台,甚至连同平台不同版本之间都不能兼容;
3. 硬件资源成本高,因为客户端需要安装软件,对所有客户端服务器的配置就有一定要求,这样就带来了高昂的硬件成本。
在 C/S 时代,京东的物流系统和企业应用一样,业务规模和在线用户的量级都很小,所以 C/S 架构足以支撑正常的业务。
### B/S 时代
随着互联网和电子商务的飞速发展,京东的订单量也呈现出每年数十倍的增长速度,京东物流中心的规模和数量也随之快速增长,很多跨物流中心的业务模式(比如内配调拨、跨分拣中心分拣等)也不断出现,在这种背景下,局域网已经满足不了业务需求,这就要求系统必须具备远程访问的功能以及可扩展性。同时随着 Internet 和 WWW 技术的发展,B/S 架构也就应运而生。B/S 架构是 C/S 架构的一种改进,相当于三层 C/S 架构(浏览器/Web 服务器/数据库服务器),主要利用了 WWW 浏览器技术,采用 HTTP 协议,用浏览器实现了原来需要客户端软件才能实现的强大功能。B/S 架构如图2所示。
图2 B/S 架构
在 B/S 架构中,客户端为瘦客户端,业务逻辑集中在 Web 服务端,系统的开发上线以及升级维护成本比 C/S 架构要低的多,而且客户端的服务器成本也大大降低,最主要的是用户可以远程访问系统,有力支持了跨物流中心的业务模式。在 B/S 架构时代,京东的物流系统大多采用 IIS 作为 WebService,数据库采用 SQLServer,基本用的都是微软系产品。
### +互联网时代
随着京东业务规模的不断扩大,物流系统的业务量级也由原来的日均几万单发展到几百万单,这样的业务规模已经远远超出企业应用的规模,毕竟企业应用的用户是企业内部员工,京东的客户是面向全国乃至全球的普通消费者,二者在数量级上是存在巨大差异的。在这样的规模下,京东物流系统如果还停留在传统的 B/S 或者说企业应用的技术思路上,肯定是无法满足性能和吞吐量需求的。在业务规模的驱动下,系统必须引入更多的互联网技术,比如分布式缓存,消息中间件、分布式文件系统、流式计算、海量存储技术等。
对于强依赖数据库的 OLTP 类系统,分布式缓存是一种非常好的提升系统容量的技术,京东的物流系统基本都是业务密集型的 OLTP 系统,强依赖关系型数据库,但关系型数据库的 TPS 毕竟是非常有限的,这样在数据库之上,就有必要将一些相对静态的数据进行一级或多级缓存,将大部分并发分摊到缓存中,只有极少部分请求才会穿透到数据库,这样系统的并发性能和吞吐量就会大大提升。在物流系统中,基础资料类系统,比如仓储系统的基础资料系统,配送系统的基础资料系统等等就特别适合使用缓存,因为基础资料数据是相对静态的数据,读多写少,数据变更的频率非常低,大多数据是几周或者几个月才会变更一次,这样缓存命中率就会非常高。同时基础资料类系统主要提供大量的读服务,相对更偏底层,读并发会非常大,所以必须通过缓存才能满足其高并发的需求。
消息中间件主要用在两种场景,一个是用来处理同步异步化,可以将系统之间同步调用服务处理为异步消息,将强依赖变为弱依赖,在解耦的同时还能提升系统的可用性和吞吐能力;另一个是用来进行削峰,可以将峰值流量缓存到消息队列中,然后再慢慢去消费消息,有效的提升了系统的并发性能。仓储系统的订单接收模块,就是采用了同步异步化技术,将订单信息发送到消息队列中,然后由订单路由模块通过异步的方式下传给仓储系统生产,如果不引入消息队列,直接通过同步调用服务的方式将订单直接下传给仓储系统,这样接单的并发性能就会受制于仓储系统。
分布式文件系统用来存储图片,大文件等,比如电子面单图片,订单报文,商品资料报文等等,在仓储订单路由系统中,订单和商品资料报文最初是存储在 MySQL 中,后来就改成分布式文件系统。在仓储面单系统中,也是将电子面单存储到分布式文件系统中。流式计算主要用于处理实时/准实时的统计类监控报表需求。比如分拣发货量、站点验货量、妥投量统计,仓储出库量统计等等。海量存储技术(比如 HBase)用于存储数据结构比较简单的数据或者是生产系统中的历史数据。
在京东物流系统中,引入的互联网技术还有很多,这里就不再一一赘述。图3简单的展示了这一阶段的系统结构。
图3 +互联网时代
在这个时代,我们的系统从 .Net 平台迁移到了 Java 平台,Java 平台相较 .Net 平台具备很多优势,比如更加开放、开源资源更丰富等,只有这样才能引入更多互联网技术。同时数据库也由 SQLServer 迁移到了 MySQL,MySQL 比 SQLServer 更加灵活,最重要的是开源免费,可以大大降低成本。
### DB+ 时代
在+互联网时代,我们的系统引入了很多互联网技术,系统的容量也得到了明显的提升。但是业务规模的扩张速度总是快于我们系统的迭代速度,业务规模总是在驱动着系统的升级迭代。这个阶段业务量级已经达到日均千万甚至亿级,单纯的引入一些互联网技术无法让系统容量发生质的变化。上面提到,我们的系统强依赖关系型数据库,对于数据库的读,我们通过扩展读库即可实现分布式,但是对于数据库写,在+互联网时代还没真正做到分布式,这就是一个很大的问题。所以在这个阶段,我把它总结为 DB+ 时代,也就是 DB+NoSQL+ 分布式,主要包括如下几个方面的改进:
引入 KV 引擎,将一些数据从关系型数据库(MySQL)迁移到 KV 引擎中来存储和处理,这样不仅可以大大降低关系型数据库(MySQL)的负担,还能提升数据的读写性能。京东的物流系统中,引入的 KV 引擎主要包括
Redis、HBase、Elasticsearch 和 Cassandra,Redis 用于缓存那些相对静态的热点数据,HBase 是存储,主要存储海量的业务数据和历史数据,Elasticsearch 主要存储查询条件相对复杂的数据,Cassandra 主要存储一些日志、流水类数据,将一些查询条件相对复杂的数据写入 Elasticsearch 等。
引入数据库分库分表中间件,实现数据库写的分布式,做到数据库的读写都可以随时扩展,真正实现从 Scale up 到 Scale out 的转变。京东物流系统的 sharding 中间件是自主研发的,支持分库分表,动态 Scale out 以及读写分离,历史数据结转等。
追求 BASE 模型,容忍分区失败,弱化事务,大事务化小事务,甚至是无事务,舍强一致性取最终一致性。
图4能简单说明 DB+ 的基本思路,系统的存储分两部分,一部分是传统的关系型数据库(MySQL),用来存储结构化,强事务数据,数据库做了 Sharding,读写均为分布式,支持弹性扩展。另一个是 KV 引擎,KV 引擎主要包括 Redis、HBase、ElasticSearch 和 Cassandra,Redis 主要用来做热点缓存,HBase用来存储数据量级大而且 rowkey 又比较固定的数据,ElasticSearch 用来存储查询条件比较复杂的报表、查询类数据,Cassandra 主要用来存储日志、流水类数据,这类数据量级大,读写性能要求也比较高,但是大多只需要单记录查询。
图4 DB+ 时代
### 总结
京东物流系统的技术架构是随着公司业务的发展,业务模式和规模的不断扩张一步步演进过来,主要经历了 C/S,B/S,+互联网,DB+ 4个阶段。这4个阶段是笔者根据自己多年的经验总结出来的,并不能代表所有电商物流系统的架构演进过程,只是希望读者能对电商物流系统的架构演进过程有一个初步的了解和认识,同时也为电商物流系统的研发和设计人员提供一个参考和借鉴,在技术选型和架构方向上尽量少走一些弯路,进而设计出真正高并发、高吞吐量的物流系统。
每一次演进都是规模驱动的结果,现阶段还处于电商高速发展的黄金时期,业务规模还会持续保持快速增长,京东的物流系统还将继续演进,后面可能会进入 NoSQL 时代,也有可能会进入 NewSQL 时代,目前还不好说。