Weibo Mesh的发展

2018-09-21 11:15:38 浏览数 (1)

初代Motan

微博从2013年开发了Java语言的Motan RPC框架,基于此完成了服务化改造。Motan从2013年上线至今经历过每个热点事件,三节高峰的挑战,稳定性和可靠性都得到了实际场景的验证。这些经历之下微博Motan也积累了一套服务治理型RPC的服务化体系。

除了Motan,2015年开始,为了应对越来越猛的流量洪峰,更合理的对资源进行整合利用,开发了Open DCP弹性计算平台。实现了动态的弹性扩缩容,告别了以往花费动辄几千万的资源成本,及节前几个月开始的劳民伤财为三节做准备的日子,也不需要为一个个热点事件提心吊胆。

上面是微博平台技术体系概貌,是一个基于Open DCP弹性云计算平台和Motan RPC的服务化架构,经过几年的运营和考验,我们已经在混合云和服务化方向有了丰富的经验和积累。在解决了微博内部服务高可用,高性能的问题后,业务方平台服务调用的问题开始显现出来。比如调用链路过长,导致坑多性能差,比如每个服务本身需要做高可用和服务治理,这些事情平台已经有了丰富积累,大家在做一遍重复严重且浪费资源。平台希望将平台技术服务到业务方时,需要一个跨语言的解决方案。从2016年起,我们开始了跨语言服务化改造之路。

跨语言RPC要点

异构系统之间如何做到服务化的解决方案呢?

将原有Java体系积累的经验加以总结,给其他技术栈业务赋能,更好的维护微博整体的稳定性和高可用。

上面是跨语言RPC的几个技术要点,最下面是可靠性和易用性,比如我们Motan有Cluster的概念,每次调用都从这个Cluster里面通过负载均衡策略来找出可用节点endpoint,再通过高可用策略完成调用。整个过程各种理念可复用,各种语言按章实现就好。各种策略可以按需根据实际情况进行扩展。而传输,IO,进程线程模型等各种语言不一样,需要根据语言特点来选择实现。

协议和序列化是跨语言比较重要的一点,因为要让不同语言互相理解,互相沟通。

Motan解决的是微博内部Java服务之间的调用,因此Motan1协议时,其实没有考虑到跨语言的问题,用的是对Java友好的Hessian。后期在跨语言方面,Motan1的协议显然对跨语言不友好,Motan2对协议就给了一个足够容易理解的协议,是一个简单的TCP描述。比如,请求一些方法,服务的分组,或者Body,请求发过去,对方收到语言后,怎样让这个语言理解呢?关键一点在于序列化。

现在Motan使用简单序列化方式,只支持几种简单的类型,不过也一直在迭代中。本质上,它仍然是简单协议,会尽量保证它的简单。只有足够的简单,才能在跨语言上降低成本,开发成本还好,主要是语言沟通起来解析成本,比如,编译型语言有各种明确的强类型,而解释型语言不需要强类型约束,如何让他们很好的沟通,就需要取舍。

Weibo Mesh是基于Motan来做的,需要对Motan有个整体的了解。

Weibo Mesh最开始支持Java,现在支持Golang,Openresty,Php。

基于Motan-Go的Weibo-Mesh

我认同Service Mesh是下一代微服务,系统如果很复杂,服务化到一定程度,由于微服务的粒度和规模慢慢增大,出现依赖复杂度增加带来的流量交错,难以管控及难以治理等一系列问题。为了解决这些就需要一个东西很好的管控这些服务和流量,这就是Mesh。

看一看Mesh Istio怎么玩的,Istio有一个基于Envoy的数据传输层,另外是控制面板,Istio通过这个控制面板完成流量调度,鉴权,服务治理等工作。这是Istio现在的玩法。

Weibo Mesh最开始只是想做跨语言,解决调用链路长的问题。之前的请求需要到注册中心寻找目标服务,通过HA做服务路由,绕了一大圈,链路特别长,我们希望跨语言的Motan RPC,Client对Server发起直连,通过点对点的通信来解决链路过长的问题。

最开始做跨语言想GRPC已经做好了,就想通过Motan支持GRPC协议方式来实现Motan实现跨语言调用。 后来改完之后准备对接Php,发现需要大范围的改代码,而且性能没有宣传的那么好。如果通过GRPC做跨语言,服务治理怎么做呢?

以Php为例,每一次请求过来过程就结束了,没有一个常驻内存可用于存储每次请求状态的地方来实现服务发现,服务治理之类的事情。

我们尝试在本机的后台进程做服务发现,或者在Nginx上基于OpenResty的timer来实现服务发现,并发送结果写到Php的$_SERVER变量中,让Php能直接使用等,但效果并不理想。

所以整体用GRPC做跨语言的方案并不理想,后来我们想既然解释型语言的跨语言服务化由于语言本身特性和特殊场景下,不适合直接通过语言本身实现,这样,不如做个代理。这个代理就是Weibo Mesh的雏形,类似于Service Mesh中的SideCar。

比如Java启动一个服务,这种情况下,Java Client访问这个服务是这样的流程:

  • Java Client启动时会根据配置去注册中心订阅自己要访问的服务;
  • 请求过程中会有一个线程不断从注册中心发现当前可用的节点列表回来;
  • 针对于Php就给它一个Go Agent,服务发现,订阅,治理这些事情就让Motan Go Agent来做,其他都一样。

如果Php要做Server呢?

Php要做Server,我们使用Motan Go Agent来帮助Php的服务导出,所以Motan Go Agent既要做服务发现,也要负责Php服务的注册,Motan Go Agent更像一个Motan Server。 启动时需要导出Php的服务,并保持注册中心状态的上报更新。同时需要把请求转发给后段Php做处理,他们之间可能基于CGI或是Http协议完成。

这样我们需要的服务治理方式,高可用等保障,通过逻辑封装实现起来就容易多了。

针对于Java,Golang这种方便实现服务化的语言,用Motan实现,其他的语言通过Motan Go导出服务。

改造后性能符合预期,规模大了之后,节点多了之后,通过扩展注册中心功能来解决。

Istio中通过一些请求的Header数据,通过一些规则基于Iptables的流量转发,而Weibo Mesh不需要转发,因为服务都是通过发现回来的,调用时明确的,不需要转发,同时为了流量更均匀,更好的控制流量,需要一个自动流量调度和弹性扩容。

Weibo Mesh改造收益

未来的架构

在Service Mesh中没有了Client和Server的概念,都是Service。

0 人点赞