在去年12月16日开源中国举办的开源年终盛典上,TARS 获得了年度“最佳原创开源软件”奖。
谈到微服务,人们往往会提起Spring Cloud和Service Mesh。
目前带服务治理的微服务框架中,Spring Cloud对JAVA开发者在微服务系统开发过程的各个环节不断丰富,使其在JAVA开发领域有广泛的应用。
另外,近年Service Mesh 作为后起之秀,也得到了较为广泛的关注。它在 Sidecar 的基础上,强调了各个代理之间形成的有机网络,可以做到语言无关、功能可扩展,目前社区处于发展阶段。
Spring Cloud 与 Service Mesh 这两种模式,一个作为JAVA开发领域的翘楚,一个被誉为开启下一代微服务架构的基础,那么 TARS 的突破口在哪里?又何以戴上“最佳原创”的皇冠?笔者深挖了TARS 这个项目开源以来的一些信息,并采访了项目相关负责人,整理出此文供读者参考。
据悉,TARS是腾讯2017年 4 月份开源的一款微服务框架,它集可扩展协议编解码、高性能 RPC 通信框架、名字路由与发现、发布监控、日志统计、配置管理等于一体,是涉及到微服务架构系统开发和运维的一整套解决方案。
服务治理能力与多语言支持
Spring Cloud的各种服务治理功能能够满足系统的大多数需求,而且它们都在不断完善,甚至于近期 Hystrix 都表示已经足够稳定,而不再开发新功能了,但是仅支持单一语言把使用群体限定在了 Java 之上。
虽然单语言架构能应对大多应用场景,但在性能方面不得不说还是C++ 与 Go 等语言比较有优势。另一方面,在团队与系统中,不同语言之间的通信协同是一件十分麻烦的事情,如果原生提供多语言适配,那么能够为开发者省去不少时间与精力,让他们可以专注在业务功能的实现上。随着业务和用户规模的扩大,为了应对快速的业务迭代与海量服务的开发与治理,结合Java 与 C++ 或者其它各类语言的组合,将会带来更高的收益。
而Service Mesh,像前面说到的,它统一控制住了系统中所有服务的通信流量,也就可以很容易地进行一系列服务治理,以 Istio 为代表的一系列 Service Mesh 框架也在不断演进其服务治理能力。另一方面,通过 Sidecar 模式,Service Mesh 天然就可以实现框架对多语言的支持。但是这样一来,业务需要再封装一套通讯组件去解决通讯问题,并且还存在异步调用等问题,同时会增加架构和维护的复杂度。而且由于 Service Mesh 目前还处在早期发展阶段, Istio 发布 1.0 版本仅几个月,相关实践还有待挖掘。
笔者从 TARS 社区了解到,它是目前区别于前两者的具有服务治理能力并支持多语言的微服务框架。
具体来讲,TARS 的服务治理除了涉及到服务注册、发现、负载均衡、熔断、容灾容错等业界常说的能力之外,还提供面对海量访问的一些特殊的治理能力,如 Set 模型、自动区域感知、过载保护等。
而它的多语言支持在一次次完善中不断壮大着整个TARS 生态:
C++、Java >>>
TARS 于 17 年 4 月 10 日开源,最初的版本支持了C++ 与 Java。
TARS 的前身是腾讯从 08 年开始研发的后台逻辑层统一应用框架 TAF(Total Application Framework),由于已经在内部研发了十年之久,这个版本的TARS 已经实现了前边提到的丰富的功能。它来得虽然晚,但是能力上并没有要落后的意思。直到今天,腾讯内部各大核心业务都在使用TARS ,基于该框架部署运行的服务节点规模达到十万个,服务着腾讯数百个产品,包括手机 QQ、手机浏览器、应用宝、手机管家、地图、游戏、智能产品等。而TARS一开源,仅在 4 天内就有超过1000个Star,之后阅文集团、虎牙直播、科大讯飞、大唐移动等50多家公司企业陆续采用它进行微服务架构系统的开发。
PHP >>>
17 年 9 月 4 日,支持PHP 语言的TARS-PHP 发布。
TARS-PHP 主要带来了通信协议设计上的改进,使开发者既可以使用二进制的TARS 协议,大大压缩服务请求的流量,也能够借助 TARS 协议解析的 PHP 扩展,提高打包解包的性能,进而提升单进程的任务处理能力。
TARS-PHP 版本的客户端选择了使用PHP扩展的方式实现了对 TUP 协议的支持,TUP 协议是在 TARS 协议之上的协议,它通过固定的数据结构封装收发包必须的信息,如返回值、输入输出参数、包本身的状态、包计数等,使得非TARS 原生客户端可以与 TARS 服务端进行通信。
概括起来,TARS-PHP 的解决方案兼具简单高效、接口维护方便、易于扩展、代码自动生成等特点,集成了寻址、服务发现、监控、上报等功能,并且通过引入扩展,做到了性能的大幅度提升。
阅文集团在微服务层使用PHP、JAVA做了一些TARS的TCP微服务,它与HTTP的交互是基于TCP异步加协程的方案。从实际数据来看,目前模板拼接的Node HTTP服务大概有十多个,逻辑API层PHP服务与定时服务有40多个,后台TCP服务有100多个,每个调用是亿级以上。
Node.js >>>
支持Node.js语言的Tars.js 于 17 年9 月 4 日 发布。
它的设计理念是:
高自由度,开发者可以使用诸如 Express.js、Koa.js 等任何熟悉的框架,也无需对框架进行任何修改,即可通过 Tars.js 运行,享受平台提供的各种监控与管理特性。同时,Tars.js 所提供的模块,也可以根据开发者的需求引入。
高性能,使用了大量的前端(V8)优化技巧,尽量降低所提供的能力对于业务性能的影响,经测试,其默认的旁路上报与监控对服务性能的影响 ≤ 5%,常用模块(RPC、日志等)性能位于业界前列。
差异化,根据不同的业务类型提供差异化运营方案,针对高流量业务,尽力降低框架对业务性能的影响,而对于低流量业务,则充分利用硬件资源提升开发体验。
Go >>>
18 年 9 月 15 日,TARS 支持 Go语言。
Go 语言的协程并发机制使它非常适用于大规模高并发后端服务器程序开发,同时随着容器化技术的飞速发展,诸如 Docker、Kubernetes 与 Etcd 等项目兴起,使得 Go 语言越来越流行,并成为云原生的首选语言,TARS 的 Go 语言版本也因此应运而生。
一方面,TarsGo 的推出,在大环境整体逐渐走向云原生的当下意义非凡,为开发者带来了适应新时代需求的一种有效选择。同时,Go 带来的天然优势,加上团队对于 TarsGo 性能上的不断优化,让其在性能上取得了巨大的飞跃,在对 TarsGo 进行性能测试时,结果显示其小包并发性能比 gRPC 高出5 倍。
高性能协议秘诀
TARS 作为一套 RPC 通信领域的框架,其对相关协议进行了一系列优化与设计。
Spring Cloud 通常采用 HTTP + JSON 的 REST 接口对外提供服务,而由于 HTTP 协议本身固有的特点,使得它不能并发处理网络请求,而且响应请求的时候还依赖于请求的先后顺序,这使得高并发、并行处理请求的场景下必须建立大量的连接,而连接的建立、维持和销毁都会消耗 CPU 和内存资源。
此外,HTTP + JSON 还存在传输包较大、序列化与反序列化效率不高、服务连锁反应导致的不稳定性等问题。
TARS 自研并在框架中主打了一种基于 IDL 实现的协议——TARS 协议,它以更加高效的方式解决了这些问题。这是一种二进制解析协议,与 Protocol Buffer 类似,它与语言无关,是一种类 C++ 标识符的语言,用于生成具体的服务接口文件。
首先 TARS 协议是一种二进制协议,相较于常见的 JSON 等文本协议,它的编解码效率更高、网络包占用空间更小。
TARS 提供了异步长连接的 RPC 调用方式,这主要是通过两个部分的异步来实现的,首先是网络首发包的异步,TARS的网络层实现采用了 Reactor 模型,通过 nio 提供的事件 IO 实现基于事件的异步网络 IO。其次是线程模型的异步,首先主调线程发起异步调用,主调线程将请求内容加入网络线程池的发送队列中,之后该线程继续执行。网络线程池使用 Reactor 模型实现,通过 nio 提供的 Selecter 实现事件 IO,所以所有网络线程均是事件驱动的异步 IO,当监听到对应连接的写事件后将请求发送,等待监听到读事件后读取响应并交给回调线程处理响应。
每个 TARS 协议请求带有一个请求 id,通过同一个连接发送的多个请求可以通过 id 来匹配响应,从而避免线程阻塞,降低硬件资源消耗。通常情况下一个客户端和一个服务端之间仅使用几个连接就可以满足传输的要求。
TARS 协议采用 .tars 文件定义接口和数据接口,TARS 文件是 TARS 框架中客户端与服务端的通信接口,可映射实现远程对象调用,通过提供的工具可以将数据和接口定义翻译成各种语言的代码实现。接口的共享只需提供接口的定义文件,使用者通过定义文件直接生成客户端接口代码即可。这样减少了双方的沟通成本,不再需要写大量的接口定义文档与解析 JSON 所需的对象。
关于协议,2017 年 11 月 16 日,TARS 还将 Protobuf 协议引入,开源了TARS-PB。为了减少对 PB 序列化和反序列化的侵入,TARS对对象仍然采用 PB 原生的生成方式,同时利用Protoc插件机制来实现TARS-PB代码的生成。TARS-PB 的发布,让已经使用 Protobuf 作为内部数据交换协议的用户可以更方便地对TARS 进行集成。
开源之路
TARS 团队认为开源应该保持初心,这是其开源态度。
采访中,TARS开源项目负责人单致豪介绍:“我们开源的初心是贡献,我们希望帮助开发者敏捷构建稳定可靠的微服务,帮助运维享受的高效运营平台,帮助企业得到开箱即用的高性能生产级产品。” TARS-PHP负责人梁晨说:“从了解TARS, 到阅文集团微服务改造使用, 再到为TARS开源贡献自己的一份代码, 点滴积累,希望能够回馈社区,让更多的开发者和公司受益!”Linux基金会亚太区负责人Keith Chan表示:“TARS已经成为Linux基金会重要的开源项目,我们希望项目能在基金会中健康成长,TARS的开源初心正是Linux基金会开源初心的表现。Linux基金会会持续帮助和支持项目发展,让世界越来越多的开源爱好者能了解并使用,同时基于TARS开发出更优秀的开源项目。”
这样的初心体现在以下几个细致的方面:
文档服务于社区 >>>
一直以来,腾讯开发者文档经常被吐槽写得像那啥,而在对待TARS 的时候,开源团队为此做了大量考虑。团队介绍,在TARS 开源前,团队了解了公司内部和开源社区在项目管理、代码维护、文档书写等各方面的差异,并对项目做出修改,以保证开源后向社区的风格靠齐,具体包括:
按照社区的习惯对 TARS 。代码的组织结构进行调整,将内部原来分开维护的各个语言的框架代码统一在 Git 上进行管理,文档全部采用 Markdown 书写;
对 TARS 所有代码的编码和注释风格进行规范,让用户阅读代码更加简洁明了;
对 TARS 所有代码文件、配置文件、DB文件的字符集编码采用 UTF-8 进行标准化;
对 TARS 框架编译安装的方式与社区常用的方式对齐,采用符合社区习惯的 cmake 方式。
纠结于开源协议 >>>
社区常用的开源协议有 GPL、Apache、BSD 与 MIT 等,它们有各自的约束和规范。比如 GPL 有传染性,它严格要求使用了采用 GPL 协议的类库的软件产品必须同样使用 GPL 协议,所以使用 GPL 协议的开源代码,一般不适合用于商业软件或者对代码有保密要求的项目。而像 MIT 协议就特别宽松,甚至可以将基于 MIT 协议的源码商品化。
TARS 是一个比较庞大的框架,涉及到前台、后台等方面的技术,这其中依赖了一些第三方开源软件,而这些第三方的开源软件采用的开源协议并不相同,包括前边说到的严格的 GPL。
于是团队纠结于将 TARS 开源要采用什么协议的问题。按照当时的情况,如果只是想要赶时间快点把TARS 开源出去,那么就可以不对项目做大面积的修改,但是这样的话就必须选择GPL 协议。问题是选择 GPL 协议将很难受到社区用户的认同和商业化用户的青睐。
这时候团队表示他们坚定了开源初心,希望让 TARS使用更友好的开源协议,最终选择 BSD-3-Clause,以核心组件为基础,以不依赖开源协议为 GPL 的开源软件为目标,对其中的工具或者组件代码重新开发测试。
以开源反哺行业 >>>
我们从 TARS 团队处了解到了项目当前的具体情况。自17 年 4 月份开源后 TARS 便同步建立 TARS开源社区。在这一年多的时间里,TARS 陆续收获了上千位个人开发者用户,关注并使用 TARS 的企业有五十余家,其中包括游戏、直播平台与网络通讯等行业。目前已建有 TARS技术交流群十余个。同时,TARS 与外部的开源社区保持紧密联系,就2018年,参加了20余次公开技术大会与企业内训。
今年 6 月份,TARS 进入 Linux 基金会,这是对其开源发展的肯定,在 Linux 基金会的带动下,TARS 将有机会获得包括开发与运营在内的各方面资源,为其发展提供助力。而除此之外,TARS 还积极参与到业界相关标准的探讨中,以各种形式去带动行业的发展。
今年 8 月 14 日,由中国信通院发起,腾讯深度参与制定的行业首个微服务平台标准正式对外发布,而这背后TARS 团队功不可没。据介绍,微服务平台标准的定制最早在今年 1 月份发起,当时中国信通院相关团队与TARS 开源团队在一场闭门会议中交流。正是这个契机,充分展现了腾讯基于 TARS实践微服务架构的能力,而这场闭门会也成为了双方微服务标准合作定制的启动会。
总结
回顾了 TARS 开源近两年以来的种种,可以概括为几个方面:项目独有优势、创新能力、开源态度及贡献精神。开源是一件小事,但是如何做好开源却是一件大事。在年底做了这样一份开源相关的总结,希望广大开源爱好者能够从中得到一些启发。
参考资料:
腾讯开源 2018-12-17
本文分享自微信公众号 - TARS星球(TarsCloud)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。