唯品会的Service Mesh三年进化史

每种架构风格,都会因各公司面临的情况不同而有不同的实现路线,Service Mesh也不例外,比如江南白衣描述的唯品会的服务化体系开放服务平台OSP(Open Service Platform)走的ServiceMesh之路就与流行的Istio不同。但它们要解决的核心问题是相似的,比如服务的注册发现、路由、熔断等如何实现,如何高效的传输与序列化、代理,甚至包括如何更方便的对原有的系统升级改造等。


一、标准服务化体系阶段

如果用两根手指将Local Proxy 和 Remote Proxy的框框按住,就是个标准的服务化框架。

传输与序列化层

当时还没有GRPC,自己拿Netty撸了一个TCP长连接,多路复用,异步IO的传输层,基于Thrift协议的序列化。

当然,这个组合从性能上现在看也不过时,自定义TCP不比HTTP2弱, Thrift 也比ProtocolBuffer略快,我们还支持基于Java类来定义Thrift接口,而不是原生Thrift,PB的有额外学习成本的中立语言,完美。

缺点嘛,就是跨语言时会略尴尬,虽然原生的Thrift也在某种程度上跨语言,但我们除了保留Thrift序列化协议外,其他从头到脚都重新实现了,也就不再能从它那借力。

服务注册中心

当时的大环境下,ZooKeeper也是比较流行的注册中心选择,不过最近在做去ZK化,改为自研的Http Api Server,数据用Redis或 Etcd存储。

API网关

当然要有入口网关,将外网的HTTP请求,经过认证,安全防刷, 再转换为OSP调用后端服务。

服务路由

服务的注册发现,负载均衡,路由定制,机房策略等路由策略,超时,重试,熔断等可用性策略,我们统称为路由逻辑。

我司的主力语言,前端是PHP 和 Java,后端是Java,在调用端有着硬性的跨语言需求。

SM第一步

上述的路由逻辑,如果在每种语言实现一次客户端,显然是不合算的。为了PHP,将这些逻辑抽取成独立的Proxy。

SM第二步

这个独立的Proxy,是部署成传统的集中式的Proxy集群,还是当时还不很著名的本地SideCar模式呢?

在公司的体量下,有着强烈的去中心化的愿望,所以我们选了SideCar模式。

SM第三步

PHP使用了Proxy,那Java呢,继续像dubbo一样在客户端里可以吗?

这个当时有比较大的争议,因为毕竟多经过了一层节点,虽然本地连接不经过网络,也很难说性能毫无影响。 为此我们还专门做了个基于Unix Domain Socket的版本,但后来觉得性能足够,一直没上线。

最后,老板力排众议,一是为了架构统一性,二是因为我们的Proxy功能还不成熟,而使用它的应用又特别多,如果不独立出来,很难推动快速升级。所以统一使用了Proxy模式。

SM第四步

SideCar模式虽好,但是存在单点的问题,如果SideCar在升级,或者挂掉了怎么办?

SideCar升级,可以联动同一台机上的应用先摘除流量。
SideCar挂掉,可以搞个脚本把它自动重新拉起。但重新拉起的间隔里还是会丢失的请求,如果重新拉起还是失败呢?

作为一个架构师,高可用的观念是深入到骨子里的,所以我们又在每个机房搭建了一个Remote Proxy集群,并在客户端里的SDK加入了如下的逻辑:

“如果本地Proxy不可用或宣称自己准备关闭,就将请求无损转发到Remote Proxy,再启动一个监视器观察本地Proxy什么时候重新可用。”

至此,一个封闭的服务化框架完备了,我们有了标准的服务化体系。能力上,也比当时久不更新的Dubbo,还有后来的Netflix,SpringCloud要强不少。

二,按不住的多语言的客户端接入

时间匆匆过, 一个公司里,总是按不住会有更多的语言出现,比如Node.js, C++, Go,像前面说的,再撸一次TCP/Thrift 感觉有点累了,这些也不是主流语言,花太多时间在上面不值得。 所以,我们在Proxy上额外支持了HTTP/JSON的传输层,再根据注册中心里的元数据,重新序列化成Thrift来调用后端服务就好了。

我们还发现,在PHP里用Thrift,还不如它内置的C写的HTTP/JSON库快。

不过,我们也不想在这些客户端再实现一次本地SideCar与Remote Proxy的切换逻辑了,反正这些非主流语言的客户端的调用量不会很大,就通通去调用Remote Proxy集群好了。哪天撑不住时,可能会改用前面说的不那么完美的方案。

至此,多语言的客户端完全咩有接入限制了。

三, 普通Web应用也想零成本变身服务化

时间又匆匆过,又有大量原来的Web应用,不想改造成OSP应用,又想作为一个服务,或者接入API网关,或者加入服务化大家庭,享受各种服务治理的能力。

