微服务的本质是弹性架构,动态适应业务规模增长,符合业务成长规律。在确定是否投资某一个业务领域或者产品的时候,刚开始都是探索,碰到各种问题,并经过多轮迭代,做成一个可用的产品,随着用户使用的越来越多,产品迭代的持续推进,产品越做越好。评估一个单体应用是否值得采用微服务架构进行演进,首先需要确定其业务价值,如果业务价值成长预期大于可预见的投入,那么这个投资就是值得的。单体应用改造为微服务应用是个持续迭代,逐步成长的过程,本文遵循一个进度可控,持续迭代的逻辑,提供了一个单体应用向微服务演进的开发实践参考。“持续迭代演进”是贯穿其中的核心哲学,碰到困难的时候,都会引用这个哲学思想。
自动测试服务
让单体应用健康地运行起来
通常来讲,单体应用都是一个WEB服务,用户通过浏览器访问单体应用。单体应用在线给用户提供服务,如下图:
这个系统经过大量的内部测试以及用户使用,平时运行稳定,只是在应对更大规模的用户请求的时候,无法达到预期的吞吐量,系统处于一种相对“健康”的状态。
当我们需要对一个处于相对“健康”的服务进行改造的时候,这种相对状态就被打破了。任何对于稳定系统的修改,都可能引入新的问题,导致系统失去健康状态。改造的第一个步骤,就是需要提供应对措施,让系统不至于失去健康状态。
解决方案是开发自动测试服务,可以自动的请求单体业务系统,并对请求结果进行判断,检查单体应用的功能是否正常。如下图:
在实际的实践过程中,最困难的事情是自动测试服务要测试哪些内容,如何设计测试步骤,对于一些特殊场景,通过自动测试服务测试非常复杂;还有就是随着测试用例的增多,用例之间相互影响,出现问题难于定位等,这些困难让大量的开发人员望而却步,所以很多系统都没有对应的自动测试服务。在这里,“持续迭代演进”的哲学思想被第一次提及。
自动测试服务在开始构建的时候,可以只测试单体业务系统的核心接口,比如登录、支付等核心流程。
在日常开发过程中,培养良好的开发习惯,持续的完善自动测试服务。比如在发现BUG的时候,将早期错漏的场景测试,补充进去;完成新的需求开发,把新功能的测试用例加入自动测试服务里面去。
尽可能只增加测试用例,不修改、不删除测试用例。在必须修改、删除测试用例的时候,尽可能多做评估,保证修改、删除是必须的,可以和团队成员一起评审后再修改和删除。测试代码可以大量重复,不需要为了测试代码的美观,频繁的重构测试用例,必要的时候,可以开发一个新的自动测试服务,两个服务同时测试,不用废弃老的测试服务。自动测试服务可以是多个测试服务,还可以是多个相互之间存在强逻辑关系的一组服务,完全取决于测试场景和设计。
自动测试服务用例运行失败,马上修复,优先于功能开发。
自动测试服务不需要尽善尽美,尽最大努力测试能够测试的内容。随着测试能力的积累,以及对于自动测试服务的测试思路的调整,后续写测试用例会越来越简单,能够自动完成的测试点也越来越多。
遵循以上的原则,构建和维护测试用例会一天比一天轻松,即使对于非常棘手的测试用例运行失败,分析也会变得简单。因为测试用例一直都是正常稳定通过的,那么每次失败,都是和新的改动有关,而每次改动量非常小,把思路对准修改的影响就很快识别出问题所在了。
网关服务
弹性架构的基础
改造过程中,需要保证每天下班前系统都是处于相对“健康”的状态,即构筑的测试用例能够全部运行通过。由于每天修改的内容通常并不会很多,早期涉及到服务拆分、重新设计等场景的时候,保证健康状态并不是一个容易的事情。为了让微服务改造的过程更加顺畅,首先需要在原有的系统架构上,引入网关服务。
网关服务提供一个代理,原来对于业务系统的直接访问,都通过网关来访问。增加网关服务具备如下的用途(需要具备如下功能特征):
将单体应用的功能隐藏在网关之后,当单体应用被拆分或者重构的时候,整个系统对外提供的功能保持不变。为了达到这个目的,网关服务需要能够灵活的适配单体业务原来的通讯协议,同时要能够适应拆分的微服务的新协议,并且能够根据用户的请求,灵活的定制路由规则,将请求的流量按需转移到拆分后的服务。
网关服务能够收集系统运行监控数据,比如接口的时延、用户请求数、系统瓶颈等。这些数据是微服务拆分的依据。进行微服务拆分的依据一般有两个:
基于业务逻辑的划分。
基于逻辑的划分和微服务功能有关,实现不同功能的模块可以独立为一个微服务,比如用户管理服务和订单服务。
基于运维数据的划分。
基于运维数据的划分更多的是性能考虑,比如将访问频繁的接口,单独设计为一个微服务,以更好的给这个接口单独分配更多的处理实例,或者将有状态任务单独拆分出来,提供更好的硬件资源来运行,提高单实例处理能力。
通过网关服务来适配内部服务的协议差异和定制化路由转发,并收集系统的运行状态,为微服务拆分、改造提供了技术基础和改造依据。
服务拆分
基于业务逻辑和基于运维数据
构筑好测试体系和网关,就可以进行拆分了。微服务拆分可以逐步迭代的进行,拆分依据有两个,首先是业务逻辑的需要,然后是运维数据揭露的性能优化的需要。对于一个单体应用,最快被识别出来的通常是和认证鉴权有关的功能,需要拆分出一个用户管理服务。
有了网关的支持,实现用户管理服务的功能可以分步骤迭代的进行了。比如第一天实现login接口,当用户访问login接口的时候,就将请求路由到用户管理服务上面来,其他请求仍然路由到单体业务系统,当所有测试用例都通过后,就可以逐步的删除单体应用的相关接口。
微服务拆分的另外一个依据和触发点,是运维数据来驱动的。比如用户管理服务发现login接口访问量巨大,而createUser等接口访问量极小,那么可以将所有查询相关的接口拆分为一个微服务,这个微服务进行无状态设计,并且由于这个服务全部都是只读接口,那么可以更好的使用缓存,避免访问数据库。拆分后的服务具备更好的性能和适应能力。
通过网关路由调整,可以将查询请求路由到查询服务,而修改、新增用户等请求,可以路由到管理服务。查询服务可以部署更多的微服务实例和更好的应用缓存,提升整体的吞吐量;管理服务由于写操作可能存在并发访问控制问题,扩容实例对于性能提升不明显,可以选择更好的硬件来运行这些服务。
随着业务的规模扩大,拆分和优化会时刻发生,比如拆分数据库解决数据库瓶颈问题。自动化测试用例和网关服务为这些拆分提供了良好的保证。
使用CSE作为微服务化的开发框架
上面提供了一个“持续迭代演进”的方法学,CSE(https://www.huaweicloud.com/product/cse.html)提供了一套开发框架,方便用户能够更好的应用这套方法学。使用CSE,能够很好的进行测试服务的开发和多维度开发环境的管理。CSE的网关服务具备强大的性能统计数据,帮助用户识别性能瓶颈;网关提供接口级别的兼容性转发规则和基于URL匹配的转发规则配置,能够轻松的调整路由;同时还提供了强大的定制开发能力,嵌入认证、鉴权、重试等管控能力。
下面我们通过一个小项目,来演示CSE的这些能力。这个项目的地址:
https://github.com/huaweicse/cse-java-chassis-samples/tree/master/porter/porter_lightweight
开发者可以下载和使用这个项目。下面的功能说明,都是基于这个项目。
1
构筑自动测试服务能力
CSE提供了服务发现的能力,测试服务能够自动发现网关服务和内部服务,它们都注册在统一的服务中心。
这种发现能力的好处,使得自动测试服务,不仅能够以“黑盒”的视角从gateway访问整个系统,还可以以“白盒”的视角直接测试内部的微服务。
通常微服务都提供了REST接口对外提供服务,以“黑盒”来测试内部服务,需要测试代码,拼接HTTP消息,这样测试代码会显得比较冗余。CSE提供了RPC和REST等多种书写客户端代码的方式,能够更加简单的书写客户端代码。
RPC方式访问
@RpcReference(microserviceName = "hello", schemaId = "hello")
private Hello hello;
System.out.println(hello.sayHi("Java Chassis"));
Spring MVC RestTemplate格式
RestTemplate template = RestTemplateBuilder.create();
template.postForEntity("cse://pojo/pojo/rest/dbgrinfo", "test", String.class)
使用其他HTTP Client
此外,还可以使用第三方的工具来调用。比如Apache Http Client等。
CSE作为一个微服务框架,自己的自动化测试体系也是基于CSE本身构建的。这些自动化测试的机制方式,开发者也可以在业务系统中参考。
[ServiceComb的自动化测试服务](https://github.com/apache/servicecomb-java-chassis/tree/master/integration-tests)
[CSE的部分测试用例](https://github.com/huawei-microservice-demo/ServiceEngineIntegrationTest)
2
分层的部署环境支持
为了更好的支持分层测试,一般会将测试环境分为Alpha、Beta、Gamma、Production等。每个环境测试的内容不同,环境稳定性不同。一些公共的中间件服务,可以不用针对每个环节都搭建,极大的减少环境搭建的时间。CSE提供了分层的逻辑隔离能力,不同环境的微服务可以同时注册到一个服务中心,而他们之间的访问互不影响。
CSE提供的多环境支持可以参考[如何进行微服务的多环境开发部署](https://bbs.huaweicloud.com/forum/thread-11095-1-1.html)。
3
通过网关获取监控数据
CSE提供了强大的监控数据能力,可以统计一个周期内的请求数,时延等信息,还能够统计到处理环节的细节,比如发送请求和等待响应的时间等。这些数据对于性能分析非常关键。 下图展现了少量的数据示例。
网关打开监控数据是非常简单的,具体可以参考[开发指导](https://docs.servicecomb.io/java-chassis/zh_CN/general-development/metrics.html)。
除了监控数据,网关还有access log,可以帮助识别调用失败的环节。
0:0:0:0:0:0:0:1 - - Fri, 15 Feb 2019 11:06:15 CST "POST /api/user-service/v1/user/login HTTP/1.1" 200 0 7
0:0:0:0:0:0:0:1 - - Fri, 15 Feb 2019 11:06:15 CST "POST /api/user-service/v1/user/login HTTP/1.1" 200 0 8
AccessLog可以包含一个请求的trace id信息,详细参考[开发指导](https://docs.servicecomb.io/java-chassis/zh_CN/build-provider/access-log-configuration.html)。
4
通过网关管理路由规则
PART
01
CSE网关路由管理能力非常强大,同时具备非常灵活的自定义能力。可以使用网关高效的处理使用CSE框架开发的微服务请求转发,同时也能够方便的扩展,将请求转发到非CSE框架开发的微服务。
PART
02
CSE在灰度发布支持上,能够做到智能识别接口兼容性转发,具体示例如下:
PART
03
CSE能够识别每个微服务实例包含哪些接口,当请求高版本接口的时候,能够自动将请求转发到高版本实例里面去。这样的路由技术,可以很好的支持灰度升级,当provider/consumer都更新了部分新实例的时候,不用担心由于新consumer请求到老provider而导致故障。
PART
04
CSE还提供了基于服务名和URL前缀的路由转发规则,通过配置文件即可启用。还提供了实例隔离、错误重试等可靠性保障措施。可以通过[开发指南](https://docs.servicecomb.io/java-chassis/zh_CN/references-handlers/loadbalance.html)深入了解。
结合这些能力,就可以轻轻松松“0代码”实现滚动升级不断服。
5
专注于业务功能开发
除了上面的一些特性,来支持单体改造,CSE还提供了大量的平台功能,让业务能够专注于业务逻辑开发,而不需要开发可靠性、服务管理、服务运维等方面的功能。下面挑选一些代表性的功能。
高性能和高可靠
CSE提供了非常高效的REST通信实现,目前是开源微服务框架里面最高效的REST实现,在普通的4U8G虚拟机,框架能够到达5万以上的吞吐量。
CSE运行框架在实例发现保护、实例隔离、错误隔离和重试、线程池隔离等方面也提供了强大的保护能力,通常用户不需要开发任何代码,系统默认就集成了这些健壮性特性,即使用户需要定制,一般也只需要简单的修改配置项就能够实现。比如实例隔离的配置项:
cse:
loadbalance:
isolation:
enabled: true
enableRequestThreshold: 5
singleTestTime: 60000
continuousFailureThreshold: 2
该配置项定义了隔离的条件,以及隔离的时间。再比如重试配置项:
cse:
loadbalance:
retryEnabled: false
retryOnNext: 0
retryOnSame: 0
配置项定义了是否开启错误重试以及重试策略。CSE的大部分策略,不仅可以全局配置,还可以针对微服务配置,只对微服务生效。有些配置项还支持对具体的接口配置,只对接口生效。
cse:
executors:
Provider:
[servicename:schemaid.operationId]: cse.executor.reactive
该配置对给微服务servicename的schemaid(class对应的类)的operatioinId(对应方法名)配置了单独的线程池,避免其他服务的运行对这个接口的执行产生影响,起到了故障隔离的作用。
在线的中间件服务
下图展现了CSE开发SDK的内部功能及其和云上服务之间的关系。业务通常指需要使用SDK开发业务服务,注册发现、集中配置、运维监控等能力,都可以直接使用云上服务,完全开通即用,省去了开发者的部署、运维成本。
云上服务都提供了高可用设计。注册发现、集中配置等服务,还通过API Gateway进行了能力开放,开发者可以在云下连接和使用这些服务,这样用户可以在本地进行微服务应用开发。
微服务治理管控平台
登录华为[CSE平台]( https://console.huaweicloud.com/cse),该平台可以对CSE SDK开发的微服务进行在线管理、监控和治理。
微服务治理管控平台的主要功能是服务治理,该功能可以在线对微服务进行动态策略调整。包括动态调整限流策略、负载均衡策略等。通过应用这些策略,可以在不升级微服务的情况下,应对一些常见的突发业务。比如在某个大型活动过程中,通过对非关键业务的限流来保障关键业务的平稳运行。
微服务管控平台还提供了其他重要的功能,包括一键式购买微服务引擎、微服务目录,仪表盘等功能。
DevOps支持
[ServiceStage]( https://console.huaweicloud.com/servicestage)提供了一站式DevOps平台。通过ServiceStage可以托管源码,创建流水线,部署应用,管理用户网络、计算和存储资源。ServiceStage还集成了容器、虚机能力,可以管理应用的动态扩缩容。可以通过“体验中心”来了解ServiceStage功能,这里不再详细介绍。
▼
往期精彩回顾
▼
长按关注>>>
盘它
戳“阅读原文”获取CSE,解锁新姿势!