微服务指南和实施要素
2018年10月24日


一、什么是微服务化和组件化?为什么要做微服务?


1. 什么是微服务

顾名思义,微服务得从两个方面去理解,什么是"微"、什么是"服务",所谓服务,就是IT系统提供的一种能力/功能,它要区别于系统,服务是一个或者一组相对较小且独立的功能单元,是用户可以感知的最小功能集。微-狭义来讲就是规模小,就是指开发单个小型的但有业务功能的服务,每个服务都有自己的处理和轻量通讯机制,可以部署在单个或多个服务器上。微服务也指由多个相对独立的、松耦合的部分组成的面向服务(SOA)的架构思想。也就是说,如果每个服务都相互关联,都要同时修改、更新,那么它们就不是真正的微服务,因为它们紧耦合在一起。

相对于传统的单体架构和面向服务的架构(SOA),它的主要特点是组件化、松耦合、自治、去中心化,体现在以下几个方面:

1)一组小的服务

服务粒度要小,而每个服务是针对一个单一职责的业务能力的封装,专注做好一件事情。

2)独立部署运行和扩展 

每个服务能够独立被部署,并运行在一个进程内。

这种运行和部署方式能够赋予系统灵活的代码组织方式和发布节奏,使得快速交付和应对变化成为可能。

3)独立开发和演化 

技术选型灵活,不受遗留系统技术约束。合适的业务问题选择合适的技术可以独立演化。

服务与服务之间采取与语言无关的API进行集成。相对单体架构,微服务架构是更面向业务创新的一种架构模式。

4)独立团队和自治 

团队对服务的整个生命周期负责,工作在独立的上下文中,自己决策自己治理,而不需要统一的指挥中心。

团队和团队之间通过松散的社区部落、产品部落进行衔接。


我们可以看到整个微服务的思想就如我们现在面对信息爆炸、知识爆炸是一样的,软件也越来越巨大、复杂 ——但是通过解耦我们所做的事情,分而治之,以减少不必要的损耗,使得整个复杂的系统和组织能够快速的应对变化。


2. 微服务由来和特性

让我们的系统尽可能快地去响应变化。其实几十年来我们一直在尝试解决这个问题。如果一定要在前面加个限制的话,那就是低成本的快速响应变化。上世纪90年代Kent Beck提出要拥抱变化,在同期出现了诸多轻量级开发方法(诸如 XP、Scrum);2001年敏捷宣言诞生,之后又出现了精益、看板等新的管理方式。如果说,敏捷开发这些是为了尽快的响应变化,在软件开发流程和实践方面提出的解决方案;那么微服务架构就是在软件技术和架构层面提出的应对之道。

微服务“Microservices”最早于2014年 由Martin Fowler提出,他是软件开发和设计领域的专家,被开发者们尊为“教父”,他也是敏捷开发方法的创始人之一、面向对象编程的开拓者、控制反转/依赖注入的提出者,著有《分析模式》《极限编程》《UML》《重构》等。

原文如下:http://martinfowler.com/articles/microservices.html

文中所说,微服务架构的思考是从与整体应用对比而产生的,尽管“微服务”这种架构风格没有精确的定义,但其具有一些共同的特性,如围绕业务能力组织服务、自动化部署、智能端点、对语言及数据的“去集中化”控制等等。

其中,对应用组件封装的方式是整体架构与微服务架构的主要差异,微服务架构将相关联的业务逻辑及数据放在一起形成独立的边界,其目的是能在不影响其他应用组件(微服务)的情况下更快地交付并推出市场。


根据MartinFowler的分析,微服务架构有以下的一些通用特性,但并非所有微服务架构应用都必须具备所有这些特性:

1) 通过服务实现应用的组件化(Componentizationvia Services):微服务架构中将组件定义为可被独立替换和升级的软件单元,在应用架构设计中通过将整体应用切分成可独立部署及升级的微服务方式进行组件化设计。

2) 围绕业务能力组织服务(Organizedaround Business Capabilities):微服务架构采取以业务能力为出发点组织服务的策略,因此微服务团队的组织结构必须是跨功能的(如:既管应用,也管数据库)、强搭配的DevOps开发运维一体化团队,通常这些团队不会太大(如:亚马逊的“Two pizzateam”- 不超过12人)。