为此,我们开发了一个很轻量的注册器,也是以sidecar的形式运行,不断的对Web应用的做健康检查,与注册中心进行注册,心跳,和反注册。

当然,免费的午餐肯定没那么好吃,比如没有了基于IDL生成SDK的与客户端的契约化编程,没有了高效的传输层序列化层,没有了限流,自动隔离线程池,ClassLoader预热,闲时主动GC等等细微的Runtime加强。

至此,多语言的服务端也完全咩有问题了。

四、容器化了,容器化了

为了容器化,sidecar跑在哪里,又成了问题。 如果跑在每一个Pod里,一来呢,身为Java应用,堆内堆外内存吃得有点多;二来呢,升级Proxy时,又要重新发布每一个应用;

所以,我们选择了DaemonSet的形式,每台宿主机上只运行一个Proxy,Proxy启动时把自己的IP写在一个共享文件里,这个文件也Mount进各个容器里面,各个客户端会监听这个文件。

为了隔离性,Proxy加了个来源IP的限流,效果就是单个容器的调用高于2万QPS时,第二万零一个请求开始就把它临时重定向到Remote Proxy集群。 十秒钟后再重试本地Proxy,如果还是高,又继续打发过去。

另一个改动,我们之前基于IP来定义路由规则( 比如把一些消耗较大的接口,都发送到隔离的三台机器上)。容器里IP不固定了怎么办?

我们引入了一个部署池的概念,比如一个应用有两个部署池,一个3台机器,另一个20台机器,这个部署池的名字,会注册为服务实例的元信息。在服务路由里就用这个池的名字来定义规则。

Istio 的区别

1. Server端无入口Agent

Server端前面也摆一个Agent,全部流量都流经它,有点重啊。当初在Client前摆一个Agent都争半天了,真的要再来一个?

如果已经是OSP应用,当然没必要摆这个Agent了。如果是一个希望零成本变身的Web应用,那我们回顾一下服务端要做的事情:

一是服务注册和心跳。 我们在应用旁边摆了个轻量级的注册与心跳器来实现。

二是分布式调用链记录。分布式调用链监控原本就支持Web应用呀,不需要额外的Agent。

三是服务端授权,服务端限流之类必须在服务端进行的服务治理,相对没那么重要与常用,真的需要要时同样以Servlet WebFilter 或多语言SDK包方式提供。

所以,这个偏重的Agent暂时没有太大必要。

2. Client端不基于IPTable劫持

为了客户端零改造成本,Istio里基于IPTable,将Client发出的所有请求劫持到Proxy上。但IPTable的性能一般,尤其是一个环境里有很多应用时,性能更加跌得很厉害。所以我们就不节约客户端的一点点改造成本了。

基于SDK的访问,支持Local Proxy与Remote Proxy的完美切换,比IPTable更加的高可用。而如果某种语不想写这种复杂SDK,那要么全部打到本地Proxy(等于IPTable),要么全部直接访问 Remote Proxy集群。

3. 没有画大饼用的Mixer

为了Proxy实现的可替换性,Istio里将与基础设施相关的部分都提取到中央的Mixer里,连分布式调用链跟踪都分离出来太那啥了,每个请求发生前发生后都可能要调用一下这个Mixer,一个是性能,一个是中央化的容量瓶颈。

虽然理解Google架构师们为了画大饼的无奈,但自用体系,不需要考虑Proxy的可替换性时,还是把该下沉到Proxy的基础设施埋点给下沉下去。

4. SideCar以DaemonSet形式运行

因为是Java,堆内堆外要3G左右,所以每台宿主机只运行一个Proxy。 当然也为了升级Proxy方便,不用每次升级Proxy将全部应用的容器重新发布一遍。

5. 不依赖K8S和容器技术

这么一路走来,当然不会依赖于K8S。目前Istio们为了节约开发精力而完全依赖K8S,其实也大大局限了它们的适用范围,起码一个公司里如果混合物理机与容器双向调用的就难搞了。

6. 路由和路由是不一样的,熔断和熔断是不一样的

一个词能涵盖完全不同级别的实现。大家都说路由,但我觉得比如Dubbo,比如OSP,才算是真正的规则路由。

其他负载均衡,熔断,重试等等,都一个名字也可以做得差别极大。

http://calvin1978.blogcn.com/?p=1779

原文地址:https://www.cnblogs.com/doit8791/p/10015266.html

时间: 2024-08-30 12:20:44

唯品会的Service Mesh三年进化史的相关文章

什么是 Service Mesh

作者|敖小剑 微服务方兴未艾如火如荼之际,在 spring cloud 等经典框架之外,Service Mesh 技术正在悄然兴起.到底什么是 Service Mesh,它的出现能带来什么,又能改变什么?本文整理自数人云资深架构师敖小剑在 QCon 2017 上海站上的演讲. 简单回顾一下过去三年微服务的发展历程.在过去三年当中,微服务成为我们的业界技术热点,我们看到大量的互联网公司都在做微服务架构的落地.也有很多传统企业在做互联网技术转型,基本上还是以微服务和容器为核心. 在这个技术转型中,我

