20世纪90年代中期开始,分布式架构开始流行起来,面向服务的架构(SOA)越来越占主导地位。在21世纪初,微服务开始出现,一系列基于微服务架构的框架涌现,而近日,为构建微服务开源生态, TARS项目也将成立基金会。本文邀请腾讯云高级工程师田甜老师带大家了解开源微服务框架现状,详细阐述TARS、gRPC、以及腾讯云Service Mesh的不同优势和特点,希望能与大家一同交流~
引言
目前开源界的微服务框架大体可以分为以下四个种类。
第一类是无服务治理的,这一类基本可以看做是一个RPC框架。RPC发展到现在已经有几十年的时间了,主要代表为gRPC、BRPC、Thrift,它们也都有对外开源的代码。
第二类是带治理功能,但是语言比较单一,主要的代表是以Java为主的Spring Cloud、dubbo等。
第三类就是Service Mesh,主要代表产品是Linkerd和ISTIO,这是未来的发展方向。
最后就是TARS,不仅支持多语言,还附带一些服务治理相关的功能产品。
一、TARS 架构体系
1. TARS简介
TARS是腾讯从2008年到今天一直在使用的后台逻辑层的统一应用框架TAF(Total Application Framework),目前支持C++、Java、PHP、Nodejs、Go语言。该框架为用户提供了涉及到开发、运维、以及测试的一整套解决方案,帮助一个产品或者服务快速实现开发、部署、测试,以及上线。
它集可扩展协议编解码、高性能RPC通信框架、名字路由与发现、发布监控、日志统计、配置管理等于一体。通过它可以快速用微服务的方式构建自己的稳定可靠的分布式应用,并实现完整有效的服务治理。
2. TARS整体架构
TARS的架构如下图所示:
Devops相关方面,主要有代码管理、代码编译和自动化测试等等,底层还有OSS的服务治理。支持协议方面,主要基于自身的TARS协议,另外一些其他自定义的协议也可以支持。服务治理的功能较为丰富,包括大家常用的服务注册、负载均衡、熔断、服务配置等等,这些都是在我们线上做分布式服务管理的时候要做的。
TARS支持五大编程语言,其中包括C++和JAVA、nodejs和PHP和GO,也可以扩展其它语言。
3. 服务治理
对于服务治理,其实最重要就在于客户端和服务端之间的调用。我们的客户端调用服务端是通过registry 来实现的,registry 中文名字叫做主控。客户端在调用的时候会去 registry 做请求,后端有一个 SDK 管理所有的协议,这个 SDK 可以对服务进行监控统计,全部自动完成。
(1) 自动区域感知
调用 logsvr 的时候,用户请求主控拿到节点列表并直连。这里需要指出,基于路由的规则,我们需要把网段注册成一个地区,从而实现自动区域感知。
这是因为在线上业务当中,会出现一些问题。如果一个服务部署到同一地区的不同区域以后,它的跨机房时延在4毫秒左右。如果是跨城市、省份的话可能高达到40毫秒,所以如果我们同机房有部署的话,就会尽量访问自己机房,这样可以提高性能,减少访问耗时。
综上,常规的负载均衡方式面对跨地区或者跨机房部署的服务,会因为网络原因造成延时增大,使用不同服务名来解决该问题时也会带来繁重的运维工作,而通过 Registry 和开发框架配合实现自动区域感知可以自动完成相关的工作。
(2) SET模型
SET模型是腾讯运用比较广泛的体系,因为当容量大到一定程度之后,一个服务发布的过程中也许能影响到全区的服务。例如手机QQ的用户基数上亿,一点微小的变动都会产生深远的影响,因此我们设计了SET模型。
如上图所示,假设该模型有300万的容量。如果单个地区容量过大会导致整个容量过载,所以将它分成三组,6个服务,每个服务自我调用。但是这种服务开发成本相对比较高,如果要再扩增100万容量的话,需要建更多组服务才可以实现。
通过框架处理可以很好解决上述问题,为了以示区别,我们在服务A、B前加上标识Set。通过纵向割裂,将300万以100万/个SET的单位分成3组,每一个SET负责100万的容量,未来业务容量超过了300万接近400万时就只需要加一个SET就可以了。该场景主要是防止故障扩散,如果其中一个场景在迭代的时候出现了问题,只会影响指定SET的100万的用户,不会影响到其他200万的客户。
(3)流量控制
关于流量控制,其实在分布式架构方面也会存在一些问题。比如说,我们经常发布节点,如果按照节点一个一个发布的话,即使服务部署得非常多,但因为流量较大,单个节点存在的用户也会比较多。
这时可以通过权重设置做到无损发布,例如通过权重指定某一个节点的流量只有10%,以此来控制流量。在发布的时候,经常会出现重启导致流量丢失的现象。面对这种情况,我们可以先把流量调为0,发布完成之后,再调回来,这样就可以实现部分按需流量的控制,这也是在大规模线上应用比较常用的解决方案。
(4)分布式跟踪
当有用户反馈说某项服务访问比较慢的时候,我们就需要知道用户相应的用能耗时。这种情况下,如果只是通过相应的数据去排查的话,是比较困难的。
因为在一个微服务下面,一个请求可能会跳多次,所以无法预测到一个服务具体走的跳数,这时候就需要通过分布式跟踪来进行链路追踪。TARS有一套比较完整的体系,从接入到存储都可以自我实现。
(5) 服务配置管理
关于服务配置管理,我们分了四级,分别是应用级配置、SET配置、服务配置和节点配置。
做分布式架构,最难的点就是运维可视化。这样做不仅能让部署和发布更加方便,还能将开发和运维分离,不需要开发接入,一些流程化操作可以寻求外包人员,这样也减轻了人力成本。
TARS的产品应用比较完善,在某些技术上甚至处于领先地位,目前应用在很多大规模应用上也很少出问题。
二、gRPC架构体系
gRPC主体是一个RPC框架,同样也定义了负载均衡策略。
gRPC主要基于Protocol Buffers 框架,Protocol Buffers 是Google出品的序列化的框架,与开发语言和平台都无关,具有良好的可拓展性,可用于数据存储和通讯协议。
gRPC官方介绍虽然简单,但实际在线上应用时需要脚本和参数。所以我们做了一个脚手架,通过这个参数生成代码。因为gRPC线上只提供了标准的接口,并不直接提供代码。很多服务治理的服务,比如日志、ACL这些全都得自己实现。
gRPC可以实现多数语言的代码客户端生成,但是如果想要使用的话还需要做出一些改造,完成相应协议的互转,最后还需要开发常用内部服务SDK来降低使用成本。
服务的实现主要依赖于gRPC拦截器的实现,通过拦截器可以实现远程日志、监控上报、链路追踪等服务。gRPC可以在RPC调用前触发注册的拦截器,在调用前可以执行远程日志上报等等功能,通过多种拦截器串行,实现一个拦截器链路,最终实现各种插件。
关于Protocol Buffers插件系统,它可以做到一些简单的增强。我们在自己的项目中把Protocol Buffers作为一个描述语言,当接口完成时,通过Protocol Buffers的插件功能将开发文档转成swagger,这样的话与前端互通就会变得非常方便,这些代码和文档就可以一下子自动生成。
关于gRPC的周边生态,它主要依赖于Protocol Buffers,拥有庞大的插件集合,可以转换出任何的语言,包含Tars协议。gRPC现在应用的场景也已经非常广泛,主要是在云原生方面。
gRPC也和TARS一样,存在着一些问题,就是它们需要用户改造过以后才能使用。这样的话就会产生用户的学习成本,需要把整体架构改造成符合RPC框架思路的架构,造成比较多的麻烦。
三、Service Mesh的探索
我们知道腾讯游戏的数量非常繁多,架构往往并不统一。各个团队都跟着自己的思路走,想用什么就用什么,慢慢得各种框架和问题也随之出现。为了探索解决这一问题,我们引入了一个新的思路:Service Mesh。
Service Mesh 是一个相对底层的架构,作为我们微服务的底层。两大主要产品是linkerd和Istio,它们可以直接从底层做一些链路追踪方面的事情,通过应用下沉提高了系统的适用性。
如下图所示,左边展示的是TARS和gRPC,他们的主要思路在于无性能损耗的交用,把所有的东西都执行到RPC里面,侵入性较强。右边是Service Mesh的架构,Service Mesh会把业务的服务做得很薄,基本上没有什么业务逻辑,而把所有微服务治理的东西全部放到下层,从而做到整个服务的流量控制,这样就组成了一个个小方格,互相之间可以互联。
这样的方式可以将框架做得非常薄,甚至不要都可以。整个架构非常清晰,相当于单体调用通过Service Mesh可以直接变为分布式的架构。
我们去年在王者荣耀里面也做了一些应用,最后发现这些架构非常方便。当我们给王者荣耀做活动使用的时候,虽然流量很大,但是性能非常稳定。每个服务下面都有一个Proxy,Proxy就是Sidecar,用于处理服务网格中所有服务的所有入站和出站流量。Proxy把所有的头转给Mixer,Mixer是负责提供策略控制和遥测收集的组件服务,这一块是做数据平面的一些操作。接着是Adapter,为Mixer提供扩展服务的独立服务,比如做一些远程负载均衡的流量控制。以这一套架构作为分布式体系的一部分,能大幅度降低许多单体应用的开发成本。
Pilot主要职责是向 Sidecar 发现服务、信息和各种流量管理和路由规则,Galley服务提供配置的校验、各种配置之间统筹,为 Istio 提供配置管理服务,Citadel用于密钥管理和证书管理,下发到Sidecar等负责通讯转发的组件。
通过测试数据可以看到,Istio在打开Mixer情况下单边延迟增加1ms 左右,双边延迟增加2ms左右,对服务影响较小,关闭Mixer延迟可以更低。
如果以绝对数字来看的话,相当于增加了一倍的耗时。但是在我们正式应用当中,大部分服务耗时都是在50毫秒左右,如果我们只增加了1毫秒,其实影响并不大。但是如果对于一些底层存储应用,本身的耗时是比较低的,如果再用这套架构把它变成分布式架构就会非常困难,因为性能损耗会变得非常大。
未来腾讯云会在设置一个统一的Istio管理平台,在容器管理平台里面会提供Istio的服务网格技术,在上面一层可以通过一些控制平面,服务我们上面的一些管控体系,通过Istio的应用管理平面来实现,底层可以访问我们的外部存储的,这个就是我们一套比较完整的应用架构。
下图所示的是 Service Mesh 和我们微服务框架的对比,在语言支持方面,它是跟语言无关的的底层架构,所以具有很高的拓展性。未来我们将会逐步完善整体生态建设,社区现在的活跃度也维持在较高水平。
最后给大家总结一下,我们的传统框架未来还会存在,但是它的功能会越来越业务化,治理相关的一些功能会逐渐下沉,更加注重是业务化的功能。
如果在应用当中,你还没有配置一些框架的服务体系的话,那使用TARS是非常合适的。TARS使用的是完整的微服务体系,非常方便快捷。如果使用gRPC则需要自己建设周边的体系。我们未来将会以Service Mesh为主,慢慢替代原有框架。如果大家还在做框架开发相关的业务,可以慢慢地抽出来往Service Mesh上面靠,因为框架开发未来会慢慢以业务开发为主,治理这一块将不再是重点。
四、Q&A
Q:对于Service Mesh,Service Mesh相当于将所有的服务治理都单元化集成到某个应用中,那么每一个单元的负载均衡或者是流量控制,是如何控制的呢?
A:负载均衡其实就是将流量转化成IP列表,分发给不同的IP。这里需要通过Sidecar?因为Sidecar会知道你的流量往哪边走,目前是通过iptables劫持流量指向Sidecar。当你的服务通过Sidecar之后,Sidecar获取到目的地址,通过控制面板上的数据,搭配一些策略,然后做映射,把你相应的请求分发到多个节点中去从而实现均衡。
讲师简介
田甜,腾讯高级工程师,对分布式架构与容器化技术有深入研究,具有丰富的分布式架构设计开发与项目实践经验。目前专注TARS-GO框架开发,是TARS-GO早期发起人和最核心开发成员之一,也是腾讯游戏数据研发工程师,致力于在数据服务场景中应用微服务架构。