Service Mesh 是近两年比较火的微服务化新方式,也产生了一大批以 Istio 为表明的 Service Mesh 实现。php
微博基于实际业务需求,打造并开源了本身的 Weibo Mesh,而且内部已经在重点业务上进行大规模落地。网络
本文将从以下几个部分为你们详细解读 Weibo Mesh,但愿能够为你们带来服务化方向上的一些灵感,更好的服务于本身的业务:架构
微博服务化挑战负载均衡
服务化新思路框架
Weibo Mesh 方案介绍运维
生产实践ide
总结模块化
微博服务化挑战函数
首先,为你们介绍下微博服务化面临的挑战。微博的形态比较特殊,除去常态午/晚高峰流量较高外,突发热点事件的杀伤力更大。微服务
热点事件来袭时,流量极短期内呈现爆炸式增加,而且每每事件爆发没有任何征兆。这对于微博服务化及稳定性均带来了极大挑战。
若是其中某一个环节掉链子,不能及时感知并做出应对,极有可能会致使雪崩式宕机,致使全站挂掉。
那么怎么解决这种问题呢?首先会想到自动扩缩容/降级建设,可是咱们决策依赖是什么呢?又如何知足系统可观测性要求,以及如何评价系统可用性及冗余度呢?
究其本质,系统的服务治理建设很是重要,它会直接影响到服务可用性。可是微博技术栈的多样性又致使了在微服务化和服务治理方面困难重重。
从技术层面看,微博的典型服务调用大体如上图,业务体系会调用平台体系的多个接口,例如经过平台接口获取微博内容。
平台体系主要是 Java 技术栈,原本微服务相关解决方案也多,再加上服务化时间较早,平台微服务体系建设相对比较完善,同时也产出了一些优秀开源框架,好比 Motan 微服务框架。
业务方的语言栈:多样化,基本涵盖了全部主流语言,其中 PHP 相关系统流量占比较大。
调用链路:一般状况下业务方和平台使用 RestFul API 进行交互。一次请求调用要通过 4,7 层的层层调度,服务稳定性还时常遭受网络抖动及 DNS 不稳定的困扰,在中间层的消耗是不容忽视的。
另外,业务部门的语言种类繁多,间接致使了各部门微服务体系建设良莠不齐。
峰值流量应对须要全部部门全部业务模块的通力协助和联动,考验的是整站实力,咱们须要全部模块都能具有高水平的服务治理能力。所以咱们迫切须要解决跨语言微服务化问题。
上图是微博平台内部的微服务体系支撑图,平台实现以 Motan 框架为核心的微服务治理体系 。
此外,还有自研的 Vintage 注册中心及 Open DCP 智能弹性调度平台以及 Graphite 实时监控平台,能够看出平台微服务架构有完善的 DevOps 支撑。
业界的大趋势是云原生,微服务做为云原生重要的一环,是咱们必需要突破的。
微博服务化新思路
跨语言服务治理尝试
为了解决跨语言服务治理的问题,我简单介绍一下咱们尝试过哪些解决方案。
这里有个大背景,Motan 因为是微博内部使用已久,经历太重大考验而且开源的优秀框架,它积累了不少优秀的服务治理经验,因此咱们服务化改造要充分考虑 Motan 的存在。
咱们尝试将 Motan 适配 Yar 这种 PHP 的 RPC 协议,PHP 能够与 Server 端的 Java 进行通信,但 PHP 并不能进行服务发现。
因而咱们在 PHP 旁边加一个 Daemon 程序,也考虑过使用 Nginx,来作服务发现。
固然问题也是显而易见的,这样改造会致使业务侵入变高,成本变大,扩展性也较差,况且并无解决 PHP 作 Server 端的服务治理问题。
咱们也尝试过 GRPC,固然跨语言调用能解决,可是这里遇到几个问题,一个是如何进行服务治理,另一个是 PB 序列化问题。
因为微博场景的内容结构体很是大,效率并不比 Json 高,业务变动致使 PB 文件的变动让升级维护成本变得难以接受,另外序列化数据遇到问题调试也变的困难。
此外 ,技术栈的多样性也会引起一系列的问题。即便咱们解决了 PHP 到 Java 的调用问题。可是相同的治理功能,不一样的语言不可能再实现一遍。
Motan 框架积累下来的服务治理经验是咱们须要传承和发扬的,那如何均衡这些问题及解决方案呢?
跨语言服务化本质
我认为跨语言服务化的本质,总结下来有两点:
数据交互
服务治理
数据交互设计要考虑跨语言及协议中立,服务治理设计要灵活全面且可扩展。
上图我列举了跨语言服务化方式的优缺点:
传统的 HTTP 代理,能够解决不一样服务之间的调用。HTTP 就是传统的走网关,较容易实现,但由于内部的调用每一个人都要加网关,这就增长了链路,致使扩展能力低。
RPC 模块或者 Agent 代理。RPC 框架业界有不少,大多 Java 栈的,功能也齐全,但跨语言维护成本很是之高。
Agent 代理是一个新的思路,Agent 代理的研发成本、维护成本、使用成本对比起来均比较折中,即咱们独立一个 Agent 来专门解决咱们遇到的跨语言服务化困扰。
那样既能释放传统的业务端的服务治理压力,又能传承 Motan 框架的精髓,也不须要实现多语言服务治理逻辑,更可让业务和 Agent 互相独立发展,可谓一举多得。
这个思路最终也演化成了今天的 Weibo Mesh:
由此微博走向了 Service Mesh。微博走向 Service Mesh,并非盲目追赶最新的技术潮流。
咱们立足于现状,立足于解决实际业务问题,并一步步探索事后,发现最终的解决方案与 Service Mesh 思路不谋而合。从侧面也验证了 Service Mesh 思路解决服务化问题的合理性和前瞻性。
上图,咱们能够用正交分解法来理解 Service Mesh,能够看到,原有的微服务被拆分红业务逻辑层和服务交互治理层,其中服务交互治理层抽象为 Service Mesh。
Service Mesh 把服务间的交互与治理逻辑从业务中进行解耦,抽象独立成一个专门的处理模块。
一般 Mesh Agent 以 Sidecar 的形式和业务进行本机部署,Agent(如下 Mesh Agent 简称 Mesh 或 Agent)能够理解为服务的基础设施层,业务无需关心服务间交互/治理细节,所有交由 Agent 统一处理。
Service Mesh 带来的是微服务架构思路的转变,为业务开发带来了诸多架构上的优点,Agent 及业务都可独立发展,一般 Agent 交由运维管理,业务开发交由业务线,故总体能够作到持续开发、持续集成。
Mesh 思路不光能够解决跨语言服务化的问题,也能够解决资源服务化问题,而这些改造基本都对业务方透明。
Weibo Mesh 方案介绍
下面具体介绍下 Weibo Mesh 的实现方案。上图是 Weibo Mesh 架构图,除了必须的 Mesh Agent 外,考虑到业务迁移及实际落地须要,这里在业务代码和 Mesh 之间增长了 Client。
这个 Client 很是轻,其核心功能是封装 Mesh 请求,方便业务进行 Mesh 调用,最大限度下降业务迁移成本。
实际上在 Client 中咱们也实现了其余一些对业务友好的功能,同时对 Mesh 调用进行了功能加强。
好比能够在 Client 中进行跨语言的序列化,Mesh 故障转移,请求多发,超时控制等。
固然不一样业务方能够进行功能定制。Client 和业务相同的语言编写,其核心目的是帮助业务进行平滑迁移。
Mesh 层实现了 Service Mesh 的核心功能,包括发现、交互、路由、治理。
Weibo Mesh 是由 Go 实现的,国内各大厂商的 Mesh 数据平面也大多使用 Go 来实现。
Go 具备优秀的性能及易用性,又是云时代比较推崇的语言,将来 Mesh 层极有可能结合容器,沉淀成为容器的一个基础设施层。
Weibo Mesh 数据面
剖析一个 Service Mesh 服务,通常经过数据面和控制面。首先来看一下 Weibo Mesh 在数据平面的表现,包含五个核心模块:
Cluster(集群管理),对分组下经过服务发现回来的的节点列表的抽象管理。
HA(高可用策略)、LB(负载均衡)。
Endpoint(服务节点的抽象),本质上是 IP 和端口,但从代码层面看,它是服务节点的抽象,经过 Endpoint 能够进行直接的调用,能够理解为它是调用的一个单元。
Protocol(Motan2/传输协议+Simple/序列化协议)。
下面一一介绍这些模块。
①Cluster 模块
调用方请求经过本机的 Mesh,在 Cluster 模块处理中,首先通过一系列集群粒度的 Filter Chain(过滤链,包含集群 Metric,熔断,拦截,鉴权,分组切换等功能,它们以链式结构进行组织调用,支持任意过滤功能扩展)。
而后再通过高可用策略跟负载均衡策略筛选出一个可用的 Endpoint,在 Endpoint 中又会进行请求粒度的 Filter Chain(单机的日志记录,Metric 等),经过进行请求序列化,根据传输协议进行组装,最终经过 Endpoint 把请求发到对端的 Mesh 上。
②高可用策略
Weibo Mesh 中的高可用策略,支持通常的经常使用策略,好比 Failfast,Failover 等,负载均衡支持权重轮巡,根据权重轮巡、随机等经常使用策略。固然也能够定制本身的 HA/LB 策略。
Weibo Mesh 中推荐采用的高可用策略是 Backup Request,又叫双发。双发继承自 Motan 框架,是咱们探索出来的比较高效可靠的机制。它能够有效解决长尾问题,同时能提高系统吞吐量。
传统解决接口超时问题可能经过重试,在一次请求发送以后等待指定的超时时间,若是没有返回则再请求一次,最差状况下要消耗 2 倍的超时时间。
而双发机制则否则,在发送一次请求后等待 P90(在 T1 时间内有 90% 的请求都能返回则称 P90=T1,一般系统的 P90 和程序设置的超时时间相比小不少)时间。
若是请求没有返回则在此刻再次发送一次请求,在超时时间内,这两个请求中取最快返回的那个。
固然,这里有个防雪崩机制,假如,超过必定数量的请求(好比 15%)都在进行双发,则认为服务总体有问题,会自动中止双发。实践证实,双发机制的去长尾效果很是明显。
③节点抽象
Endpoint 是调用方 Mesh 到对端 Mesh 的调用单元。当咱们启动 Weibo Mesh,在初始化 Cluster 的同时,也会对 Endpoint 进行初始化,绑定 Filter Chain,并为每一个 Endpoint 保持必定数量的长连接供选择调用。
固然这里还会有一些细节,若是某个节点的调用失败,计数超过必定阈值则自动摘除节点,并进行按期探测等待可用,再从新加入可用节点列表。
④Motan2 传输协议
Weibo Mesh 总体沿用了 Motan 的协议设计,并进行了升级。
Motan 支持 Java 的序列化,当时考虑的是 Java 间相互通讯,可是考虑到跨语言通讯及将来扩展须要,咱们把协议设计分红序列化协议与传输协议。传输协议负责把序列化后的数据进行传输,序列化协议是跨语言的关键。
Motan 传输协议是典型的三段式:
Header
Metadata
Body
Header 中会标记序列化类型,消息类型(心跳仍是正常请求),能够定义本身的 PB 序列化或是自研的 Simple 序列化。
在 Metadata 中会有一些方法名、属性名、用户参数;在 Body 中存放的是通过序列化后的请求/响应体。
Simple 序列化:Simple 设计比较简单实用。目前 Simple 序列化支持了基础类型,包括 Bool、String、Int、Float,固然它还会支持一些组合类型,例如 String、Bool 组合成的 Map,Array 等。
上图示例,type 是一个字节的数据类型,好比 Bool、String,接下来是字节长度,接下来是 UTF-8 字节流。Content 中能够进行嵌套,下方就是进行嵌套的例子。
协议转换过程:从协议层面看 Weibo Mesh 请求流转是调用方经过函数调用 Client,而后通过 Motan2 传输协议以及 Simple 序列化后,通过本机 Mesh,Mesh 层再转发给对端的 Mesh。
对端 Mesh 上层多是任意一种形式的服务,好比非 RPC 服务,因此这里咱们有个 Provider 模块,能够代理 HTTP/CGI 等非标准 Service Mesh 服务,它能把这些服务导出成一个具备 Motan 协议的 RPC 服务。
经过 Provider 屏蔽了 Server 端服务的真实协议。Provider 外面是标准的 Motan 协议服务,内部是原有协议的服务,这样对 Server 端来讲,迁移到 Weibo Mesh 成本极低。
Weibo Mesh 控制面
控制面主要分两方面:
①策略扩展
Cluster 和 Endpoint 都有相应的 Filter Chain,他们实现了不一样纬度或者粒度的调用控制策略。
Filter Chain 包括访问日志记录、Metric、熔断、限流、降级等。折中调用效率和耦合程度,它们都是以插件形式存在于 Weibo Mesh 中,也能够自由定制 Filter 策略及调用顺序。
②流量调度
Weibo Mesh 的流量调度基于注册中心。注册中心不只为 Mesh 提供了服务的注册和发现,也提供了服务的配置下发,Mesh 在订阅注册中心的同时,也须要订阅相关的配置项。
好比咱们把 A 机房的流量都路由到 B 机房去,咱们在 Mesh 只要支持这条指令就能够。
生产实践
典型场景
上图是网关,Mesh 在微服务架构中的总体分布图。通常状况下网关架设在服务边缘,边缘节点主要把控宏观的流量调度控制问题。
在内部,各微服务之间构建 Weibo Mesh,来有效提升服务间通讯质量、可观测性等要求。
迁移成本的考量:
真正将 Service Mesh 引入到业务场景中时,须要考虑一些问题点,好比业务部署模式是非云,混合云仍是云原生?像微博是混合云,场景不一样,所以架构也不尽相同。
Weibo Mesh 要适配注册中心。
各语言要适配 Client,目前已经支持 PHP/C++/C/Python/Lua 等主流语言,Java/Go 原生支持。
要适配相应的 DevOps 建设。须要相应的监控/统计等平台支撑,任何架构改造都要有足够的 DevOps 支撑。
接下来为你们介绍 Weibo Mesh 正反向代理实践。
正向 Mesh
上图是 Weibo Mesh 场景下的正向代理流程。Server 端服务进行注册,被调用方订阅到,调用方请求通过 Client,再通过本机 Mesh,最终到对端的 Mesh。须要注意的是虚线部分是故障转移的流程。
假如本机 Mesh Agent 挂掉,Client 会经过服务发现回来的节点快照选择可用节点进行调用,达到故障转移的目的。
反向 Mesh
上图是 Weibo Mesh 场景下的反向代理流程。通常咱们的服务类型是 HTTP/CGI,或者其余私有协议。
反向 Mesh 的亮点在于,不须要 Server 端作任何架构的改造,直接架 Weibo Mesh 就能够了。
Mesh Agent 经过 Provider,将原有协议导出成 Motan2 协议的服务对外进行暴露,只须要把导出的服务注册到注册中心便可提供服务。
同时也不会影响原有服务的提供。这里若是你须要把私有协议导出成 Motan2 协议服务,能够自行扩展开发。默认支持 http/php-cgi 服务的导出。
反向 Mesh 特点:
提供 HTTP/cgi provider,可定制扩展。
HTTP 框架自动转 RPC,业务无需开发新 RPC 框架。
Mesh 对 Server 改造无侵入。
总结
治理模式的差别
传统服务调用,中间可能通过网关或者 RPC。服务治理只能存在于一端,通常在 Server 端进行服务治理。
可是 Mesh 服务,因为 Agent 本机部署,封装了服务治理,能够实现 Client 端或 Server 端的双向治理,这是 Mesh 服务的一大特点。
Weibo Mesh 优点
实战效果以下图:
上图能够看到,Mesh 服务的 Client 端 RT 曲线逼近 Server 端的 RT,这说明点对点的 Mesh 调用,因为没有中间层的损耗,再加上合适服务治理手段,两端性能也比较接近。而 HTTP 服务则有较多的中间层损耗。
右图能够看到双发的 p999 曲线相对比较直,这说明双发起到有效削长尾功能,间接也对系统性能有提高。
Weibo Mesh 集群
目前,微博内几个核心业务之间调用已经 Mesh 化,并经历太重大事件以及春晚的考验,支撑流量仍是至关大的。
和 Istio 的区别
从控制层面看,Weibo Mesh 把相似 Istio 中的 Mixer 和 CA 的功能以插件化的形式放到 Filters 里面。
Istio 服务须要经过 Pilot 来作服务发现,而 Weibo Mesh 是直接经过注册中心,Istio 用 Envoy 作 Sidecar,而咱们基于 Motan 打造了全新的 Agent。
Istio 有一个特点,上面每一个模块均可以理解为一个微服务,均可独立拆分部署。
可是 Weibo Mesh 为了效率和内部落地的方便,更多的进行了插件式耦合,总体性能相比 Istio 也会更好。
上图能够看到 Istio 经过云平台适配各类 API,来进行服务发现,Weibo Mesh 则是适配注册中心。
Istio 更强调依据容器层面的发现(直奔云原生),Weibo Mesh 则可支持通用注册中心好比 Consul、ZK 等。
Weibo Mesh 经过 Client 拦截 Mesh 请求,模块化耦合部分功能。高定制化时,并不能对服务作到彻底透明。而 Istio 经过 IPtables 流量拦截实现了业务彻底无感知。
WM 进行中
咱们知道 Mesh Agent 并不关心代理转发的是什么服务,因此就有一个新方向,即资源服务化,让资源存储层也能进行服务化。
Weibo Mesh 解决跨语言服务化的思路也一样适用于服务与资源之间的调用问题。微博服务有不少资源依赖,MC、Redis、MySQL、MCQ 等。
咱们能够在资源层架设 Agent,一样能够达到资源即服务,也就是泛服务化。目前咱们内部也已经有基于 Weibo Mesh 的资源服务化使用场景。
WM 将来发展方向
将来 Weibo Mesh 主要有两个方向,一个是继续推动云原生,一个是在易用性方面继续打磨。
Weibo Mesh 打通云平台和注册中心推动云原生,结合容器编排在服务治理上进行优点互补。
此外,咱们也会积极努力推动,让 Mesh 整合进 L5 这一层。咱们还会继续进行探索解决业务方接入不方便的地方,好比说更加方便的流量拦截方式;更普遍的语言支持…
Weibo Mesh 始终推崇落地简单、功能高效可靠,随着 Mesh 更大规模的推广,场景愈来愈极端,性能要求愈来愈高,咱们在这方面也会持续打磨。欢迎你们一块儿加入 Weibo Mesh!