其他分享
首页 > 其他分享> > 单体应用微服务改造实践

单体应用微服务改造实践

作者:互联网

【摘要】 本文介绍了如何采用一种持续迭代演进的方法将单体应用改造为微服务应用。重点介绍了如何通过自动测试服务和网关服务来构造持续迭代演进的基础设施。文末介绍了如何使用CSE更好的完成这个过程。
微服务的本质是弹性架构,动态适应业务规模增长,符合业务成长规律。在确定是否投资某一个业务领域或者产品的时候,刚开始都是探索、碰到各种问题,经过多轮迭代,做成一个可用的产品,随着用户使用的越来越多,产品迭代的持续推进,产品越做越好。评估一个单体应用是否值得采用微服务架构进行演进,首先需要确定其业务价值,如果业务价值成长预期大于可预见的投入,那么这个投资就是值得的。单体应用改造为微服务应用是个持续迭代,逐步成长的过程,本文遵循一个进度可控,持续迭代的逻辑,提供了一个单体应用向微服务演进的开发实践参考。“持续迭代演进”是贯穿其中的核心哲学,碰到困难的时候,都会引用这个哲学思想。

**1      自动测试服务:让单体应用健康地运行起来**
通常来讲,单体应用都是一个WEB服务,用户通过浏览器访问单体应用。单体应用在线给用户提供服务,如下图:
image.png
这个系统经过大量的内部测试以及用户使用,运行稳定,只是在应对更大规模的用户请求的时候,无法达到预期的吞吐量,系统处于一种相对“健康”的状态。

当我们需要对一个处于相对“健康”的服务进行改造的时候,这种相对状态就被打破了。任何对于稳定系统的修改,都可能引入新的问题,导致系统失去健康状态。改造的第一个步骤,就是需要提供应对措施,让系统不至于失去健康状态。

解决方案是开发自动测试服务,可以自动的请求单体业务系统,并对请求结果进行判断,检查单体应用的功能是否正常。如下图:
image.png
在实际的实践过程中,最困难的事情是自动测试服务测试哪些内容,如何设计测试步骤,对于一些特殊场景,通过自动测试服务测试非常复杂;还有就是随着测试用例的增多,用例之间相互影响,出现问题难于定位等,这些困难让大量的开发人员望而却步,所以很多系统都没有对应的自动测试服务。在这里,“持续迭代演进”的哲学思想被第一次提及。

·         自动测试服务在开始构建的时候,可以只测试单体业务系统的核心接口,比如登录、支付等核心流程。

·         在日常开发过程中,培养良好的开发习惯,持续的完善自动测试服务。比如在发现BUG的时候,将早期错漏的场景测试,补充进去;完成新的需求开发,把新功能的测试用例加入自动测试服务里面去。

·         尽可能只增加测试用例,不修改、不删除测试用例。在必须修改、删除测试用例的时候,尽可能多做评估,保证修改、删除是必须的,可以和团队成员一起评审后再修改和删除。测试代码可以大量重复,不需要为了测试代码的美观,频繁的重构测试用例,必要的时候,可以开发一个新的自动测试服务,两个服务同时测试,不用废弃老的测试服务。自动测试服务可以是多个测试服务,还可以是多个相互之间存在强逻辑关系的一组服务,完全取决于测试场景和设计。

·         自动测试服务用例运行失败,马上修复,优先于功能开发。

·         自动测试服务不需要尽善尽美,尽最大努力测试能够测试的内容。随着测试能力的积累,以及对于自动测试服务的测试思路的调整,后续写测试用例会越来越简单,能够自动完成的测试点也越来越多。

遵循以上的原则,构建和维护测试用例会一天比一天轻松,即使对于非常棘手的测试用例运行失败,分析也会变得简单。因为测试用例一直都是正常稳定通过的,那么每次失败,都是和新的改动有关,而每次改动量非常小,把思路对准修改的影响就很快识别出问题所在了。