3) 产品而非项目模式(Productsnot Projects):传统的应用模式是一个团队以项目模式开发完整的应用,开发完成后就交付给运维团队负责维护;微服务架构则倡导一个团队应该如开发产品般负责一个“微服务”完整的生命周期,倡导“谁开发,谁运营”的开发运维一体化方法。

4) 智能端点与管道扁平化(Smartendpoints and dumb pipes):微服务架构主张将组件间通讯的相关业务逻辑/智能放在组件端点侧而非放在通讯组件中,通讯机制或组件应该尽量简单及松耦合。RESTful HTTP协议和仅提供消息路由功能的轻量级异步机制是微服务架构中最常用的通讯机制。

5) “去中心化”治理(DecentralizedGovernance):整体式应用往往倾向于采用单一技术平台,微服务架构则鼓励使用合适的工具完成各自的任务,每个微服务可以考虑选用最佳工具完成(如不同的编程语言)。微服务的技术标准倾向于寻找其他开发者已成功验证解决类似问题的技术。

6) “去中心化”数据管理(DecentralizedData Management):微服务架构倡导采用多样性持久化(PolyglotPersistence)的方法,让每个微服务管理其自有数据库,并允许不同微服务采用不同的数据持久化技术。

7) 基础设施自动化(InfrastructureAutomation):云化及自动化部署等技术极大地降低了微服务构建、部署和运维的难度,通过应用持续集成和持续交付等方法有助于达到加速推出市场的目的。

8) 故障处理设计(Designfor failure):微服务架构所带来的一个后果是必须考虑每个服务的失败容错机制。因此,微服务非常重视建立架构及业务相关指标的实时监控和日志机制。

9) 演进式的设计(EvolutionaryDesign):微服务应用更注重快速更新,因此系统的计会随时间不断变化及演进。微服务的设计受业务功能的生命周期等因素影响。如某应用是整体式应用,但逐渐朝微应用架构方向演进,整体式应用仍是核心,但新功能将使用应用所提供的API构建。再如在某微服务应用中,可替代性模块化设计的基本原则,在实施后发现某两个微服务经常必须同时更新,则这很可能意味着应将其合并为一个微服务。



二、为什么要做微服务化、组件化?传统的单体架构、SOA架构有哪些问题?

在传统的IT行业软件大多都是各种独立系统的堆砌,这些系统的问题总结来说就是扩展性差,可靠性不高,维护成本高。到后面引入了SOA服务化,但是由于 SOA 早期均使用了总线模式,这种总线模式是与某种技术栈强绑定的,比如:J2EE。这导致很多企业的遗留系统很难对接,切换时间太长,成本太高,新系统稳定性的收敛也需要一些时间。最终 SOA 看起来很美,但却成为了企业级奢侈品,中小公司都望而生畏。


1 单体架构带来的问题

单体架构所有的模块全都耦合在一块,代码量大,维护困难,而且通常所有的模块都共用一个数据库,并发量大之后很容易成为瓶颈。

单体架构在规模比较小的情况下工作情况良好,但是随着系统规模的扩大,它暴露出来的问题也越来越多,主要有以下几点:

1) 复杂性逐渐变高

比较大型的项目通常有几万、几十万行代码,各个模块之间区别比较模糊,逻辑比较混乱,代码越多复杂性越高,越难解决遇到的问题。

2) 技术债务逐渐上升

公司的人员流动是再正常不过的事情,有的员工在离职之前,疏于代码质量的自我管束,导致留下来很多坑,由于单体项目代码量庞大的惊人,留下的坑很难被发觉,这就给新来的员工带来很大的烦恼,人员流动越大所留下的坑越多,也就是所谓的技术债务越来越多。

3) 部署速度逐渐变慢

单体架构代码量非常庞大,导致部署项目所花费的时间越来越多,有的项目启动就要一二十分钟,要是多启动几次,一天的时间就过去了,留给开发者和运维很大的不便。

4) 阻碍技术创新

比如以前的某个项目使用struts2、jsp写的,由于各个模块之间有着千丝万缕的联系,代码量大,逻辑不够清楚,如果现在想用spring来重构这个项目将是非常困难的,付出的成本将非常大,所以更多的时候公司不得不硬着头皮继续使用老的struts架构,这就阻碍了技术的创新。

5) 资源无法按需伸缩

