Servicemesh 落地实践三年,效果一直并不理想,到了该反思的时候了。Mecha 作为面向服务的分布式能力抽象层,是 Servicemesh 模式的自然进化版本,预计也将是云原生化和 Mesh 化的必然趋势,让我们将 Mesh 进行到底。
Mecha 一词,相信爱好动漫的同学应该都不陌生。是的,就是大家熟悉的那个 Mecha(机甲):
Mecha 这个词之所以出现在这里,主要是因为 Bilgin Ibryam 的这个博客文章 “Multi-Runtime Microservices Architecture”,提出了微服务架构的一个新的设想:Multiple Runtime。
备注:这篇博客文章强烈推荐阅读,我甚至建议在阅读本文之前先阅读这篇文章,因为我今天的内容,可以视为对这个文章的深度解读和思考。为了方便,这里提供一份中文翻译版本 多运行时微服务架构。
在这篇博客中,Bilgin Ibryam 首先分析并总结了分布式应用的四大需求:
由于每种需求存在的问题和局限性,导致传统解决方案如企业服务总线(ESB)及其变体(例如面向消息的中间件,更轻量级的集成框架等)不再适用。随着微服务架构的发展,以及容器和 Kubernetes 的普及和广泛使用,云原生思想开始影响这些需求的实现方式。未来的架构趋势是通过将所有传统的中间件功能移至其他运行时来全面发展,最后的目标是在服务中只需编写业务逻辑。
备注:详情请见原文,为了节约篇幅,这里只做简单概述,不完全引用原文内容。
下图是传统中间件平台和云原生平台的对比,传统中间件以各种 SDK 的方式提供能力,而云原生平台则通过各种外围 Runtime(典型如大家熟悉的 Servicemesh/Istio):
因此作者引入了 Multiple Runtime 的概念:
作者提出:很可能在将来,我们最终将使用多个运行时来实现分布式系统。多个运行时,不是因为有多个微服务,而是因为每个微服务都将由多个运行时组成,最有可能是两个运行时 - 自定义业务逻辑运行时和分布式原语运行时。
对多运行时微服务架构和 Mecha 的说明:
您还记得电影《阿凡达》和科学家们制作的用于去野外探索潘多拉的 Amplified Mobility Platform (AMP)“机车服”吗?这个多运行时架构类似于这些 Mecha- 套装,为类人驾驶员赋予超能力。在电影中,您要穿上套装才能获得力量并获得破坏性武器。在这个软件架构中,您将拥有构成应用核心的业务逻辑(称为微逻辑 /micrologic)和提供强大的开箱即用的分布式原语的 sidecar mecha 组件。Micrologic 与 mecha 功能相结合,形成多运行时微服务,该服务将进程外功能用于其分布式系统需求。最棒的是,Avatar 2 即将面世,以帮助推广这种架构。我们最终可以在所有软件会议上用令人赞叹的机甲图片代替老式的边车摩托车;-)。接下来,让我们看看该软件架构的详细信息。 这是一个类似于客户端 - 服务器体系结构的双组件模型,其中每个组件都是独立的运行时。它与纯客户端 - 服务器架构的不同之处在于,这两个组件都位于同一主机上,彼此之间有可靠的网络连接。这两个组件的重要性相当,它们可以在任一方向上发起操作并充当客户端或服务器。其中的一个组件称为 Micrologic,拥有非常少的业务逻辑,把几乎所有分布式系统问题都剥离出去了。另一个伴随的组件是 Mecha,提供了我们在本文中一直讨论的所有分布式系统功能(生命周期除外,它是平台功能)。
作者在这里正式提出了 Mecha 的理念:
思路大体是:Smart Runtime, Dumb Pipes。
我对 Mecha 的理解是:业务逻辑在编码开始阶段应该是“裸奔”的,专注于业务逻辑的实现,而尽量不涉及到底层实现逻辑;而在运行时,则应该装备“机甲”,全副武装,大杀四方。熟悉的味道是吧?标准而地道的云原生思想。
作者在原文中探讨了 Mecha 运行时的特性:
下面是我对上述特性的个人理解:
如果用一句话来总结,那么我认为 Mecha 的本质应该是:“面向应用的分布式能力抽象层”
如 Servicemesh 的本质是服务间通讯的抽象层一样,Mecha 的本质是应用需要的各种分布式能力和原语,包括但不限于服务间通讯。
从这个角度上说,Mecha 覆盖的范围是 Servicemesh 的超集:毕竟 Servicemesh 只覆盖到应用的部分需求(服务间通讯,还只限于同步 / 一对一 /request-response 模式),还有更多的分布式能力和原语有待覆盖。
换一句话说,Mecha 的目标应该是:“将 Mesh 进行到底!”
作者指出:Mecha 的好处是业务逻辑和越来越多的分布式系统问题之间的松耦合。
下图是业务逻辑和分布式系统问题在不同架构中的耦合:
其实思路和 Servicemesh 是一脉相承的,只是覆盖的分布式能力更广泛一些。
有一个问题:Mecha 会不会成为微服务架构的演进的下一个形态?我个人的答案:是,随着云原生的推进,分布式能力(以传统中间件为典型代表)下沉是大势所趋,Mesh 化的范围必然会继续扩大,也就离 Mecha 的形态越来越近了。这也就是本文标题的立意所在,Mecha 会是微服务乃至云原生的下一站。
在介绍完 Mecha/Multiple Runtime 的理念之后,我们来看看目前微软新推出来的 Dapr 项目 —— 这应该是业界第一个 Multiple Runtime 的开源实践项目。
项目地址:https://github.com/dapr/dapr。
Dapr 是 Distributed Application Runtime (分布式应用运行时)的缩写,官方介绍说 Dapr 是“一种可移植的,事件驱动的运行时,用于构建跨云和边缘的分布式应用”。
Dapr 的详细介绍是:
Dapr 是一种可移植的,serverless 的,事件驱动的运行时,它使开发人员可以轻松构建弹性,无状态和有状态微服务,这些服务运行在云和边缘上,并包含多种语言和开发框架。 Dapr 整理了构建微服务应用为开放,独立的构建块的最佳实践,使您能够使用自己选择的语言和框架来构建可移植的应用程序。每个构建块都是独立的,您可以在应用中使用其中的一个或多个。
Dapr 的功能和定位,下面这一张图就可以概括了:
Dapr 提供的具体分布式能力(building block)如下图所示:
每个 building block 提供的具体能力请参加 Dapr 的官方文档:https://github.com/dapr/docs/tree/master/concepts。
我们来看一下应用调用 Darp API 的例子,体验一下使用 Dapr 的方式。
以 Service Invocation / 服务调用为例:
部署和调用方式与 Servicemesh/Istio 极为相似,但是,差别在于:Dapr 是以提供 API 的方式提供 API 背后的能力,而不是提供提供协议代理的方式。
上图中 1,是 ServiceA 发起请求来调用一个远程服务。其 HTTP request 如下所示:
POST/GET/PUT/DELETE http://localhost:
<daprPort>/v1.0/invoke/<appId>/method/<method-name>
其中:
负载可以存放在 HTTP body 中随请求发送,如 json。
注意,虽然都是提供相同的功能,这里体现了 Dapr(或者说背后的 Mecha)和 Servicemesh 在方式上的差异:暴露 API 还是代理通讯协议。
我们看一个更明显的例子,dapr 提供的 “publish/subscriptions” 能力,让应用可以方便的发布消息,或者订阅主题并接收消息。下图是应用发布消息,请求直接发给 dapr 即可:
例子中,参数 topic 指定了消息要发往的主题(例子中是 deathStarStatus)。后续 dapr 会完成将消息入 queue,然后推送到订阅了该 topic 的应用。接收消息的方式也类似,不过这次是 darp 主动发起:
dapr 首先会请求应用,咨询应用需要订阅那些主题(topic),如例子中应用返回的的 TopicA / TopicB
dapr 实现主题订阅,在接收到消息之后,再把消息发送给应用,通过 URL 参数的不同来区分不同的主题
注意在这个调用期间,无论是收发消息,应用完全不用理会底层 pub/sub 的实现机制(比如是 kafka,还是 rocketmq,还是其他公有云提供的消息机制),也完全不用引入该实现机制的客户端 SDK,只是简单的使用 darp 定义的 API 即可,从而实现了和底层的解耦,以及“厂商不绑定”。
为了进一步简化调用的过程(毕竟发一个最简单的 HTTP GET 请求也要应用实现 HTTP 协议的调用 / 连接池管理等),dapr 提供了各个语言的 SDK,如 java / go / python / dotnet / js / cpp / rust 。另外同时提供 HTTP 客户端和 gRPC 客户端。
我们以 Java 为例,java 的 client API 接口定义如下:
public interface DaprClient {
Mono<Void> publishEvent(String topic, Object event);
Mono<Void> invokeService(Verb verb, String appId, String method, Object request);
......
}
具体可见:
https://github.com/dapr/java-sdk/blob/master/sdk/src/main/java/io/dapr/client/DaprClient.java
前面介绍了 Multiple Runtime / Mecha 的架构思想,以及参考实现之一的微软 Dapr 项目。
由于 Multiple Runtime / Mecha 这个思想非常的新,刚刚提出不久,而微软 Dapr 项目也是一个新出来的项目,不管是理论思想还是实践都处于非常早期的状态,也还没有形成完善的方法论。
特别申明:以下内容更多是我个人当下的理解和感悟,仅代表个人意见,肯定有很多不成熟甚至谬误的地方,欢迎指正和探讨。
Program to an interface , not an implementation. Design Patterns: Elements of Reusable Object-Oriented Software (GOF, 1994)
Mecha 的精髓,要从上面这句名言开始:
个人理解,Mecha 的精髓就在于这几个关键点:隔离 / 抽象 / 解耦 / 可替换。如下图所示:
在 Mecha 的实现上,我理解的原则是这样:
具体的职责划分:
在 Mecha 架构中,Runtime 自然是整个架构的核心,扮演类似 Servicemesh 中数据平面的角色
备注:Mecha 有非常多的能力,实现上也有非常多的细节,这里先做一个 High Level 的概述。细节后面会有一系列文章一一覆盖,欢迎多交流讨论。
大概是在 3 月初,当时我第一次阅读 “Multi-Runtime Microservices Architecture” 这篇文章,有一种豁然开朗的感觉,尤其是有很多之前在反复考虑和权衡但是下不了结论的问题,在这个文章中得到了清晰的解答。可谓受益匪浅。
在 Servicemesh 探索和实践的这三年中,遇到很多问题,有很多之前没有想到过的问题浮现。比如,以前一直觉得 Servicemesh 中引入 Sidecar 带来的最大麻烦会是性能,但实际上,从目前的实践看,Sidecar 引入后带来的维护代价才是更令人头疼的事情,相比之下 Sidecar 引入带来的性能损失显得无伤大雅。
总结一下我个人对 Mecha 架构的核心理解,主要是两点:
正如曾有说法,说“微服务是 SOA 实践中正确的部分(the Good Part)”,我希望在 Mecha 的探索和实践中,能够从 Servicemesh 的实践中吸取成功的经验和失败的教训,希望 Mecha 也能成为 Servicemesh 的 Good Part。希望在云原生的演进路线中,Mecha 可以继微服务和 Servicemesh 之后,成为云原生落地实践的下一站。
回到现实,目前 Mecha 和 Multi-Runtime 还是一个非常新的想法,Dapr 项目也才刚刚起步,Mecha 要探索的道路还很漫长,一切都还需要摸索着前进。
在文章的最后,特别鸣谢 “Multi-Runtime Microservices Architecture”一文的作者 “ Bilgin Ibryam ”,我非常认可这篇文章中的思想和理念,分析归纳的非常到位,提炼和升华的能力令人佩服。
本文参考了 Bilgin Ibryam 出品的如下内容:
作者介绍:
敖小剑,具有十八年软件开发经验,资深码农,微服务专家,Cloud Native 拥护者,敏捷实践者,Service Mesh 布道师,ServiceMesher 中文社区联合创始人。专注于基础架构建设,对微服务、servicemesh,serverless 等云原生相关技术有着深入研究和独到见解。
原文链接:
领取专属 10元无门槛券
私享最新 技术干货