**2      网关服务:弹性架构的基础**
改造过程中,需要保证每天下班前系统都是处于相对“健康”的状态,即构筑的测试用例能够全部运行通过。由于每天修改的内容通常并不会很多,早期涉及到服务拆分、重新设计等场景的时候,保证健康状态并不是一个容易的事情。为了让微服务改造的过程更加的顺畅,首先在原有的系统架构上,引入网关服务。
image.png
网关服务提供一个代理,原来对于业务系统的直接访问,都通过网关来访问。增加网关服务具备如下的用途(需要具备如下功能特征):

·         将单体应用的功能隐藏在网关之后,当单体应用被拆分或者重构的时候,整个系统对外提供的功能保持不变。为了达到这个目的,网关服务需要能够灵活的适配单体业务原来的通讯协议,同时要能够适应拆分的微服务的新协议,并能够根据用户的请求,灵活的定制路由规则,将请求的流量按需转移到拆分后的服务。

·     网关服务能够收集系统运行监控数据,比如接口的时延、用户请求数、系统瓶颈等。这些数据是微服务拆分的依据。进行微服务拆分一般的依据有两个:一是基于业务逻辑的划分;一是基于运维数据的划分。基于逻辑的划分和微服务功能有关,实现不同功能的模块可以独立为一个微服务,比如用户管理服务和订单服务;基于运维数据的划分更多的是性能考虑,比如将访问频繁的接口,单独设计为一个微服务,以更好的给这个接口单独分配更多的处理实例,或者将有状态任务单独拆分出来,提供更好的硬件资源来运行,提高单实例处理能力。

通过网关服务来适配内部服务的协议差异和定制化路由转发,并收集系统的运行状态,为微服务拆分、改造提供了技术基础和改造依据。

**3      服务拆分:基于业务逻辑和基于运维数据**
构筑好测试体系和网关,就可以进行拆分了。微服务拆分可以逐步迭代的进行,拆分依据的输入有两个,首先是业务逻辑的需要,然后是运维数据揭示的性能优化的需要。对于一个单体应用,最快被识别出来的通常是和认证鉴权有关的功能,需要拆分出一个用户管理服务。
image.png
有了网关的支持,实现用户管理服务的功能可以分步骤迭代的进行。比如第一天实现login接口,当用户访问login接口的时候,就将请求路由到用户管理服务上面来,其他请求仍然路由到单体业务系统,当所有测试用例都通过后,就可以逐步的删除单体应用的相关接口。

微服务拆分的另外一个依据和触发点,是运维数据来驱动的。比如用户管理服务发现login接口访问量巨大,而createUser等接口访问量极小,那么可以将所有查询相关的接口拆分为一个微服务,这个微服务进行无状态设计,并且由于这个服务全部都是只读接口,那么可以更好的使用缓存,避免对于数据库的访问。拆分后的服务具备更好的性能和适应能力。
image.png
通过网关路由调整,可以将查询请求路由到查询服务,修改、新增用户等请求,路由到管理服务。查询服务可以部署更多的微服务实例和更好的应用缓存,提升整体的吞吐量;管理服务由于写操作可能存在并发访问控制问题,扩容实例对于性能提升不明显,可以选择更好的硬件来运行这些服务。

随着业务的规模扩大,拆分和优化会时刻发生,比如拆分数据库解决数据库瓶颈问题。自动化测试用例和网关服务为这些拆分提供了良好的保证。

**4      使用CSE作为微服务化的开发框架**
上面提供了一个“持续迭代演进”的方法学,CSE提供了一套开发框架,方便用户能够更好的应用这套方法学。使用CSE,能够很好的进行测试服务的开发和多维度开发环境的管理。CSE的网关服务具备强大的性能统计数据,帮助用户识别性能瓶颈;网关提供接口级别的兼容性转发规则和基于URL匹配的转发规则配置,能够轻松的调整路由;同时还提供了强大的定制开发能力,嵌入认证、鉴权、重试等管控能力。
下面我们通过一个小项目,来演示CSE的这些能力。这个项目的地址:
https://github.com/huaweicse/cse-java-chassis-samples/tree/master/porter/porter_lightweight
开发者可以下载和使用这个项目。下面的功能说明,都是基于这个项目。

