设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 重新 试卷 文件
当前位置: 首页 > 服务器 > 搭建环境 > Windows > 正文

解读 | TARS开源项目发布Go语言版本(2)

发布时间:2018-09-22 10:41 所属栏目:117 来源:佚名
导读:对于流量控制,服务发布上线主要面对的问题是如何做对业务无损的服务变更与如何做灰度验证,在 Tars 中,可通过 Registry 和开发框架配合实现按需进行流量控制,达到无损发布和灰度流量的目的。 语言支持方面,除了

对于流量控制,服务发布上线主要面对的问题是“如何做对业务无损的服务变更”与“如何做灰度验证”,在 Tars 中,可通过 Registry 和开发框架配合实现按需进行流量控制,达到无损发布和灰度流量的目的。

解读 | TARS开源项目发布Go语言版本

语言支持方面,除了此前已经支持的 PHP、C++、NodeJS 与 Java,此次还加入了 Golang 支持。

此外,Tars 还提供一个 OSS 平台,可使运营可视化、Web 化。

解读 | TARS开源项目发布Go语言版本

它主要包含以下特点:

  • 业务管理:包括已部署的服务,以及服务管理、发布管理、服务配置、服务监控、特性监控等

  • 运维管理:包括服务部署、扩容、模版管理等

  • 提供 Open API ,可定制自己的 OSS 系统

Tars-Go,Tars Go!

多语言支持是 Tars 的一大优势,在此之前 Tars 已经推出了 C++、Java、PHP、NodeJS 版本。Go 语言的协程并发机制使它非常适用于大规模高并发后端服务器程序开发,同时随着容器化技术的飞速发展,诸如 Docker、Kubernetes 与 Etcd 等项目兴起,使得 Go 语言越来越流行,并成为云原生的首选语言。Tars 的 Go 语言版本也因此应运而生,此次 Tars-Go 的推出,在大环境整体逐渐走向云原生的当下,意义非凡。

此次新推出的 Go 版本 Tars-Go 整体架构主要可以分为三个部分,如下图所示:

解读 | TARS开源项目发布Go语言版本

  • 左边是 tars2go 工具,tars2go 基于巴科斯范式(BNF),这是一种描述程序语言结构的形式化方法,用来对 Tars 文件进行语法和词法分析,生成相应的代码,供客户端和服务端使用。同时它提供 Tars 协议二进制流的编解码功能,将二进制包转成相应的 Go 数据结构。

  • 右边部分是 package tars,它包含了 Client 和 Server 两部分的功能:

    • Client 由 Servantproxy、Communicator、ObjProxy、adapterproxy 等逻辑结构组成,这些逻辑结构用来管理 servant,obj 对应到的服务端节点的 ip 端口,和 C++ 的逻辑保持一致。底层使用 net.Conn 来建立具体的连接,并用 SendQueue chan 来控制并发数量。Client 还包含一些 Goroutine,用来做特性监控和 stat 监控上报。

    • Server 使用 package net 的 listener 来管理 TCP 和 UDP 连接,使用多个 Goroutine 进行 accept,并将 accept 之后的 net.Conn 经过 SendQueue chan 交给后端的 Handler 进行处理。Handler 由一堆 woker Goroutine 组成,每个 Goroutine 基于 net.Conn 进行收发包、Tars 协议解码,并经过 dispatcher(由 tars2go 生成) 来调用用户的代码实现,然后将结果编码成二进制流返回给 Client。Server 也包含一些 Goroutine 实现远程日志异步上报等功能,防止同步调用阻塞请求。

编者了解到,Tars 开源团队在研发 Tars-Go 的过程中经历的对其各个方面的性能调优改造,Tars-Go 在早先的版本注重于功能的开发和完善,没有体系化地进行压测和性能分析。在业务使用一段时间后,开始注重性能优化。Tars 开源团队对 tars2go 工具先进行了一轮优化,在生成语树的时候生成好了类型信息,避免使用反射进行类型判断,编解码的效率提升了 2 倍,然后对再对整体 servant 进行了一轮轮压测,并进行 CPU profile 性能分析。

下面是性能提升优化的几个实例: 

Timer 性能问题

每个请求进来,Tars-Go 会创建一个协程进行处理,因为要处理调用超时,会创建一个 timer,在结束的时候会删掉 timer,当并发量一上来,就会频繁创建和删除 timer,占用服务大量 CPU 时间。

解读 | TARS开源项目发布Go语言版本

研发团队在一个 issue 中发现 ,在多 CPU 的场景下,如果存在大量的 timer,性能就会大量损耗,优化方式是每个 p 有自己的 timer,这样可以大幅提升整体并发性能。于是 Tars-Go 将编译环境升级至 1.10.3,从 profile 来看,性能得到了很大的提升,并且基于时间轮询算法实现了自己的 timer,以精度换取性能和效率。

net 包的 SetDeadline 调用性能问题

为了设置网络连接的读写超时,Tars-Go 使用了 net 包的 SetReadDeadline/SetWriteDeadline 等相关调用,但从 profile 发现,当并发非常大的时候,会导致这两个调用占用了大量的 CPU 时间。为了绕开这两个相关调用,使用了 Sysfd 进行 Socket 读写超时的设置。 

bytes 的 Buffer 带来的性能问题

从下图可以看出,有相当大的一部分时间耗在了 slice 相关的操作上,原来在包的编解码过程中,使用 bytes.Buffer 进行临时存放,当 bytes.Buffer 底层用的 byte slice 大小不够的时候,就会分配一定的内存空间,频繁地分配效率很低,所以导致大包情况下性能下降比较明显。

解读 | TARS开源项目发布Go语言版本

联想到了 Redis 的内存模型和 Linux 的 slab 机制,对于频繁创建销毁的对象,采用预先创建和重复利用的方式。而 Go 本身提供了一种 sync.Pool 机制,供临时对象的复用,以减少 GC,Tars-Go 在此基础上,实现了类似 Linux slab 机制分配的 buffer 管理方案,通过这种方案,性能大幅提高。

其他方面的优化

解读 | TARS开源项目发布Go语言版本

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读