讲师介绍:
田甜 / 腾讯TARS开源团队核心成员。
腾讯 TARS 开源团队核心成员,对分布式架构与容器化技术有深入研究,具有丰富的分布式架构设计开发经验与项目实践。目前专注 TarsGO 框架开发,是 TarsGO 早期发起人和最核心开发成员。
陈明杰 / 腾讯 TARS 开源团队核心成员
腾讯 TARS 开源团队核心成员,对容器技术、内核技术、高可用架构,微服务等有较深理解。目前专注 Tars 开发框架的 Golang 语言版本开发。
TARS 是腾讯使用10年的微服务开发框架,支持 C++、Java、Node.js、PHP、Golang 等多种语言,其中 TarsGo 在2018年9月 正式开源。
本文会从5个方面来介绍一下我们的 TarsGo:
一、TARS 的架构体系
二、TARS 为什么要加入 GO 语言版本
三、高性能秘诀——TARS协议及编码
四、TartGo 性能提升措施
五、TARS 应用案例及未来规划
介绍 Tars 的架构体系之前,我们先将当前开源微服务框架的现状做一个简单的对比。
第一种无服务治理类,目前市面上已经有较多的微服务框架,大部分都是这一类,专门解决通信框架、RPC 或消息队列的模式,比如说 grpc、thrift 都是这一类,它往往支持多语言,但是没有服务治理,主要是专注于 RPC 框架通信。
第二类是单语言带服务治理同时也解决了通信问题的,这里代表就是 sprint cloud/dubbo,它本身是微服务框架,带有服务治理方案,整体的服务部署、服务发布整套微服务的架构,遗憾的时候他们只是支持 java,如果企业技术栈是JAVA,它们将是不错的选择。
第三种是 ServiceMesh,典型带来就是 envoy、ISTIO,支持服务治理,当前还是一个比较火的最新概念,现在很多人都是通过 SideCar 的方式实现了多语言的支持,但目前还在发展期,现在还没有大规模的应用案例。
最后一个种类,是带多语言以及服务治理能力的通信框架,目前行业里就只有我们 Tars 才有这个能力。
Tars与流行微服务框架作对比
这里主要与业界流行的微服务框架 GRPC 进行一下简单的对比。
1.在网络协议方面,Tars 支持 udp,tcp 等等,GRPC 是 http2。
2.在 IDL 方面 TARS 支持 TARS、PB 以及自定义,GRPC 支持 protobuf。
3.两个框架都通过 IDL 支持了多语言。
4.RPC 性能方面,我们测试出 Tars 比 GRPC 高5倍。
5.服务治理方面,Tars提供整套体系治理,比如说远程日志、服务部署跟发布等等整一套编译和整一套微服务治理流程,然而 GRPC 更多的是完善的社区,如果你想用 GRPC 生态环境开发框架,必须治理集成,比如监控、服务部署或服务发现这一类问题需要自己解决。
6.最后,Tars 已经大规模应用了10年,GRPC 普遍在开源社区使用。
Tars 的架构,主要包含6部分:
1.最下面的是基础设施,我们现在可以跑在物理机虚拟机和容器,通过各种云构建自己的 Tars。
2.构建之前需要有开发框架,在协议方面,主要是以 Tars 协议为主(还支持HTTP、SSL、Protobuf 及自定义),开发框架的 RPC 调用是同步、异步还有单向调用,单向调用的意思是客户端只管发包不管回包,需要很高性能的时候,单向可以提升很大的性能,这是 Tars 特有的一个功能点。
3.再上一层是服务治理模块,Tars 除了微服务有的能力,比如说服务发现、注册、附载均衡,我们说的监控之外的一些能力,Tars 还支持熔断、服务配置、日志聚合、自定义监控、set 模型、分布式追踪、自动区域感知、流量管理、过载保护。分布式跟踪和流量管理等方案,借助这些能力更好的运营大规模的微服务架构体系。
4.同时 Tars 当前已经支持 C++、JAVA,Nodejs,PHP,GO 等多种语言,未来会支持更多的语言。
5.在 oss 方面,Tars 本身支持代码的管理、代码编译还有自动化测试、持续部署等等的能力。
6.同时这套架构整体和 Devops 完美的结合,已经在腾讯之内有非常好的应用经验,外部是可以通过这套体系搭建自己的 Devops 平台。
服务治理方面的实现,主要分为三部分:
第一部分是 registry,也叫主控,它主要提供了服务发现的功能,可将微服务端的 IP 列表提供给客户端;
第二部分是业务节点,它作为业务的最小单元,在业务服务需要横向扩容时,每个服务可以部署很多的节点,这些节点都可以通过主控下发给客户端。所有服务都会上报状态给 node 服务,无论它装在物理机里还是容器,node 收集心跳,然后作为数据源,发给主控让他就知道服务的运行状况。
第三部分是服务治理的核心,基础服务集群,里面有监控、配置、日志等等功能,这些服务都是无状态的,可以根据自己的需求进行横向扩容,比如说日志量量特别大,就针对日志服务可以横向扩容几百个节点,然后通过框架的配合就可以实现服务治理的功能。
整套服务治理的流程如下,客户端会通过主控获取到路由 IP,然后通过一系列自己定义的权重或者是轮询的算法进行调用。服务端方面,为了保证可用,会上报心跳给 node,如果说后端节点异常了,客户端还有一个熔断策略,一段时间之内服务端节点超时,或调用失败超过了某个阈值,客户端会主动将其屏蔽掉,结合两种场景可以实现分布式高可用。
这种基础的服务治理针对大部分的线上的微服务就够用了,但还有一些是在线上运营的情况,比如我们在云机房的购买了云服务,我们不可能做到同时兼顾整个体系的机房和地区情况,TARS 提供了很重要的区域感知功能。
我们在扩容多机房的时候会面临一个问题,将服务部署在一个新的机房,肯定会有跨地区访问,延时整体升高,或者缓存的延时无法忍受影响客户体验。虽然我们可以通过简单的方法,把整个的服务在一个地区部署一遍,但是这样会导致运维工作量非常大。相当于同时维护两套业务,这个时候 Tars 怎么解决呢?
TARS 的自动区域感知功能,什么是自动区域感知,比如说在服务,规模不断变大过程中,就会面临跨地区或者跨 IDC,跨机房服务的部署。如果出现这种情况,区域感知的具体逻辑是客户端在每次调用的时候,会通过 registry 的一个路由表确定客户端是哪个机房的,在返回的时候筛选最近机房的服务端 IP 地址,这样就不会跨地区访问了。对用户来说只要部署和开启就可以了,对开发人来说不需要关心我这个服务部署在哪里,只需要在平台上查看一下是不是有这个配置就可以了。同时,如果运行过程中出现一个地区异常了,自动区域感知也能及时返回其它区域的节点补充,比如说宝安的这些节点都挂了,但是深圳坪山的主控还好好的,那它会返回其他的节点保证其他的程序正常运行,这样就没有开发成本和运维成本了。自动区域感知的优势就是说可以使运维更简单,降低延时以及带宽的消耗,有更强的容灾能力。
除了简单的大规模的机房横向扩容,在应用内部的时候还会有一些问题,比如你的业务的微服务的数量可能是高达上千个,但是运维一般最多两个人,上千个业务和两个人这种运维体系下面是很难做到海量规模,如果是用传统的运维体系做根本没有办法实现,所以我们就有了新的模型叫 SET 模型,我们根据标准化,以 SET 单位部署,然后可以横向扩容。
如果我们按照容量划分,正常是两个服务提供了 300 万的用户在线和运营,假如我们在正常情况下 A 服务出现了异常,这个时候A就整体不可用了,这肯定没有办法交代,所以这个时候一般会考虑怎么进行隔离?就想到一个办法就是把服务拆成三套,A1,A2,A3,这样即使是A1挂了还有两套可用,整体的是柔性可用了。但是在这种情况下对我们运维来说是不可控了。我们的框架支持这样一套逻辑,在框架下面可以动态的划分SET分组,每个组承载 100 万,这里带来的好处一个是刚刚说的故障隔离,即使是 100 挂了还有 200 万,第二个是 300 万是一个极限,如果说 300 万后面扩到 400 万,600 万甚至上千万只需要把 SET 进行扩容。
访问的时候只让每个服务访问自己 SET 的节点。主控有支持 SET 的分组逻辑,可以支持动态构建,和自动区域感知一样,与开发无关,只与运营相关,如果有运营需求只需要在平台上修改一下即可,不需要重新编写代码。
在微服务化之后肯定存在这样的问题,发布非常的频繁。正常情况下一天发布一次是少的,而每次发布都会影响上百万的用户,这时候就需要支持无损变更。这里有一个例子,框架支持通过权重配置调节流量,我们先发布一个节点,发布时把权重降低,发布完之后再加回来,只有10%的流量,本来是可能影响 100 万用户,10%仅为 10 万用户还可以接受,验证没有问题之后再发其他节点。先把流量调低,没有流量以后再发布,完成之后加回来,就做成了无损的流量发布。
Tars 支持分布式跟踪,我们面临一个大的挑战就是说我的服务请求进来失败,想知道用户反馈或者运维反馈业务请求失败,但是不知道失败在哪里,想做调用的回溯,却没地方去获取我服务调用链信息,只能一个地方一个地方去查,这样对整个查找问题的时间上会有很大的损耗。
通过这种分布式追踪最终每个请求进来都可以创建一个 Span,每次请求的时候做一个 hash,然后将这些 Span 设置一些信息,比如主调方是谁,或者被调方是谁,然后再一层一层往下传,每个服务接受到这个请求,包括请求完成之后,都会将这个 Span 发布到 Zipkin,通过这种方式,只要拿到这个请求的 ID,网页上做一个查询,就可以查到这个失败的地方在那里,也就可以快速定位到 RPC 调用失败了,最终可以快速定位到这个失败的服务节点。
在微服务化之后服务很多,会有很多配置。想象一下如果有 1000 个服务,会有 1000 个配置,其中如果有重复的内容,难道需要都存 1000 次?理论上重复的内容只需要存一次就可以了,因此我们设计了分级架构。
Tars 的配置中心将配置分成两部分,一个是框架配置,一个是业务配置。同时业务配置分成4级,分为应用级、Set 级、服务级和节点级,每一级的下一级都可以引用上一级的配置,这样就可以实现的只要在应用级配置,下一级全部可以引用它,这样就实现的服务间的共享,解决了微服务的过程当中配置共享很困难的情况。管理界面也就很简单了,把三级全部列出来就行,开发的时候只需要把自己的配置文件名写上去就可获取到配置,程序里面直接使用,这个是我们的微服务管理配置的方法。配置服务我们单独分离了出来,未来会开源,但是在 Tars 框架里面使用更加简单。
最后是可视化配置,Tars 本身支持可视化管理,如服务的发布,服务的管理等。可以看到有哪些服务,哪些应用,包含服务的状态,当前设置的状态还有当前具体的状态,还有服务IP信息或者有哪些节点,包括刚才说到分散的信息都会体现。
创建一个新的服务时,直接在页面上可以创建。用户在用 Tars 做开发的时候,根本不需要关注这个服务监控的上报,只要你在框架内部发生请求,客户端调服务端时会自动上报调用量。还有耗时、异常率(调用失败时服务端的失败返回)、超时(服务端没有反馈),通过监控页面可以快速查找,而且不用关心监控上报的事情,这是我们面临的一个最大的挑战。
平常自己开发一个服务,对服务质量做把控时,服务的指标往往需要我们自己去做一个监控,上报到数据库或者上报到一个其它监控组件,然后用其它的组件展示出来。每个业务可能实现自己一套监控上报的逻辑,非常繁琐,通过 Tars 就可以快速解决这个问题。
Tars 平台上可以一站式地管理服务,不用再登录机器,是去终端化的很好的实践。
随着容器化技术的飞速发展,诸如 docker、kubernetes 与 etcd 等项目的兴起,使得 Go 语言越来越流行,并成为云原生的首选语言。我们的tars在微服务及服务治理上功能已经非常强大了,使用 go 语言实现框架算是顺其自然的事。
TarsGo 的整体架构分为三部分
第一部分是 tars2go 工具,对 tars 文件进行语法/词法分析,自动生成框架代码,并对 Tars 协议进行的序列化和反序列化,后面会详细介绍一些序列化的规则。
第二部分客户端,设计看起来很复杂其实比较简单,pacakgeTars 是主通讯管理,底层是 sendqueue,再底下是标准库。
第三部分是服务端,有两个协程进行处理,然后会发到队列里面,队列上面有几个消费者,多个 worker,作用的是将上层的队列的数据消费了之后再反序列化给 dispatcher,就是 Tars 发给的用户代码,执行再返回,这就是整个流程。除此之外,还会有几个协程,进行特性监控及远程日志的上报,和运营相关的功能通过这些单独的协程完成。
下面介绍一下 Tars 协议的编码并提供一些demo展示。
Tars协议,Tars是一个二进制的协议,语言无关的接口描述 IDL,通过工具自动生成服务端客户端代码,Tars IDL 的关键字很像C++,下图展示了 Tars 的接口,还有 RPC 的两个结构体,语法相对简单。
Tars 协议在编码的时候分两个部分,一个是头信息,另一个是实际数据,头信息分两块,一个是 Type,第二个是 tag,正常需要 4 个 bit,但是基于结构体有时可能会定义多个成员,若字段过多可以自动扩充到 8 bit,最大可以定义 255 个字段,目前基本上还没有超过的情况。
TARS RPC 的协议,包含一个头信息和实际数据,在实际使用时将用户的函数,参数进行序列化,返回参数基本一致,整体的结构体就是这两个Tars的核心点。
怎么用 TarsGo 编写一个程序?首先用 Tars 写一个接口,这里面的 out 关键字和 go 有区别,这个时候再用 tarsgo 工具,直接将 Tars 翻译成 GO 代码,文件夹里面就会生成一个文件,这个包里面就包含了客户端代码和服务端的代码。它的逻辑是将序列化等这些步骤自动完成,用户就不用再担心 RPC 远程交互调用的问题。用户仅需要自己实现一个功能,然后再做注册,这个服务就开发完成了。我们会提供一系列的自动化工具,可以让你上传到管理平台里面,就可以跑起来服务了。客户端调用,只需要注册进去,有不填IP通过路由进行寻址或者填 IP 直接通过 IP 端口直连调用这两种情况,需注意切换的时候只需要把路由详细地址屏蔽掉就可以了自动切换。客户端直接访问生成函数就发起 RPC 请求,最终把这个节点写回 C,C 就变成你想要的值,这个是完整的开发 demo。
1.0 版本是满足功能,到 2.0 准备开源,同时也是要为了高性能的需求,针对性能提升我们做了很多东西。
首先是协议的编解码实现,第一 1.0 版本的时候发现服务编码性能特别的低下,第二个是我们一开始代码生成实现是通过 cpp 的一套方案,把Tars协议翻译成 GO 语言,大家使用我们框架的时候不仅仅是要装 GO,还要装 C++ 的生成工具非常麻烦。针对这两大点,我们做了多项优化,减少数据 copy,使用指针传递返回数据,转换类型去掉反射,使用 Tars 协议 type 类型,最近是使用纯 GO 实现了 AST,抛弃了 Yacc 与 bison,实现了框架从生成到实现的纯 GO 化。整体优化后,框架的性能提升了数倍。
线上服务 RPC 请求非常多,上百万的流量都有可能,每一次请求必须有一个 Timer 进行时间统计,请求多了之后性能就特别差,因为timer有一个全局锁,主要是 GO 在 1.10.3 版本以前都有一个大锁,导致在多核的场景下 timer 性能低下,查找到问题原因之后,直接升级 10.3 版本以上就可以解决它,10.3 版本将锁的粒度变小,这样的话就提升了性能。但我们并没有满足,因为我们 RPC 时对时间的精度要求并不高,我们基于时间轮的算法实现了自己的 timer,降低精度,可以提升显著 timer 的性能和获取当时时间的性能。
再一个是使用 Net 包的时候遇到的问题,我们在每一次读写的都会设置一个超时,因为net包中间做了很多的封装导致性能很差,我们找了一个办法,直接把 socket fd 拿出来,通过系统调用调用 socket 的设置,虽然明显的提升了性能,但是也有风险,因为改了 net 包,把接口暴露出来对于外部用户无法使用,我们对外提供了一个参数可以不设置超时,但是会有些风险,万一 socket 卡死了就没法恢复了。
有关 Bytes buffer 的问题,我们使用 buff 作为序列化缓存,当 buffer 增大时,底层的 byte slice 需要一次 copy。同时每次请求创建一个 buffer,因为 RPC 正常的情况下非常小,全部是小内存,容易导致gc性能下降。我们想了办法,第一个是用池子放内存这样就可以避免频繁内存分配导致的 gc。底层 slice 自动扩容问题怎么解决呢?我们将 buffer 进行封装,然后针对不同的 size 进行分类的封装,通过经验预测分配对应大小的 buffer,这样就减少底层扩容的几率,底层只要扩容我们整体的压力就没有那么大,因为占比非常多。
其他的优化:
第一个是使用协程池,我们会加入一个协程池,减少协程分配引起的栈扩容。
第二个是 TCP 连接优化,我们会设置一个比较大的buffer收取连接数据。
第三个是使用指针而不是值传递,同时避免多协程竞争同一个 channel。
第四个是避免使用反射,但是有的时候也不能避免,去掉反射往往会提升很大的性能。
最后看一下我们优化完之后的性能对比,我们是在 4 核 8 线程 CPU3.3Ghz 主频上进行的测试,可以看出,TarsGo 版本的性能和 C++ 基本持平,上文提到过如果切换 C++ 程序性能跟不上肯定会遇到大的挑战,但是是 TarsGo 跟上了。第二个整体上已经远超其他的语言,性能表现的不错。
Tars在去年4月份开源,和很多的企业交流同时获得了很多广泛的应用,在今年6月份的时候加入了 Linux 基金会,当前以基金会的名义运营,同时 9 月份的时候开源 GO 版本。
我们 Tars 已经应用在这么多产品和行业上,未来会更多的发展,同时我们会引用更多的开源社区的一些东西,反哺社区或者是吸收更多的经验,欢迎大家一起,为大家、为用户提供更多的选择,谢谢大家!
提问:您好,其实我也是最近刚刚听到的 TarsGO,我想了解一个问题,因为像这种大场的开源项目,场内场外不一样,TarsGO 在腾讯内之间是什么样的关系?以及腾讯对 Tars 开源的定位,因为大家要用这个东西,总归是希望长远的发展起来而不是像某一些项目丢出来以后就没有响声了。
田甜:TarsGO 在设计之初,我在发起之初考虑的就是开源和内部是同一套代码,在我们内部的时候名字也叫 TarsGO,所以说这一块迭代更新这一块不用太担心,因为外部和内部除了一些我们内部有一些关键的模块,因为协议和我们的WEB模块不一样,其他所有的都是一致的,我们在迭代更新的时候都是完全开源版本和内部版本是完全一致的,同时 C++ 版本整体规划可以让 Tars 负责人单致豪给大家解释一下。
单致豪:我是项目的负责人,其实 Tars 在腾讯里面已经用了 10 年,所以说这个框架一开始在 08 年的时候那些第一批开发人全部出来了,现在这个项目还是继续运行,我们这个项目内部有了 300 多个用,GO 版本也有 20 多个产品在用,所以不用太担心内部和外部维护的问题。
提问:你们 Tars 更感觉你能讲一下跟 K8S 有什么区别?
田甜:K8S 更多的是资源管理调度与微服务管理,我们 K8S 可以做容器分发调度,可能是先通过资源的管控,再上升到对流量的一些管控,所以说我刚刚一开始的时候对比了一下说到,tars 也是可以跑在 K8S 之上的,我们更倾向于给用户的应用框架而不是做一些底层的资源管理。
提问:我是觉得 K8S 跟 Tars 和 K8S 差不多,就是 K8S 多了一个容器管理,你们那个也是的,你们也需要的,每个节点也有一个像那种每个服务每一个 serve 做服务,K8S 也有。
田甜:我们和 K8S 一个是有部分的竞争和重合,K8S 并不管你的用户逻辑的,这个需要注意的,K8S 更多的是关心我的这个进程拉起来,然后我这个进程挂了我要进行迁移调度和分发,但是我们这里是更倾向于业务,我们这些都是业务相关的配置,K8S 不会管你的业务的内部的配置,你得自己管,然后你的日志他可能会做一些公共的存储,但是那些日志你打的这些不会管。
提问:我想问一下,因为我们在刚刚讲的讲到了 registry,如何保证高可用呢?
田甜:registry (主控)高可用有两个方面,第一个方面,如果说在规模不大的时候,因为在规模不大的时候,一万个以下,因为 registry 不是每一次访问的,这个路由信息是有缓存的,所以说访问的频次非常低,只要保证可用不经常挂。第二个方面,我们在registry后面的存储使用了 etcd,etcd 使用 raft 在节点高可用上做得非常好的。
提问:Tars 的客户端在扩容和缩容方面的过程能不能介绍一下?
田甜:我们是有服务管理的,扩容就是选择一个服务版本然后进行扩容,目标IP,其实这里的一些信息,扩容就是分几步,一个是拷贝配置,针对新的节点要有配置,这里的扩容就是服务配置,配置完之后就是发布,把节点我们刚刚说的程序发布到目标的机器上,这里也会填一个IP,发布完成以后一启动的时候我们会收到服务节点的上报,拉起来会上报心跳,然后报给主控,就知道了这个服务已经起来了。主控就会将这个节点信息分发出去,客户端下一次请求就拿到目标节点了。
提问:扩容可能还比较直观一点,那比如说像这种扩容肯定是从裸机开始到后面的应用,那缩容是如何做到流量进来,然后关闭流量,然后可能有一些队列还要消费,消费完之后正式把机器下线?
田甜:这个缩容和发布很像,会先通过主控把流量调到 0,其实客户端再主控拉新的 IP 的时候已经拉不到 IP 了,我们平台会等待,等我们的客户段全部刷新了主控的缓存之后这个客户端已经没有了,就不会发新的请求在这里了。
提问:那程序会不会有健康检查的机制,包括是和主控这边怎么样说这个程序就没有再应用?
田甜:这里就有几个配合了,一个是上报心跳,会保证各个节点已经下掉了,其实这个上报心跳是有频次的,第二个结合我们的监控中心,我们所有的调用都是有所有的监控数据的,每一次调用都会有数据上报,我们会等一段时间再去较验确保这个节点已经没有流量了,这个是组合的过程。
提问:还有一个问题,你们对于操作系统这一块客户端的支持支持到什么样的程度?windows 呢?
田甜:CPP 版本目前来说不支持其他的系统,但是 TarsGO 我可以保证的是所有系统都支持。
提问:最后想问一下日志这一块,我感觉监控和日志都是数据量非常大,我想问一下日志的客户端的架构?
田甜:这里面的客户端比较简单了有一个缓存把日志记录下来批量发给日志服务,其实我们的日志服务也是迭代了好几轮了可以简单讲一下最新的版本。我们的客户端里面会有一个日志 SDK,每个节点上有一个日志 agent,agent 通过消息队列将日志发送到远程集群,这样框架就清晰且框架不是很重,主要的逻辑都在 agent 上,高可用方案与其它实现一致的。
提问:还有日志,如果你的应用层面,比如说网络不通或者是时间方面导致了不能通信是不是会影响整个的应用?
田甜:对,所以针对这种情况我们的远程日志不一定是 100% 的远程,为什么加一个 agent ?就是加一个容错策略,本地缓存之类的,如果网络不通的时候会把日志本地缓存住,等待网络通了之后再发送出去,或者由于各种发不出来了,在本地上也会有 cache 文件。我们尽可能保证不丢的情况下,在下一次网络通的时候再发出去,如果时间上有一些错位,日志其实并不太关心时间,其实只要是打出来就可以了。
提问:你刚刚说到的 client 访问主控的时候有缓存,这个是用户来做还是 Tars 做?
田甜:这个是所有讲的都是 Tars 框架做。
提问:如果主控那边有更新的话是怎么通知到 client 的缓存?
田甜:其实有两部分,一个是定时拉取,因为主控服务节点非常多但是变更并不多。第二个我们可以主动的调管理接口更新本地缓存。
提问:你好,我是从开源网站里面拉过 Tars,试用了一下,我发现它整个里面存储,就是开源那一条,里面功能是很全面,包括你上面提到一些监控、远程日志这些,我从开源里面拿过来用,我发现可能在这种日志系统或者是监控模版不是能满足需求,我不知道 Tars 这边官方怎么看待这个问题,内部直接是 RPC 口来做这个事情?
陈明杰:我们 Tars 后台监控整套方案马上开源出来,前面 Tars 版本其实在早期时候,Tars是这么做的,最早期的,但是那个量是很多年以前,现在马上我们要对 Tars 后台就是监控,我们监控体系是做分布式的,我们还有一个 Tars monitor 服务,它后端可以实现自动落地,可以落地到各种存储,比如说落地到本地或者其它的存储上,然后整套开源的框架,就是我们监控会基于这些开源的组建,我们之前像监控像 Tars 服务,整个方案都会出来,我们现在大概是在千亿级。
提问:我用的时候感觉应该用不了的,要在企业里面用……
陈明杰:对,马上就开源出来了。
提问:我是做YY的,我们一般会替换成公司的监控或者替换成公司的日志系统,你们后面还会开源这些东西是吗?
陈明杰:开源版本监控有很多耦合,我们现在做改造,马上就可以给大家提供,可以做千亿级别每天的写入。
提问:刚才说还是要做改造才能用到企业里面。
陈明杰:对。
提问:刚才说新版监控,原理是承受千亿级的量?
陈明杰:两部分,一部分我们其实每个机器上其实都是有 agent,我们监控先发给 agent 做聚合,agent 聚合之后会发给 Kafka,通过 Kafka 再写入后台像 HDFS 这样分布式存储,像刚才我们说 Tars 类型的服务,取一些高性能的,通过 Kafka,我们 Kafka 后面还有消费,不同地区可以设置不同消费组,这样一个方式做到日志的千亿级别的写入。
提问:可视化方面,有个页面吗?
陈明杰:可视化还是可以用前面这一套,我们有更强的能力,比如说我们多一些维度的展示,多一些跳转。
提问:刚才说熔断之后,熔断那个 IP,如果连不同后面会不会有重试的机制?
陈明杰:会的,比如说一分钟之后可能会屏蔽或者一分钟之后会放,或者放一个流量,或者探测这个节点,如果恢复重新交回到请求列表面里面去。
提问:刚才时间不太听清楚,是用开源还是自己手工的?
陈明杰:自己手工写的,比如说你定时一秒之后,大的时间轴会放到队列里面,到一定时间,会处理和通知,然后去实现。
提问:我这边有个问题,用到一些 RPCX 的功能,然后我看到两个框架,第一,你们 Tars-GO,一个是 RPCX,你们这里也没有列出 RPCX 的对比,我制片看 RPCX 之前在服务端,然后备份,这些工具比较好,文档也是看得比较好,我就选他们那个,你们那个看起来就是应用性没有他们现在那么好。
陈明杰:您刚才也看到 RPCX 没有提供像 Tars 完善的微服务整个体系,它虽然有一致服务的能力,像我们服务部署、流量控制、熔断这些策略,可能没有像 Tars 这么完善,还有像服务编译部署,这些都是 Tars 独有的,还有我们刚才说的分布式追踪,像其它一些微服务的能力,RPCX 差是做不到的,像运用性方面也在做努力,下周可能会出 docker 的方案,Tars 跟 docker 整个部署,在前期使用方面,运用性比较差,微服务需要很多后台框架,管理平台需要部署,这套编译和部署上手会比较难一点,但是正常通过文档引导可以做成功部署,我们也有相应的交流群,遇到问题也可以联系我们一起去看一下后面会出更方便的方案,比如说刚才提到的 docker,docker+K8s 包括后台服务容器化,这样方便跑一个容器就可以整个快速部署起来,只要关注自己的开发,像 Go 的开发就比较简单,只需要把官网上的 Go 包下载就可以了,整个部署后台会基于一种细化去做部署。
提问:讲师您好,我看服务是以 set 方式做可用区的方式,有一个场景,同一个服务分两个 set,在 A set 里面去调 B 里面的服务,这时候是否可以在 a 里面 sync 调另外 Set b 的服务呢?
陈明杰:正常不会调到,如果你分了 Set 之后,另外一个服务,可以通过指定 Set 方式去调,假设 bSet 挂掉了,一时半会恢复不了,你通过服务快速更改,马上就把 Set 调到另外一个 Set。
提问:有区域跟可用区的概念,可用区我同一个 vj(谐音),比如说我现在华南地区机房里面,我在深圳和广州两个可用区,我会优先深圳,深圳废了,我就可以直接调到广州这边。
陈明杰:这个就是刚才讲到 IPC 分组里面是有的,比如说启用 CIPC 分组,使用一些有,比如说自己 IPC 内里面有就先调,如果没有可以调别的节点。
提问:注册中心的信息存在哪里?
陈明杰:目前存在 ETCD 里面,每个 Registry 节点会做 Tars,保证分布式,然后中间节点是可以用 ETCD。
提问:腾讯应该是 C++,他用的一个方式,通过重新加载做这个 VC 吗,像动态库做这个分析,像静态编译,然后起伏,目前我们这边要升级版本,是不是要先把服务拆下来,再去布局?
陈明杰:这些都可以串在平台管理能力里面,一个节点我们是可以做到无损发布的,无损发布就是在管理平台我们做无损发布,我点击这个无损发布,第一件事情就是把它从路由节点里面摘掉,摘掉之后这个请求就会过来,会有个队列里面,因为还有一个请求在队列没有用完,我们是可以拿到Tars框架是有的,可以拿到请求队列里面的信息,他会请到请求队列里面完成信息的时候,更新完之后再把流量放回来,这样做无损发布的过程。
提问:最后一个问题,在腾讯这种 C++ 语言这么强的公司里面推广一个 Go 会遇到什么问题,我看 Tars-GO 应用主要还是在 PCG 等事业群在用,其它部门都在用其它内部微服务方向,开发 Tars-Go 要联系到企业内部很多不同 CKV 这样的服务包括监控,你们在做推广过程中会不会遇到一些阻力,你们是怎么解决这些阻力?
陈明杰:现在其实还好,现在大家都是比较积极转 Go,PCG 以前 MIG 跟 OMG 现在慢慢大部分在转 Go,特别是北京的团队还有深圳的团队,他们都在积极转 Go 的过程,你现在可能比较久,现在内部很多 CKV 那些组件所有都有相应的 Go 库,包括内部平台刚才说的那些东西都是有相应的 Go, Tars 协议还有一个好处,后面的存储组件都是Tars协议接口,主要这个工具生成一下,其实这些 API 都可以用。
提问:老板会支持这个级别吗?
陈明杰:我接触过几个领导,他们都是直接整个从 C++ 或者 JAVA 转过来的,他们从主管级别开始强烈往下推,再带下面人去做这个事情。