2018 年被称为 Service Mesh 之年,层出不穷的服务网格产品,越来越多的厂商参与进来,提供自己的解决方案。
其中的 Istio 甚至成为了服务网格代名词。但目前我看到的是,经过了 2 年的发展,Istio 还未被大规模的使用于生产中。
Spring Cloud、Dubbo 等发展了多年的框架依然有着存量用户,不容易切换到服务网格,因为这势必意味着 2 套解决方案共同存在,那么如何平滑过渡到服务网格也是这些框架的用户关心的事。
这次分享我将讲述 Apache ServiceComb 在开发框架和服务网格的融合实践,也会看到 Spring Cloud 如何向服务网格平滑过渡。
Apache ServiceComb 在今年推出了服务网格(https://github.com/apache/servicecomb-mesher),配置管理(https://github.com/apache/servicecomb-kie)等多个新服务。
我们在 17 年看到服务网格的兴起后便开始了服务网格的研发,并于年底在华为云上线商用,今年将它开源捐赠给 Apache 基金会,完善了 ServiceComb 的多语言能力。
得益于我们本来在 ServiceComb 开发中的积累(Go、Java 语言开发框架),我们快速的基于原本的 Go 微服务开发框架进行了服务网格的开发,以此来实现多语言的接入。
这是当前组件的全景图,Mesher 作为服务网格方案可将服务接入到分布式系统中,与 go chassis 和 java chassis 等开发出的微服务打通。
注册发现中心,管理微服务及版本信息等元数据,并且可以管理框架生成出来的 Open API 文档。而这也大大加强了团队之间的合作效率,可以根据文档来进行客户端的开发和测试。
一个通用的配置管理中心,当前是独立的服务,未来我们将会接入到配置管理中心,让用户可以在统一的中心进行配置管理(熔断、限流等规则),并且能够管理业务的配置。
2 个框架,都实现了一致的功能,以保证用户体验一致,比如熔断、限流。可根据代码自动生成 Open API 文档并上传到 Service center。
以 go chassis 实现为例,基本的运作机制如下:
不同协议请求进入到各协议 Server,Server 将具体的协议请求转换为 Invocation 统一抽象模型,并传入 Handler chain,在这 chassis 已经默认实现了很多的 Handler,比如熔断,限流等,最终再进入 Transport handler,使用具体的协议客户端传输到目标。
生成的监控数据通过 http API 导出,由 Prometheus 收集处理
Archaius 为动态配置框架,可从各种不同的 source 中读取配置,比如 Kie。
服务网格方案,Mesher 之所以能建立在 go chassis 之上快速建立起来,得益于 go chassis 的 invocation 概念。
即 invocation 不感知协议,可以将协议转换为 invocation,而微服务相关的所有治理能力,都以 invocation 作为标准,所以这些功能就可以完全复用,只需要扩展 Server 实现即可,代理服务将请求转为 invocation 后,后续的代码就可以复用了。当前基于这个框架,Mesher 已支持 grpc 与 http 协议,也支持开发者自己定制。
提供 Spring Cloud 的扩展组件(https://github.com/huaweicloud/spring-cloud-huawei),可以使其接入到 ServiceComb 管理面中,帮助 Spring Cloud 用户平滑向多语言,服务网格转型,Java 不再是开发微服务唯一的选择,可平滑过渡到使用 Go 语言或者 Node js 等,并将一部分开发团队从框架中解放。
Mesher 支持.Net 应用接入到服务网格,可以与其他语言打通,在一套系统下进行治理。
ServiceComb 可独立部署,不会绑定部署系统,无论虚机还是容器还是 kubernetes 平台,都可以部署,部署限制性很低。
使用统一的微服务解决方案可打通公司内部各个业务服务的能力,不断复用当前能力,以更快的应对需求并且通过业务暴露出的数据做更多的业务整合,以构建更加强大的业务平台。
下面, 我以实际的例子来讲述用户使用 ServiceComb 的实践经验。
多年的 PHP 技术积累,很多程序都是 PHP 的,面临微服务化改造非常困难,而基于 java 技术新开发的业务又要快速开发以应对市场变化。那么微服务化是非常重要的,为了能让服务共同协作。
java 可以选用 java chassis 进行微服务化。对于存量 PHP 业务,要求稳定,不碰业务代码,零侵入完成微服务化;对于新开发业务,要求高性能,细化到业务的治理和监控。在这个场景中,一个统一的微服务解决方案变得至关重要。
以下是改造后的架构
改造后收益:
在原来的框架中,PHP 作为动态语言难以承载未来业务量的上升,在进行接入改造后,由于 java chassis 是一种高性能 java 微服务开发框架,因此整体的性能得到了提升,而更多的语言选择意味着业务团队可以自由选择适合服务的语言进行实现,并能够在统一的系统中进行治理。对外暴露使用 Edge Service,一种网关开发框架,与业务部署在同一网络,可将业务能力暴露给其他应用。
原本的系统是独立的烟囱式单体,业务能力无法复用,如果想应变不断变化的需求就需要将单体进行拆分,微服务化,以快速复用解耦的已存在的业务能力,前台选择 Node js 进行开发,使用服务网格接入,而后台则全部使用 java chassis 开发。
同济使用了多种云服务构建了自己的平台服务,其中的 EI 服务,云容器引擎等商用方案不在本次话题内。微服务引擎就是 ServiceComb 的商用方案名称。
并非所有服务都适合服务网格。由于服务网格是应用代理服务,用户态与内核态之间的数据复制导致性能有所下降,而下降的程度基本与一次请求调用传输的 payload 大小相关,越大性能下降越明显。而较小的尺寸,性能下降很小。所以对于请求并发量很大,且处理大尺寸请求的接口最好不要应用服务网格,比如图片,大量数据。开发框架依然是这种场景的首选。
即便使用用户态协议栈,避免了内核态用户态切换以及数据拷贝,但这也并非是一个完美的方案(https://blog.cloudflare.com/why-we-use-the-linux-kernels-tcp-stack/),所以在某些场景下,使用服务网格将会一直面临性能上的降低,而且当前没有好的解决方案。
使用 ServiceComb,如果是新项目可以一开始全部使用服务网格,在遇到性能瓶颈时再考虑使用开发框架进行优化。
ServiceComb 在微服务领域多年的积累使我们能够快速的应对服务网格的兴起,并且快速构建出开发框架与服务网格融合的解决方案。在用户对性能有要求的情况下能够使用框架来满足,并对其他语言提供了兼容,而使用 Spring Cloud 的用户也可以接入到 ServiceComb 中使用服务网格或是 go 语言框架。
为何架构设计如此重要,因为他帮助你解决非功能性的问题,并促进业务的成功,为业务保驾护航。
微服务作为一种架构模式,给了一种架构指导,也是一种最佳实践。而该模式的引入帮你解决问题的同时却又引入不少问题需要解决,需要一套强大的框架来帮助你完成这个架构转型,让你更加聚焦于业务功能,免去架构设计上的投入,ServiceComb 的微服务解决方案便是为了解决微服务带来的复杂性而生。
微服务化给业务带来的一个很大的价值是将企业内部的业务能力进行解耦后复用,打通数据,以快速应对变化的市场需求。而随着多年的发展,公司内部通常会积累相当多的技术栈,语言,这些系统 (即异构系统) 间通常是不产生关系的,数据无法打通,将这些业务进行整合,打破烟囱成为了亟待解决的问题,ServiceComb 在这方面提供了一个完整的方案,可以供企业转型时使用。
对于想深入了解 ServiceComb 的读者,可以阅读我们的项目介绍参与到社区:
https://github.com/apache/servicecomb-mesher: 服务网格
https://github.com/apache/servicecomb-kie:配置管理中心
https://github.com/go-chassis/go-chassis:go 微服务框架
https://github.com/apache/servicecomb-java-chassis:java 微服务框架