出口电商+跨境物流技术挑战:MongoDB应用实例




内容来源:2017年4月22日,贝法易集团技术部总监黄亮在“2017年MongoDB中文社区深圳用户组大会”进行《MongoDB在跨境电商物流供应链系统中的实践》演讲分享。IT 大咖说做为独家视频合做方,经主办方和讲者审阅受权发布。数据库

阅读字数:2896 | 4分钟阅读express

嘉宾演讲视频地址: suo.im/5pkBJh

摘要

本次介绍下出口易跨境电商物流供应链系统从单体应用过渡到面向服务的分布式系统架构的过程当中,遇到的一些挑战和实现。其中包括了基于MongoDB建模和数据持久化方面上具体实践。后端

关于出口易物流

出口易物流是广州市贝法易商贸有限公司(简称贝法易)旗下,以全球仓储为核心,整合全球物流网络系统,为跨境电商卖家提供海外仓储、国际专线、国际小包、国际快递、FBA头程等物流服务以及本地化售前售后服务,解决订单管理、金融融资难题。咱们不是物流的供应商,咱们是跨境电商全程物流解决方案提供商。数组

咱们公司的重资产是人员,咱们了解跨境电商物流,包括跨境电商通关的环节、关于物流方面的国际法律以及离境品的相关信息,这些都是咱们公司最宝贵的资源。网络

咱们公司底下有一大群长期合做的供应商,这是咱们最大的优点。咱们的难点也是在于这些供应商是不可控的,由于咱们是在使用别人家的服务。架构

因此除了订单系统还有一个很重要的资产就是咱们自营的海外仓储,这也是咱们最核心的价值。并发

覆盖欧美澳主要市场的服务网络

上图是咱们全球布局的物流网络。这些仓储有大有小,英国仓库是咱们最核心的仓库。截至2017年,在国内咱们一共有八个仓储中心,重点的是在深圳、广州和上海。框架

全球主流电商平台重点推荐物流服务提供商

咱们合做的平台推荐咱们的物流服务提供商有Amazon、ebay、wish、阿里国际、shopee、AliExpress还有LAZADA。分布式

出口易新老架构演变过程

咱们以前的系统是上图左边的架构,针对商家第三方的ERP和一些商家本身研发的一套系统,还有一些平台跟咱们的系统都是有直接交互。有的是经过出口易提供了一套UI来进行访问,还有就是大量的线上发货,咱们会采用API来进行接入。咱们后台有admin管理后台,还有单独的一块WMS系统。高并发

咱们认为这个系统有些过于庞大,想作一些调整。新的架构大部分仍是没有改动,只是在后端针对admin的系统想要往面向服务架构方向落地。基于业务场景的切分有两块,一块是基于通用服务,好比说用户的认证和受权,还有就是日志。

支付有一些支付网关,有和paypal、alipay、payoneer还有银行的接口。

下面是咱们业务最主要模块,包括产品报价、客户关系管理系统,还有订单、物流网络和运输,包括WMS、支付、物流轨迹跟踪、供应商管理系统,还有结算报表等等诸如此类。

出口易老业务系统特色

单体应用:先后端系统共用一套WEB App Solution。

单一数据库:采用MS SQLServer 数据库,核心业务功能共用一个数据库。

业务功能完整:IT系统随业务的发展不断扩展新功能。知足开展跨境电商物流业务最基本的功能性需求。

容易测试和部署:单独一个Solution,系统依赖少,一旦部署,所有功能便可测试。

出口易老业务系统不足

不够灵活:对应用程序作任何细微的修改都须要将整个应用程序从新构建、从新部署。

妨碍持续交付:系统规模大,构建和部署时间也相应地比较长,不利于频繁部署,阻碍持续交付。

受技术栈限制:包括开发语言,开发工具,数据库一旦选定,没法根据实际须要做其余选择。

技术负债:系统逻辑异常复杂,随着时间推移,人员更迭,技术负债不断累积。

出口易新业务系统特色

面向服务:根据业务模块切分不一样的系统模块,系统模块采用面向服务架构。服务与服务经过明确的接口定义进行通信。

领域驱动设计:每一个业务模块团队负责一个领域或业务功能相关的所有开发。核心领域根据DDD中明肯定义的规则实现。

独立部署、升级、扩展和替换:每一个服务能够单独部署,透明升级,不影响整个系统。

异构/采用多种语言:每一个服务开发团队,能够选择本身熟悉开发语言,数据库,开发工具和开发架构。

新架构落地的切入点

身份认证:每一个服务都须要统一的登陆认证。

鉴权:不一样的用户使用相同的服务模块都须要鉴权。