比如说统计模块是CPU密集型的模块,而交易模块是IO密集型的模块,假如我们要提升交易模块的性能,加大内存、CPU,但是由于所有的模块都在一个架构下,因此所有模块得一视同仁,无法按需进行伸缩。


2 为什么不推荐用SOA架构?

首先说一下SOA架构,在2000年初的时候,两个概念非常流行,一个是EAI(Enterprise application integration),即企业应用集成;还有一个是EII(Enterprise application integration),即企业信息集成。一个从应用的角度,一个从数据的角度,本质是一回事,都是怎么把孤立的系统集成在一起。国外信息化起步较早,很多大公司先后建设了很多系统,比如从开始的ERP,到OA系统,到CRM系统等。由于这些系统往往由不同的供应商提供,采用不同的技术,实施的时候也没预先考虑到和现有系统集成,因此系统集成非常困难。因此,SOA架构应运而生,SOA架构源自于企业内部异构系统的集成,具体做法是各个系统对外提供粗粒度的服务,外部系统可以通过相对标准的技术访问。每个遗留系统提供服务,该服务作为系统的前置代理,对外提供访问。所有这些服务部署在一个中心化的平台,称之为企业服务总线ESB(Enterprise Service Bus),ESB提供复杂处理,包括:

·外部访问:为满足不同客户端访问需求,提供各种各样的访问协议,如WebService、HTTP、FTP、Email等,其中WebService是最典型的通讯协议。

·内部处理:请求进来后,需要一系列复杂处理,如对通讯协议的解析,数据的序列化和反序列化,业务流程的编排和服务路由等。

比如,2008年的时候,eBay基于Axis,开发了自己的SOA框架,各个系统通过创建服务,对外提供功能。如后台搜索系统,本身是C++开发,通过对外提供Java服务,最终以WebService的方式,方便其他系统(大多是Java)调用搜索的功能。经过1年多的时间,整个SOA平台已经有上百个服务,很大程度上方便了系统相互集成。

但很容易看到,ESB是一个很重的机制:

1) 所有系统,都要接入ESB,使它变得巨大且复杂;

2) 而且ESB的中心化带来了单点故障隐患,只要ESB一挂,其他服务都不可用;

3) 服务统一在ESB上进行部署,也限制了服务的水平扩展;

4) 此外ESB还包含很多业务相关的功能,如业务流程编排等,限制了业务扩展的灵活性。

无论对于服务的提供者还是使用者,通过ESB这种方式集成,开发代价大,因此这种传统很重的SOA架构并没有得到大规模应用,特别是互联网公司,几乎很快就过渡到了微服务的架构上。


3 微服务化所带来的改变和优势

上面所说的单体架构、SOA架构的劣势,恰恰就是微服务的优势,此处不再一一描述,仅仅强调和补充如下几点:

1) 加快产品更新迭代速度

微服务中的每个服务,可以单独做上线发布,还可以支持多版本并行,开发测试也是独立的,所以能够快速地进行产品迭代。

2) 降低耦合度,提高效率,能快速开发、测试和上线

每个服务相对隔离,相互之间几乎没有强依赖,这样开发起来,就不会依赖其他模块的代码和功能,可以独立的开发、测试、部署和升级。

3) 以相对节约的方式,提高服务性能和稳定性

每个微服务,可以根据需要进行扩容、缩容,业务量大的服务,可以单独配备更多的资源(服务器、CPU、内存),而业务量小的服务,可以只分配较少的资源,正所谓“好钢用在刀刃上”。配合微服务相关的技术,还可以让我们的服务动态的扩容,以应对临时的流量冲击或大幅波动。

4) 隔离故障,提高安全性和故障恢复的速度

微服务的故障,通常只会影响一个点(通常很小),而不会影响整个系统。通过微服务设计中常用的熔断、降级的机制,可以保证将局部故障的影响降到最低,甚至消除,让用户根本察觉不到。微服务的架构,从数据安全上讲,也更为安全,数据分散在不同地方,泄露更难,出问题的几率更小,恢复更容易。另外,对于重要的服务,还可以特别加强监控,从侧面给予了重要服务的特殊保护。这对于像银行交易这样的核心系统来说尤为重要。


4 注意微服务带来的一些缺点

虽然有如上诸多优点,但是微服务化的架构也带来了一些缺点、麻烦;

