一、背景
Service Mesh、云原生等概念已经出了五六年了。从实践落地来看,还没有得到广泛的推广普及,使用范围限制在亚马逊、微软、阿里云等云厂商内部。在各大厂商的实践过程中,Bilgin Ibryam 在其博客Multi-Runtime Microservices Architecture (infoq.com)中提出了微服务的一个新的设想:Multiple Runtime。在其设想中的微服务架构中,出现了 Mecha 层的划分。故我们将其提出的 Mutiple Runtime 微服务架构模式,翻译为“机甲模式”。
本文将对机甲模式(Bilgin Ibryam 的设想:Multiple Runtime)做出介绍,并对服务架构的演变历史进行回顾。
二、服务架构的演变
2.1、单体服务
业务功能集中在一个项目中开发,进行部署,通过单一后端应用提供并集成所有的服务。
2.2、分布式系统
根据业务功能对系统做拆分,每个业务模块作为独立项目进行开发,以服务形式部署。
2.3、微服务
微服务(Microservices) 是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic) 的 API 集相互通信。
2.4、Service Mesh
服务网格是一个基础设施层,用于处理服务间通信。云原生应用有着复杂的服务拓扑,服务网格保证请求在这些拓扑中可靠地穿梭。在实际应用当中,服务网格通常是由一系列轻量级的网络代理组成的,它们与应用程序部署在一起,但对应用程序透明。whats-a-service-mesh-and-why-do-i-need-one
三、分布式的核心问题及机甲模式
伴随着分布式系统的落地,需要解决分布式系统中:服务治理、分布式事务、打包部署等问题。下面我们一起来过一下分布式系统中需要关注的问题:
3.1、分布式应用程序需求
3.1.1、生命周期(Lifecycle)
功能以代码的形式交付之后,编程语言会决定在这个生态中用什么样的库、打包方式、运行方式。例如,Java 生态中依赖的 Maven 库,JVM。在整个生命周期中,打包、部署、健康检查、配置、异常恢复,都是应用在整个生命周期中的重要组成部分。
3.1.2、网络(Networking)
当下,几乎所有的分布式应用程序都需要考虑到网络问题。而且网络的范围更广,不仅仅是通信问题,还包括服务发现、超时重试机制、网络安全问题等。
3.1.3、状态(State)
状态的概念,大部分情况下是指服务的状态,服务需要表现出无状态。服务编排、工作流、时间调度(定时任务)、幂等性、故障恢复、缓存等。
3.1.4、绑定(Binding)
分布式系统中,不仅需要考虑到系统内部的调用。还需要考虑到与外部系统、组件之间的连接、协议转换、消息的传递及路由、事务。
3.2、分布式的困境与现状
在容器(Docker)、服务编排(Kubernetes)的基础之上,随着行业内在分布式中的积累,Service Mesh、云原生(Cloud-Native)在各大云厂商的。
3.2.1、分布式的困境
不同语言的基础功能复用性不高或者比较困难,服务的开发者绑定在特定语言上
强依赖 SDK,升级工作会变得复杂
数据库等客户端配置、初始化需要在服务中进行,未完全解耦,抽离出来
3.2.2、分布式架构现状
传统中间件和云原生平台对比,传统中间件提供各种 SDK 的方式提供能力,而云原生则是提供各种外围 Runtime。云原生平台在业务逻辑从平台中解耦的方面已经做的比较好了,但是在未来还会有更多的可能性,应用中的过滤器、聚合器、内容路由,流式计算中的合并、滑动窗口等逻辑部分,依然是在业务逻辑中。
3.3、机甲模式对分布式的设想
基于现状,业界大佬(Bilgin Ibryam)在自己的博客Multi-Runtime Microservices Architecture中对当前的云原生的最佳实践进行归类划分
Kubernetes 和容器技术对多语言应用程序的生命周期管理,奠定了基础
Service Mesh 利用先进的网络功能对 Kubernetes 有了进一步提升
Dapr 基于 Kubertetes、Knative 和 Service Mesh 的理念,在分布式系统方面有了更先进的实践
3.3.1、机甲模式架构
这是一种类似客户端-服务端架构的双组件模式,其中每个组件都独立运行。它与简单的客户端-服务端架构的不同点在于,这里的两个组件部署在同一台主机上,面向 localhost 通信。
组件 Micrologic,包含了几乎所有分布式系统关注的最基本的业务逻辑
组件 Mecha,提供了分布式系统的功能
Micrologic 与 Mecha 可以是一对一的部署,也可以是多个 Micrologic 共享一个 Mecha 部署
3.3.2、机甲模式特点
Micrologic 组件本身不是微服务,它包含微服务的业务逻辑,并且只能跟 Mecha 组件配合一起使用,形成一个微服务
Micrologic 组件通过一些预定义的 API 与 Mecha 进行通信,Mecha 与外部系统进行通信
Mecha 组件是通用的、可配置的、可重复使用的组件
Mecha 组件适用于多语言微服务
Mecha 组件与多个代理不同,而是通过内部插件或者外部服务支持,作为一个整体提供一套能力
Mecha 组件通过简单文本声明方式配置,确定启用哪些功能及与 Micrologic 的绑定方式
所以说,机甲模式(Mecha)其实是对 Service Mesh 接下来发展的一种预测,未来的微服务部署模式,可以像电影中,人类穿上不同的机甲进行战斗一样。通过 Micrologic 与 Mecha 的组合,实现一个真正的微服务。
比较形象的描述,程序可以像钢铁侠的战甲一样,按需装配。如下图:
3.4、问题解决案例及思考
3.4.1、案例一:本地开发环境遇到的服务调用问题
在一个调用关系复杂的微服务项目中,单次请求的处理,调用到微服务中多个模块,业务层面拆分粒度比较细的情况下,对于处在开发阶段的研发人员来说,则会很费力。服务发现、负载均衡没有做好,完成一次调试,本地可能需要启用多个服务。
为了专注于当前业务逻辑,总结以下经验:
未迭代的服务依赖 DEV 环境实例
借用 DEV 环境代理网关解决网络访问和请求转发问题
巧用 switch-host 配置 DNS,对不同环境的问题进行本地回放
3.4.2、案例二:插件式开发框架-Spring-brick
在许多 To-B 和 To-G 的项目中,为了应对特殊场景,例如:数据库需要用“指定厂商”的数据库,但是不同的厂商,SQL 的方言有所不同,所以同一个产品需要支持灵活切换数据库。如果可以将持久层以插件形式集成到项目中,实施的成本可以大大降低。
Spring-brick 框架就是一个很不错的实践产物,它可以解决如下痛点:
在 To-B 系统场景中,不同甲方会有不同的需求,在不打分支和改动系统核心代码的前提下,可以在插件中进行扩展开发特定功能,不同甲方使用不同插件,完美解决非核心系统的扩展功能开发,例如扩展中台系统的不同需求。
在 To-C 系统场景中,可以在主程序通过定义 java-interface,在插件中做不同实现,来达到动态扩展系统功能。
在开发中,由于引入了不同版本的依赖,导致系统无法运行,本框架可以完美解决在不同插件中定义不同版本的依赖,从底层进行隔离,以解决引入不同版本依赖冲突的问题。比如可以解决同一个程序同时连接 mysql-5 和 mysql-8 版本数据库。
在开发中,不同插件依赖不同框架的功能,可以按需引入。比如在插件 A 引入连接 mysql、在插件 B 引入连接 elasticsearch、在插件 C 引入连接 oracle。
在插件中,可以任意集成不同的非 web 类型的 springboot-xx-starter,然后将不同插件功能组装起来,以达到一个统一对外提供服务的完整系统,实现系统组装化、插拔化开发。
在不重启主程序的前提下,对插件进行动态的安装、卸载、启动、停止。
3.4.3、思考
Service Mesh 的落地,离不开容器(Docker)和容器编排(Kunbernetes)支持,对团队组织能力和运维能力有很高的要求,开发负责人需要根据自身情况,选择适用自己的方案。例如,小规模软件的服务“硬拆”为微服务,反而会导致新架构与组织能力的不匹配,让架构升级得不到技术红利。
从分布式的发展来看,进化点:
生命周期的自动化、高度的可运维
业务逻辑与分布式系统问题之间的耦合性越来越低,业务模块中集成的 SDK 越来越薄
业务层与基础能力层之间在 localhost 层面交互,甚至在同一个进程内部实现热加载、卸载
基础层能力的复用性走高,平均成本走低
对于一些正在做数字化转型的传统企业,有自己的机房,但是又缺乏组织和运维能力,Service Mesh 甚至基本的微服务架构的落地都会比较困难。特别对于一些有沉重历史包袱的项目,采用插件式的开发框架,也是一种提升交付能力的方式。
技术演进的速度永远比开发者学习的速度快,但是演进的方向和思想,是开发者所必须要了解的。
参考资料:
Multi-Runtime Microservices Architecture (infoq.com)
评论