由单点登陆的页面包括基于OAuth2 API这样的方式来接入。内部采用的是DDD这样的一个逻辑架构,包括应用层、领域层。领域层里面又包括了领域模型、实体子对象、领域服务、领域事件和查询的规格。

基于仓储,要存一个订单,必须链接实体和子对象一块儿存储刷新到数据库。

咱们作应用的时候更偏向于完成业务,因此选用了mangoDB。咱们有一套本身的架构,在封装的过程当中就会把mangoDB作一层封装。

上图中面向切面的架构包括了exertion、loading和cache等切面。

上图是TMS系统调拨单聚合根示意图,它包括了物流轨迹的集合、预计到货时间等信息,还有这些调拨单历经的节点信息。

为何选择MongoDB?

一、非事务紧密型。错误数据容忍性相对比较高。

二、团队成员有使用MongoDB开发经验。对基于MongoDB方面的建模须要考虑的必要冗余有必定的了解。

三、Portal 模块数据库读大于写,基于MongoDB读写方面的高性能,解决了高并发下系统卡顿问题。

四、TMS 系统模型之间关系复杂,采用传统关系数据库,势必增长一堆表。采用MongoDB,能够把复杂的模型,经过一个Doucment存储到一块儿。

基于MongoDB开发须要注意的问题

集合之间不能Join,建模方面要特别注意。建议增长必要的冗余,减小二次查询。

仅仅支持单个Document级别事务。数据一致性错误时,要考虑增长必要数据监控和数据修复功能。

聚合查询,须要经过MongoDB 聚合管道方式查询,MongoDB C# 驱动提供了良好支持,可是相对Linq查询仍是比较繁琐。

基于MongoDB的持久化实现

1、仓储Repository

仓储限定在对整个聚合根的操做上,提供聚合根的持久化和重建或查询。

2、仓储上下文Repository Context

负责事务处理。每一个聚合根的仓储都会关联到同一个仓库上下文。可是MongoDB 不支持事务,咱们提供了虚拟实现。仓储上下文应用了工做单元模式。

一些关注点

1、领域模型采用POCO(POJO)

简单的CLR对象(简单的Java对象),不继承任何持久化框架中的基类,或实现任何持久化框架中的接口。领域层不引用MongoDB类库。MongoDB仓库层使用lambda expression 实现类的Map。

2、ID 生成器

有多种ID生成器可供选择。GuidGenerator,OjbectIdGenerator,String OjbectIdGenerator,etc。咱们ID一概使用String类型。因此直接使用MongoDB的StringObjectIdGenerator。

3、多态类的Map

若是把多态类(继承)映射到MongoDB,须要指定已知类型。

4、一些须要了解的约定

NamedIdMemberConvention能够指定类的哪些属性能够做为ID。

IgnoreExtraElementsConvention能够忽略Document中不存在于类中的字段,不然会抛出异常。

EnumRepresentationConvention能够指定枚举序列化的方式,咱们都指定为BsonType.String。

MongoDB聚合框架(C#)

1、聚合框架

MongoDB2.2版本引入了此功能,是数据聚合的一个新框架。

这个框架一是对文档进行“过滤”,也就是筛选出符合条件的文档;二是对文档进行“变换”,也就是改变文档的输出形式。其余的也包括按照某个指定字段分组和排序等。

它实际上是MapReduce的替代方案,但比MapReduce简单。

该框架使用声明性管道符号来支持相似SQL 中的Group by 操做的功能。不须要本身编写自定义的JavaScript。

2、管道操做符

$project:数据投影,主要用于重命名、增长和删除字段。

$match:过滤操做,筛选符合条件文档,做为下一阶段的输入。

$limit:限制通过管道的文档数量。

$skip:从待操做集合开始的位置跳过文档的数目。

$unwind:将数组元素拆分为独立字段。

$group:对数据进行分组。

$sort:对文档按照指定字段排序。

$geoNear:会返回一些坐标值,这些值以按照距离指定点距离由近到远进行排序。这个在地理信息系统中比较经常使用。

总结

对于大多数的聚合操做,聚合管道能够提供很好的性能和一致的接口。

使用起来比较简单,和MapReduce同样,它也能够做用于分片集合。

输出的结果只能保留在一个文档中,要遵照BSON Document大小限制(当前是16M)。

管道对数据的类型和结果的大小会有一些限制,对于一些简单的固定的。

汇集操做可使用管道,可是对于一些复杂的、大量数据集的聚合任务仍是使用MapReduce。

今天的分享就到这里,谢谢你们!

相关文章
相关标签/搜索