微服务架构概念
当前微服务很热,大家都号称在使用微服务架构,但究竟什么是微服务架构?微服务架构是不是发展趋势?对于这些问题,我们都缺乏清楚的认识,本文基于作者在大型互联网系统的服务化实践和思考,和大家一起探讨微服务架构。
本文主要内容包括:
- 传统SOA架构
- 新型SOA架构
- 服务设计方式
- 深入微服务
- 微服务体系
- 微服务系统架构
传统SOA架构
说到微服务,离不开SOA,两者经常放一起讨论,首先我们要了解SOA架构。
国外信息化起步较早,很多大公司先后建设了很多系统,比如从开始的ERP,到OA系统,到CRM系统等。由于这些系统往往由不同的供应商提供,采用不同的技术,实施的时候也没预先考虑到和现有系统集成,因此系统集成非常困难。
在2000年初的时候,两个概念非常流行,一个是EAI(Enterprise application integration),即企业应用集成;还有一个是EII(Enterprise application integration),即企业信息集成。一个从应用的角度,一个从数据的角度,本质是一回事,都是怎么把孤立的系统集成在一起。
SOA架构源自于企业内部异构系统的集成,具体做法是各个系统对外提供粗粒度的服务,外部系统可以通过相对标准的技术访问,大致结构如下图所示:
每个遗留系统提供服务,该服务作为系统的前置代理,对外提供访问。所有这些服务部署在一个中心化的平台,称之为企业服务总线ESB(Enterprise Service Bus),ESB提供复杂处理,包括:
1. 外部访问
为满足不同客户端访问需求,提供各种各样的访问协议,如WebService、HTTP、FTP、Email等,其中WebService是最典型的通讯协议。
2. 内部处理
请求进来后,需要一系列复杂处理,如对通讯协议的解析,数据的序列化和反序列化,业务流程的编排和服务路由等。
2008年的时候,eBay基于Axis,开发了自己的SOA框架,各个系统通过创建服务,对外提供功能。如后台搜索系统,本身是C++开发,通过对外提供Java服务,最终以WebService的方式,方便其他系统(大多是Java)调用搜索的功能。经过1年多的时间,整个SOA平台已经有上百个服务,很大程度上方便了系统相互集成。
但我们可以看到,ESB是一个很重的机制。首先通讯方式复杂,前后端涉及多种协议,由于每次调用代价很高,服务一般提供粗粒度的接口,一次性尽量完成更多处理。
ESB的中心化带来了单点故障隐患,服务统一在ESB上进行部署,也限制了服务的水平扩展;此外ESB还包含很多业务相关的功能,如业务流程编排等,限制了业务扩展的灵活性。
无论对于服务的提供者还是使用者,通过ESB这种方式集成,开发代价大,通信效率低,因此这种传统很重的SOA架构并没有得到大规模应用。
2008年的时候,eBay基于Axis,开发了自己的SOA框架,各个系统通过创建服务,对外提供功能。如后台搜索系统,本身是C++开发,通过对外提供Java服务,最终以WebService的方式,方便其他系统(大多是Java)调用搜索的功能。经过1年多的时间,整个SOA平台已经有上百个服务,很大程度上方便了系统相互集成。
但我们可以看到,ESB是一个很重的机制。首先通讯方式复杂,前后端涉及多种协议,由于每次调用代价很高,服务一般提供粗粒度的接口,一次性尽量完成更多处理。
ESB的中心化带来了单点故障隐患,服务统一在ESB上进行部署,也限制了服务的水平扩展;此外ESB还包含很多业务相关的功能,如业务流程编排等,限制了业务扩展的灵活性。
无论对于服务的提供者还是使用者,通过ESB这种方式集成,开发代价大,通信效率低,因此这种传统很重的SOA架构并没有得到大规模应用。
新型SOA架构
这里应用直接调用服务,无需经过复杂的中心节点,使用轻量级的协议,一般是HTTP,数据格式也很简单,比如JSON,由服务提供者直接解析协议和数据格式。同时每个服务本身包含核心的业务封装,提供给多个应用场景。
此外每个服务独立部署,提供更好的灵活性,包括业务功能扩展和处理容量水平扩展。
我们可以看到,新型SOA和传统基于ESB的SOA相反,这里是强化服务终端能力,弱化通道连接。
服务如何设计
随着互联网业务越来越复杂,新型的SOA架构不断深入发展,出现了多种服务设计模式。
面向业务系统服务设计
面向业务系统SOA把原单体应用里的业务逻辑层剥离出来,作为单独的服务对外提供。
举一个电商的例子,这里有两个应用,顾客使用的商品详情页,展示商品的信息、商品库存,商品价格;下单页供顾客下单,涉及商品查询、库存扣减、生成订单等。
页面应用和服务关系如下图所示:
商品详情服务主要面向商品详情页提供数据接口,包括商品基本信息、价格信息、库存信息,接口经常根据页面需要,聚合这几部分信息,提供粗粒度服务,服务底层自由访问所需要的表。
订单服务主要面向下单页,其中商品信息可以通过商品详情服务获取,无需单独访问库表。而对于库存,这里是扣库存场景,需要自己访问库存表,订单信息也是如此。
面向业务系统的服务设计是比较直接的,每个服务针对自己的“主应用”提供粗粒度服务,总体上看应用/服务/库表是多对多的关系,如果服务设计得不好,容易导致整体网状依赖,修改时,往往牵一发动全身。此外对于新业务,需要单独构建对应的服务,不利于业务创新。面向细分主题服务
面向特定主题/概念/要素构建细分服务,最终服务于该主题相关的所有业务场景,比如围绕用户构建用户服务,对外供所有需要用户信息的业务系统访问,内部只访问用户相关的几张表,结构如下图所示:
面向基础系统服务
面向基础系统服务屏蔽底层硬件的访问细节,以更友好更透明地方式对外提供访问,如短信服务、储存服务、缓存服务等。我们一直讲软件即服务,现在更进一步,硬件也是服务。
通常面向基础系统服务通过底层系统的集群或多路由,提供更可靠,更强处理能力的服务。
深入微服务
微服务概念是Martin Fowler在2014年抛出,文中给出微服务的一系列特征,但并没有给出准确定义。大家分别有自己的理解,还没有共识,基于本人的服务化实践,我觉得微服务有两大思想。
- 简单连接
通过传统SOA方式连接客户端和服务端,是非常痛苦的,涉及传统很重的通讯协议(DCOM/RMI/CORBA/WebService等)和复杂的数据格式(二进制/XML等)。在连接通道方面,微服务很轻,一般采用轻量级的通讯协议(如HTTP)和简单数据格式(如JSON)。
微服务无需中心节点提供复杂处理,特别是业务相关的处理,把业务的职责还给服务端,更灵活地响应业务变化。微服务构建好后,应该象水电煤一样到处可用,没有技术障碍,不同语言都可以互相调用。 分散管理
分而治之是处理复杂问题的有效手段,微服务对系统拆分尤为彻底,在多个方面实现对系统的分散管理:- 分散业务
微服务聚焦细分业务领域,是对应业务规则的唯一入口,它把整体业务分割成一个个高内聚的小业务,简化业务之间依赖关系。 - 分散数据
微服务独占式访问对应的数据,服务和数据是一体的。它把整体数据分割成一块块数据,数据块内部的表紧密相关,块间数据相关性弱。在实施层面,每部分数据独立schema,逻辑上分离,或者使用独立数据库,物理上隔离。 - 分散物理资源
借助虚拟机和容器技术,一台物理机可以切分为多套环境,非常适合微服务部署,对服务器资源更高效地利用,同时有些微服务面向基础硬件封装,提升了对物理资源的管理。
我们可以看到,传统的基于ESB的服务不属于微服务范畴,它既不体现简单连接,也不体现分散管理(ESB甚至通过流程编排对业务集中管理)。相对于传统重的SOA服务,新型SOA,无论是面向业务系统服务,面向细分主题服务,面向基础系统服务都符合简单连接的特性,因此都可以算微服务的范畴。
特别地,面向细分主题服务很好体现业务和数据的分散管理,面向基础系统服务很好体现物理资源的分散管理,因此这两者更好地满足微服务思想,是更纯粹的微服务。
这里是一个电商库存微服务的实例,希望帮助大家深入了解微服务,大型B2C电商的库存概念比较复杂,包括:
- 分散业务
物理库存(仓库里的实际库存)
- 虚拟库存(仓库里没有,但可以假装有,先拿出来卖,比如新版iPhone预售)
- 活动库存(总库存里拿出一部分做活动,提供优惠价格促销)
- 共享库存(北京的库存可以共享出来,放到上海卖)
- 冻结库存(库存暂时被冻结部分,比如已下单但未发货,此时前台不可卖)
对于前台来说,用户可看到的库存计算规则如下:
可售库存=本地库存(实际-冻结)+虚拟库存(虚拟-冻结)+兄弟仓库共享库存(共享-冻结)
对于具体活动场景来说,可售库存的规则不一样,它等于活动库存。
商品库存是电商的核心数据,有数十个业务系统调用,大促时每天调用数十亿次,往往在数百台虚拟机/容器上部署,提供水平扩展,具体架构如下:
库存微服务化设计有很多好处:
- 统一业务规则
库存的计算规则很复杂,不同业务场景看到的库存数量都不一样,库存微服务通过提供唯一的库存访问入口,统一对库存相关规则进行封装,方便各个业务场景使用,如果库存规则有变化,变化也局限于库存微服务内部,外部业务代码保持不变。 - 一致数据模型
库存微服务只访问库存相关的四张表,它不访问外部库表,也不允许外部应用直接访问这几张表,收敛了对这些表的访问入口,避免各个业务直接往表里加字段,导致数据模型混乱。
此外,这些表独立成库,再加上只有库存服务访问,数据库连接数可以大大减少,避免数据库连接数不够。
各种内部优化 各种内部优化
库存微服务汇总所有读写接口,内部可以做各种优化。比如缓存,由于所有写场景都在这里,可以通过写后马上更新方式,保证缓存的实时一致性。所有读场景也在这里,可以通过合理设计,一个缓存满足多个读场景需求,提升缓存使用效率。
库存的变化是非常重要的系统状态变化,库存微服务在各个库存变化点,提供库存变化消息通知,以统一的消息命名方式和消息格式,保证相关方能够方便地接收库存消息。水平扩展
库存服务每天访问量很大,通过微服务方式可以很方便地水平扩展,服务本身是部署在标准的虚拟机或容器内,通过云的方式可以动态收缩和扩容,1号店在大促的时候,就经常以租用公有云服务器的方式实现服务能力扩展。大家可以看到,微服务很适用业务高度复杂、业务共享性高、并发量大的场景,在电商,类似的场景还有订单/商品/用户/价格/支付等等,我们可以围绕这些细分概念构造微服务。
微服务体系
随着服务的不断构建,一个完整的微服务体系如下图所示:
最底下是基础系统的服务,这些服务实现对底层系统功能的封装,供之上各个业务使用,如短信/消息/存储等服务,上层服务无需关注底层资源的物理位置和内部细节。
之上的共享服务基于细分主题,封装企业各个维度的核心数据资源和业务规则,偏下层产品/用户/订单等都是主数据,共享性更强,偏上层的积分/抵用券/发票等,为某几个业务系统所使用,规则相对也更简单。
系统服务为企业整体系统提供基础技术平台,共享服务提供基础业务平台,两者一起奠定企业信息系统的基础。最上面的业务服务基于两大基础平台,面向具体的业务系统提供服务。
在这里,服务形成了明确的分层,调用规则如下:
上层可以调用下层,比如共享服务调用系统服务,也可以跨层调用,比如业务服务直接调用系统服务。
同层方面,业务服务可以互相调用,组成更粗粒度服务,共享服务和系统服务都是细分服务,相互之间垂直正交,不允许相互调用。
通过服务细分和服务分层,微服务的职责定位明确,依赖关系清晰,总体上,整个系统变成层次化的依赖,而不是网状依赖。
微服务系统架构
下图是一个大型B2C电商系统实际的架构,上层是各种业务应用,底层是大量服务,并且服务分为应用服务(面向业务)和基础服务(面向共享主题),一个非常典型的微服务架构。
当前随着网络通信技术的完善和云计算的流行,包括容器化部署,客观上,很好地解决微服务技术上的问题;主观上,互联网系统体量大、业务复杂,通过微服务的方式对系统进行深入拆分是很自然的选择。
微服务通过简单连接简化技术实现,通过分散管理简化业务依赖,很好地平衡了技术复杂性和业务复杂性,在大型互联网公司已经遍地开花。
作者介绍
王庆友,前1号店首席架构师,先后就职于eBay、腾讯、1号店等公司,精通电商业务,擅长复杂系统业务建模和架构分析,同时在构建大规模的分布式系统方 面有丰富实践,尤其在大型系统的SOA改造方面有很深入的理论和实践。