作者:费伟伟
上海华瑞银行数字银行开发中心
微服务这个词基本贯穿了最近几年的技术圈,那微服务到底是什么?为什么需要微服务?微服务到底解决了什么问题?微服务主要的核心能力有哪些?本篇分享会介绍下,可以作为传统银行项目经理和初级开发人员入门的一篇文章。
单体应用的问题
- 部署效率低
当单体应用的代码越来越多,依赖的资源越来越多时,应用编译打包、部署测试,基本都要10分钟以上,这还是都做了自动化编译打包的情况下,如果编译打包、上传、起停服务都是手工做的话那估计要半小时,以前很多时候都是只要在测试环境发布一个包,很多测试同学就下楼抽根烟,或者去喝杯咖啡,是不是很有画面感:)
- 团队协作成本高
以我这么多年的编码经验,早期在团队只有两三个开发人员的时候,协作修改代码,最后合并到一个分支,然后打包部署,风险还是可以控制的,但是一旦团队人员开始扩张,超过5人修改代码,然后一起打包部署,测试阶段只要一个功能有问题,就得全部重新编译打包部署,然后重新回归测试,所有相关开发人员又都要参与其中,效率低下,开发成本比较高。这一点不单单针对服务端单体开发,在超级app的移动开发团队一样会存在这样的协作问题。
- 系统高可用性差
因为所有的功能开发最后都部署到同一个包中,运行在同一个jvm进程中,一旦某个功能涉及的代码或者资源有问题,那就回影响整个应用包的部署功能。在单体时代我们经常遇到的问题是某些代码一直在创建大对象,但是没有及时回收资源,部署到线上运行一段时间出现内存泄漏,整个应用异常退出,那么部署在一个jvm里所有的服务都不可用,后果非常严重。
- 线上发布慢
对于我们主流的java应用来说,一旦代码量非常大了以后,服务启动时间就会非常长,有的甚至需要10分钟以上,如果服务节点非常多了以后,可能每次发版本需要很长的时间,因此,非常需要一种方法能够将应用的不同模块解耦,降低开发和部署成本。
通过服务化可以解决单体应用膨胀、团队开发耦合度高、协作效率低下的问题。
微服务特点
其实服务化这个概念在2003年以后就开始炒作,直到2005年很多公司推出了ESB产品才逐渐在各个公司落地,ESB带来了服务化这个概念即SOA,在SOA的架构下,所有的系统提供的能力都是服务,不同系统之间的访问都是通过ESB总线进行通讯,ESB的设计思路也是借鉴了硬件主板上的南桥北桥的设计思想,服务化和微服务都是服务,那么两者本质上有什么差异呢?
- 服务拆分粒度更细
微服务可以说是更细维度的服务化,小到一个子模块,只要该模块依赖的资源与其他模块都没有关系,那么就可以拆分为一个微服务。
- 服务独立部署
每个微服务都严格遵循独立打包部署的准则,互相不影响。
- 服务独立维护
每个微服务都可以交给一个团队甚至个人开发、测试、发布和运维,并对整个服务生命周期进行管理。
- 服务治理能力要求高
服务拆分后,服务的数量变多,因此需要有统一的服务治理平台,来对各个服务进行管理,需要能知道所有服务的调用和被调用情况,还有每个服务的响应时间、故障情况等等。
单体应用转微服务需要解决的问题
- 服务如何定义
对单体应用来说,不同功能模块之间相互交互时,通常是以类库的方式来提供各个模块的功能。对于微服务来说,每个服务都运行在各自的进程之中,通过接口向外界传达自己的信息,接口的话可以采用7层的http协议或者4层RPC协议,服务之间的调用都通过接口描述来约定,接口描述包括接口名、接口参数以及接口返回值。
- 服务如何发布和订阅
单体应用由于部署在一个war包中,接口之间的调用属于进程内的调用。而拆分为微服务后独立部署,所有的服务都需要将服务的地址和端口登记在一个公共的地方,能够记录每个服务提供者的地址以供服务调用者查询,在微服务架构中,这个地方就是我们常说的注册中心。
- 服务如何监控
对于一个服务来说,我们最关心的是qps、平均调用耗时,以及90线、95线这些指标。这时就需要有一种通用的监控方案,能够覆盖业务埋点、数据收集、数据处理,最后到数据展示的全链路功能。
- 服务如何治理
服务拆分之后,服务的数量变多了,依赖的关系也非常复杂。比如一个服务的性能有问题时,依赖的服务都势必会受到影响。可以设定一个调用性能阈值,如果一段时间内超过这个值,那么依赖服务的调用就可以直接返回,这就是常说的熔断处理。
- 故障如何定位
在单体应用拆分微服务后,一次用户调用可能依赖多个服务,每个服务又部署在不同的节点上,如果用户调用出现嗯提,需要有一种解决方案能够将一次用户请求进行标记,并在多个依赖的服务中继续传递,以便串联所有路径,从而进行故障定位。
微服务架构核心组件
- 服务描述
服务调用首先要把服务定义出来,这样服务调用者才能进行调用。常用的服务描述方式有Restful API、RPC XML、RPC IDL文件3种方式。
-
注册中心
注册中心的工作流程是:
1)服务提供者在启动时,根据服务发布文件中配置的发布信息向注册中心注册自己的服务
2)服务消费者在启动时,根据消费者配置文件中配置的服务信息向注册中心订阅自己锁需要的服务
3)注册中心返回服务提供者地址列表给服务消费者
4)当服务提供者发生变化,比如节点新增或者销毁,注册中心将变更通知给服务消费者
- 微服务框架
通过注册中心,服务消费者就可以就可以获取到服务提供者的地址,有了地址后就可以发起调用。但在发起调用之前你还需要解决以下问题:
1)服务通信采用什么协议?就是说服务提供者和服务消费者之间以什么样的协议进行通信,采用4层TCP还是七层http协议?
2)数据传输采用什么方式?就是说服务提供者和服务消费者之间的数据传输采用哪种方式,是同步还是异步,是在单连接上传输,还是多路复用。
3)数据压缩采用什么格式?通常数据传输都会进行数据压缩,减少网络传输的数据量,从而减少带宽的占用
- 服务监控
一旦服务消费者与提供者之间能够正常发起服务调用,你就需要对调用情况进行监控,了解服务是否正常。服务监控需要做到3件事:
1)数据收集,需要把每一次服务调用的请求耗时以及成功与否收集起来,并上传到集中监控中心
2)数据处理,有了每次调用的请求耗时以及成功与否等信息,就可以计算每秒服务请求量、平均耗时以及成功率等指标
3)数据展示,数据处理后,还需要在dashboard上进行展示,并通过设置指标阈值进行预警
- 服务追踪
除了需要对服务进行监控外,还需要统计出服务调用的每一层链路,以便进行问题跟踪和故障定位,服务跟踪的原理如下:
1)服务消费者发起调用前,会在本地按照一定的规则生成一个requestid,发起调用时,会将requestid当作请求参数的一部分传递给服务提供者
2)服务提供者接收到请求后,记录下这次请求的requestid,然后处理请求。如果服务提供者继续请求其他服务,会在本地再生成一个自己的requestid,然后把这两个requestid都当作请求参数继续往下传递
3)通过这种层层往下传递的方式,一次请求,无论最后依赖多少层级的服务调用,经过多少服务节点,都可以通过最开始生成的requestid串联所有的节点,从而达到服务追踪的目的
- 服务治理
服务监控能够发现问题,服务跟踪能够定位问题所在,而解决问题就得靠服务治理。服务治理就是通过一系列的手段来保证在各种意外情况下,服务调用仍然能够正常进行。
服务治理主要用于以下几种情况:
1)单机故障,传统IDC遇到单机故障,都是运维通过监控发现并重启服务或者从线上手工摘除故障节点。如果机房集群越大,越容易出现单机故障,在机器规模超过100台以上时,靠传统人工运维很难快速应对, 而服务治理可以通过一定的策略,自动摘除故障节点,不需要人为干预,就能保证单机故障不会影响业务。
2)依赖服务不可用,我们在生产环境中经常会遇到,你的服务依赖于另一个服务,当另一个服务出现问题的时候,会拖慢甚至拖垮你的服务。而服务治理可以通过熔断,在依赖服务异常的情况下,一段时间内停止发起调用而直接熔断返回固定信息。这样一方面保证了服务消费者能够不被上游系统故障拖垮,另一方面也给服务提供者减少压力,使其能够尽快修复。
3)单IDC故障,单机房故障在传统银行如果发生,那是灾难性的事故,很多银行虽然做了所谓的灾备演练,如果实际发生,根本无法做到0秒切换到灾备机房,RTO、RPO都会很高,肯定会影响业务连续性。而服务治理可以通过自动切换故障IDC的流量到其他正常的IDC,可以避免因为单IDC故障引起的大量业务受影响。
总结
本篇分享主要从单体应用的问题开始分析使用为什么要使用微服务,同时也分析了微服务的特点,已经传统单体应用转微服务需要解决的问题,最后详细介绍了微服务架构中的核心组件,后续会再单独详细介绍每一个微服务核心组件的内容。