特别是对于银行、金融业这种偏传统的行业,会遇到一些新的挑战。总结如下:

1) 运维要求较高

对于单体架构来讲,我们只需要维护好这一个项目就可以了,但是对于微服务架构来讲,由于项目是由多个微服务构成的,要维护很多个小项目,这些项目都是独立运行的,甚至在不同的区域,想要知道是哪个模块造成的问题往往是不容易的,因为我们无法一步一步通过debug的方式来跟踪,这就对运维人员提出了很高的要求。

2) 分布式的复杂性(设计、开发、测试和运维难度更大)

对于微服务架构来说,分布式几乎是必会用的技术,由于分布式本身的复杂性,导致微服务架构也变得复杂起来,比如,要考虑异步处理、远程调用、网络延迟等。服务间的交互,也更难以可视化及全面测试,出现问题不好排查。

3) 不方便整体的调整和集中管理

有一些企业级关注的系统问题,比如,安全策略如何集中管理?系统故障如何快速审计和跟踪到具体服务?整个系统状态如何监控?服务之间的依赖关系如何管理?等等这些问题,都需要整体解决,都不是单个微服务考虑的范畴,而需要一个系统性的考虑和设计,让每个微服务都能够按照系统性的要求和约束提供对应的安全性,可靠性,可维护性的能力。

4) 接口调用和功能调整成本高

由于微服务可能非常多,那么调整接口所造成的成本将会明显提高,比如传统的交易系统,可能在一个项目里面就做完所有流程,要修改的话也相对容易,使用微服务架构之后,会涉及多个子服务的调用,一旦某些微服务的接口发生大的变动,有可能所有依赖它的微服务都要做相应的调整。

5) 重复劳动、不便于代码的重构

对于单体架构来讲,如果某个程序功能被多个模块共同使用、被所有模块直接调用,但是微服务却无法这样做,因为微服务内部非接口性质的程序是不能被其它微服务直接调用的,从而我们不得不在每个微服务上都写相同/相似的代码,从而导致代码重复、不便于重构。



三、 设计要素和实践标准

根据微服务化/组件化的特性,以及银行交易系统的特点,比如对安全性、稳定性的要求,有一些比较好的设计思路和实践经验,下面将概括说明。

1、API设计及API网关

API是服务价值的精华体现,是微服务化/组件化设计中,最重要的组成部分。API需要具备可用/可靠/高效/稳定等特点,因此有如下一些设计要素和实施标准:

  • Version版本号:引入版本号的概念,以兼容多个版本;

  • Auth & Signat 认证和授权:加强安全性;

  • RequstID 请求标识:便于调试和追踪;

  • Docs 文档:配备详细的说明文档;

  • ErrorCode & Message:加入错误码和提示信息;

  • RateLimit 限流:确保服务的质量。

API网关(API Gateway)是一个服务器,是系统的唯一入口,它能够起到安全防护作用、请求管理、API管理甚至监控等功能,常见的一种架构如下图所示:

1540366539711055013.png

由于API网关所处的位置及其重要性,需要特别考虑它的安全和容错——这方面的标配功能包括:认证/授权、限流、安全(防DDos等攻击)、负载均衡、超时、熔断、重试、缓存、监控、访问日志等。限于篇幅,此处不再一一叙述。


2、微服务的治理和开发框架

前面说到,微服务会涉及到很多个小项目,会增加架构的复杂度、引入一些麻烦,对于这些服务的设计和管理,业内提出了微服务的治理规范,以及对应的解决方案。

工欲善其事,必先利其器。一个好的开发框架,能简化微服务的开发,提高服务的质量。相关的一些功能如下:

• 服务定义:包括接口管理,服务的范围和边界

• 注册发现:包括依赖关系、版本,动态的上线、下线

• 负载均衡:包括轮询、加权、最少连接数、IP Hash

• 限流容错和降级:安全,保护服务稳定和质量

• 监控和调用追踪:查看服务全链路的性能和故障

• 部署和升级:支持动态发布,灰度发布,快速扩容、缩容

• 开发、构建和测试:支持单机开发,能实现自动化构建和测试

• 认证和鉴权:权限验证,身份识别

• 协议转换,多编程语言:跨协议、跨语言相互调用

• 日志和审计:记录关键调用信息,方便排查和分析