**4.1      构筑自动测试服务能力**
CSE提供了服务发现的能力,测试服务能够自动发现网关服务和内部服务,它们都注册在统一的服务中心。
image.png
这种发现能力的好处,使得自动测试服务,不仅可以以“黑盒”的视角从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

**4.2      分层的部署环境支持**
为了更好的支持分层测试,一般会将测试环境分为Alpha、Beta、Gamma、Production等。每个环境测试的内容不同,环境稳定性不同。一些公共的中间件服务,可以不用针对每个环节都搭建,极大的减少环境搭建的时间。CSE提供了分层的逻辑隔离能力,不同环境的微服务可以同时注册到一个服务中心,然后他们之间的访问互不影响。

CSE提供的多环境支持可以参考
如何进行微服务的多环境开发部署 https://bbs.huaweicloud.com/forum/thread-11095-1-1.html

**4.3      通过网关获取监控数据**
CSE提供了强大的监控数据能力,可以统计一个周期内的请求数,时延等信息,还能够统计到处理环节的细节,比如发送请求和等待响应的时间等。这些数据对于性能分析非常关键。 下图展现了少量的数据示例。
image.png
网关打开监控数据是非常简单的,具体可以参考:

性能监控开发指导  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信息,详细可以参考:

Access Log设计参考: https://docs.servicecomb.io/java-chassis/zh_CN/build-provider/access-log-configuration.html

**4.4      通过网关管理路由规则**
CSE网关路由管理能力非常强大,同时具备非常灵活的自定义能力。可以使用网关高效的处理使用CSE框架开发的微服务请求转发,同时也能够方便的扩展,将请求转发到非CSE框架开发的微服务。

CSE在灰度发布支持上,能够做到智能识别接口兼容性转发,具体示例如下:
image.png
CSE能够识别每个微服务实例包含哪些接口,当请求高版本接口的时候,能够自动将请求转发到高版本实例里面去。这样的路由技术,可以很好的支持灰度升级,当provider/consumer都更新了部分新实例的时候,不用担心由于新consumer请求到老provider而导致故障。

CSE还提供了基于服务名和URL前缀的路由转发规则,通过配置文件即可启用。还提供了实例隔离、错误重试等可靠性保障措施。可以通过参考开发指南:

负载均衡管理参考  https://docs.servicecomb.io/java-chassis/zh_CN/references-handlers/loadbalance.html

结合这些能力,可以轻松的实现:

升级零中断 https://bbs.huaweicloud.com/blogs/72a312f09c8911e89fc57ca23e93a89f

**4.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开发业务服务,注册发现、集中配置、运维监控等能力,都可以直接使用云上服务,完全开通即用,省去了开发者的部署、运维成本。
image.png
云上服务都提供了高可用设计。注册发现、集中配置等服务,还通过API Gateway进行了能力开放,开发者可以在云下连接和使用这些服务,这样用户可以在本地进行微服务应用开发。

·         微服务治理管控平台

登录华为CSE平台:

 CSE平台 https://console.huaweicloud.com/cse

该平台可以对CSE SDK开发的微服务进行在线管理、监控和治理。

微服务治理管控平台的主要功能是服务治理,该功能可以在线对微服务进行动态策略调整。包括动态调整限流策略、负载均衡策略等。通过应用这些策略,可以在不升级微服务的情况下,应对一些常见的突发业务。比如在某个大型活动过程中,通过对非关键业务的限流来保障关键业务的平稳运行。
image.png
微服务管控平台还提供了其他重要的功能,包括一键式购买微服务引擎、微服务目录,仪表盘等功能。

·         DevOps支持

ServiceStage https://console.huaweicloud.com/servicestage

ServiceStage提供了一站式DevOps平台。通过ServiceStage可以托管源码,创建流水线,部署应用,管理用户网络、计算和存储资源。ServiceStage还集成了容器、虚机能力,可以管理应用的动态扩缩容。可以通过“体验中心”来了解ServiceStage功能,这里不再详细介绍。

标签:网关,服务,CSE,改造,自动测试,实践,单体,测试用例,拆分
来源: https://blog.51cto.com/u_15214399/2823303