【转帖】赤壁之战,曹操大败只因缺了Service Mesh

赤壁之战,曹操大败只因缺了Service Mesh 本文作者把微服务向 Service Mesh 的进化融入到了三国故事中,妙趣横生.故事比较长,大家慢慢看,精彩的在后边. http://developer.51cto.com/art/201907/599484.htm 本文作者把微服务向 Service Mesh 的进化融入到了三国故事中,妙趣横生.故事比较长,大家慢慢看,精彩的在后边. 话说曹操官渡之战大获全胜,收编了袁绍的大批将士和军队,有搞 Python的,有搞 JS 的,有搞 Ruby

Service Mesh对企业安全而言意味着什么?

你听说过Service Mesh(服务网格)吗? 我相信你听说过.Service Mesh正成为容器生态圈愈发重要的一部分. 本文将简要概述Service Mesh的作用,并深入探讨它们对于企业安全性的意义. Service Meshes是什么?它为何如此重要? 连接问题 要想理解Service Mesh的存在原因,首先考虑一下容器环境中的网络连接. 想象一下当你运行一个云原生应用时会发生什么.但凡它具有一定的规模和复杂性,它通常都需要由大量单独的服务组成,这些服务间为了能够像一个单体桌面应用程

什么是Service Mesh?

转至大佬宋净明的博客:https://jimmysong.io/posts/what-is-a-service-mesh/ Service mesh 又译作 "服务网格",作为服务间通信的基础设施层.Buoyant 公司的 CEO Willian Morgan 在他的这篇文章 WHAT'S A SERVICE MESH? AND WHY DO I NEED ONE? 中解释了什么是 Service Mesh,为什么云原生应用需要 Service Mesh. 如 Willian Morg

consul 1.2 支持service mesh

主要说明: This release supports a major new feature called Connect that automatically turns any existing Consul cluster into a service mesh solution. Connect enables secure service-to-service communication with automatic TLS encryption and identity-based

微服务架构下 Service Mesh 会是闪亮的明天吗?

7月7日,时速云企业级容器 PaaS 技术沙龙第 10 期在上海成功举办,时速云容器架构负责人魏巍为大家详细讲解了 Service Mesh 中代表性的实践方案.并以 Istio 为例详细讲解了 Service Mesh 中的技术关键点,包括 Istio 控制平面.Istio 数据平面等.以下内容根据魏巍分享整编,希望对大家了解 Service Mesh 有所帮助. 魏巍:大家下午好,刚才几位讲师讲了 K8S 的存储.PaaS 在企业的落地实践等,我们接下来要讲的是企业有了 PaaS 平台.并且

阿里巴巴中间件团队在 Service Mesh 的实践和探索

摘要: 所有软件最重要的使命不是满足功能要求,而是演进,从而持续成长. 精彩观点导读:? 我们去探索一项技术,并不会仅仅因为其先进性,而是因为我们目前遇到了一些无法解决的问题,而这项技术正好能解决这个问题. ? 所有软件最重要的使命不是满足功能要求,而是演进,从而持续成长. ? 微服务本质是对服务的拆分,微服务架构符合工程领域常用的"分而治之"范式. 近日,在Aliware Open Source?成都站-Apache Dubbo 开发者沙龙上,阿里巴巴中间件高级技术专家李云(至简)向

蚂蚁金服 Service Mesh 实践探索

SOFAMesh是蚂蚁金服在ServiceMesh方向上的探索,下面是它高级技术专家敖小剑在QCon上海2018上的演讲. Service Mesh 是一个 基础设施层,用于处理服务间通讯.现代云原生应用有着复杂的服务拓扑,服务网格负责在这些拓扑中 实现请求的可靠传递. 在实践中,服务网格通常实现为一组 轻量级网络代理,它们与应用程序部署在一起,而 对应用程序透明. 加粗部分是重点: 基础设施层:这是 Service Mesh 的定位,今天内容的最后一个部分我会和大家详细展开这个话题: 服务间通

大家都在说的Service Mesh,你何时需要它?

在对应用程序进行重构和更新的过程中,往往会出现一些挑战.更新应用程序的频率越高,复杂性就越是会增加.让应用程序在容器平台上运行,并且它们之间可以互相通信和连接,是通向模块化的.灵活的微服务架构的必经之路.但是微服务的这种灵活性也让其变得更加复杂.这时就轮到Service Mesh发挥作用了! Service Mesh向企业提供了他们所需要的中心化控制面板,同时依然能够使用灵活的.基于云的应用程序开发方式.我们可以把Service Mesh看成是用于微服务API的专门的第7层网格,它提供身份验证.