以上这些功能,当然是越全越好,目前来说,很多开源的框架,已经具备了如上的一些功能,比较常用的微服务框架,包括Spring cloud、Apache Dubbo、SOFA、Motan、Thrift、gRPC等。


3、自动化运维与DevOps、容器化

使用微服务架构,运维会更复杂,那么自动化运维和DevOps是必然之路。这方面的基础体系,包括:

  • 自动化发布系统:所以系统集中管理,一键发布,自动实现构建、打包、启动服务等;

  • 自动化测试平台:在程序构建、发布前、发布后等环节,自动执行单元测试、接口测试、UI自动化测试等;

  • 分布式统一配置中心:实现配置集中、自主管理,配置变更的推送等;

  • DevOps平台:程序从开发——到测试——到上线,全自动化流水作业,这里面还包括代码管理、自动发布/测试等;

  • 统一监控和告警平台:能够监控部署后的系统和应用,出现问题时及时响应和处理。

另外,这一部分,通常要和容器(Docker)技术结合起来,容器技术的特点,和微服务的思想可以完美结合。

  • 容器轻量、够小:解决微服务对机器数量的诉求,且占用资源少,省钱

  • 容器独立:解决多进程隔离、资源隔离、故障隔离问题

  • 开发环境与生产环境相同:避免环境不同引起的诸多问题 

  • 代码/image一体化:可复用,容易管理,容易安装部署

  • 容器的横向与纵向扩容:可动态调节CPU和内存,甚至能自动复制添加服务器

正因为容器技术具备以上这些优势,近几年得以快速的普及,从目前行业的现状来看,容器几乎是微服务应用的标配,是DevOps的基础,三者的关系如下:

1540366539712036386.png

 

4、监控和告警平台

面对这么多服务器监控和告警消息,一个平台的管理尤为重要。比较好的做法是,将多种监控的告警信息集中处理,对告警消息有效区分,合理的告警处理流程以及事后可靠的告警分析,让团队的工作效率提升明显。并能够通过邮件、微信、短信、电话等方式及时有效的发出告警信息。

监控方面,涉及多个方面,包括应用、服务器、网络等,一般来说,分为以下几类:

• 统一日志平台(日志监控):主要记录日志、异常等信息,便于排查问题,比如常用的ELK平台;

• 统一网络及服务器监控平台:监控服务器、网络等健康状态,常用的zabbix、Open-Falcon、Prometheus等;

• 统一应用及中间件监控平台:监控应用、中间件的监控状态;

• 应用性能监控(APM):监控应用的吞吐量、响应时间、调用链路等,

• 网络性能监控(NPM):监控网络的状况,流量、质量(丢包率)、连接数等。


5、多机房、多数据中心

对于银行、金融等重要系统,不得不考虑多数据中心部署,包括同城/异地的灾备、双活、多活,这就会面临多机房、多数据中心的问题。由于机房和机房、城市与城市之间,可能存在较大的网络延迟,让服务间的通信受到影响,这种影响,对大多数微服务系统和中间件来说,甚至是致命的。所以,一直以来,多数据中心,特别是多活,对银行、金融系统都是巨大的难题。

然而,技术越来越发达的今天,我们必须正视这个问题,而且也有很多的案例和解决方案可以参考。

       具体来说,有以下几个方面,可以参考:

• 部署问题:通过自动化工具,统一配置中心,灰度发布等系统来完成;

• 数据一致性:使用“单元化”设计,把用户操作封闭在一个单元内完成;

• 路由一致性:全链路的路由规则,防止串多个中心处理;

• 延时:谨慎挑选第二机房,机房和机房之间,走光纤专线。

另外,考虑拆分服务,某些服务(例如统计、大数据分析等,对实时性要求没这么高的)可以只部署在一个机房,把其他数据同步过来处理。在系统设计时,多考虑“最终一致性”的方案,采用支持多数据中心的中间件。


四、参考资料

理解微服务:http://blog.51cto.com/wyait/1907131

微服务是什么?:https://www.cnblogs.com/PerfectBeauty/p/7587748.html

微服务架构设计:https://www.cnblogs.com/wintersun/p/6219259.html

什么是微服务:https://blog.csdn.net/wuxiaobingandbob/article/details/78642020?locationNum=1&fps=1

浅谈服务治理与微服务:https://blog.csdn.net/suifeng3051/article/details/53992560