专栏名称: 腾讯开源
腾讯官方开源动态、开发经验分享
目录
相关文章推荐
51好读  ›  专栏  ›  腾讯开源

腾讯与阅文技术合作 微服务框架Tars再添PHP

腾讯开源  · 公众号  ·  · 2017-11-02 09:06

正文

作者介绍

梁晨(ted),任职阅文集团技术中心,负责起点的WEB后台开发工作。曾负责腾讯上海企业产品部营销QQWeb后台开发、QQ公众号Web后台开发,对大型网站技术架构,有自己的经验和见解。腾讯开源项目TSF2.0框架开发者,腾讯开源组件Tars-PHP开发者,也曾是腾讯公司多个PHP扩展组件的开发者与维护者。

引言

TARS作为由腾讯公司开源的优秀RPC框架与服务部署运维解决方案,被阅文集团引入了实际实践中,同时阅文集团对TARS在PHP语言层面进行了能力的补全,令TARS如虎添翼。TARS-PHP的解决方案兼具简单高效、接口维护方便容易扩展、代码自动生成,以及集成寻址、服务发现、监控、上报等功能。经历了阅文集团线上业务的考验与洗礼,充分证明了该解决方案的优势。

项目地址:
https://github.com/Tencent/Tars/tree/master/php (点击文末“阅读原文”直接访问)


“PHP是世界上最好的语言”

众所周知,在PHP诞生之初,就是WEB站点的开发而生。但是一直以来,都无法摆脱弱类型、脚本语言的性能之殇的帽子。随着互联网行业的不断发展,以及用户需求和基础架构的不断变化,PHP语言本身也一直在发展。无论是SWOOLE的出现,还是PHP7对性能的提升,都丰富和助力了PHP本身的应用。

相信大家在开发中也会发现,作为经常处在WEB中间层的PHP,其实有很多的痛点。既要接收前端的HTTP请求,又要调用各式各样的后台服务与存储服务,常常成为一个站点的性能瓶颈。其中HTTP协议的过分冗余以及上层封装带来的损耗,就是一个比较突出的问题。

开发者不但要应对使用同步的HTTP的调用库所带来的吞吐量的下降,还要忍受HTTP协议本身,以及JSON、XML协议在信息传输上的低效率。为了解决这一问题,一套在TCP协议层的,使用简单的二进制协议。才能保证业务用更少的传输带宽,承载更多的传输内容,从而提高吞吐量和WEB服务伺服能力。

同时,在实际开发的层面上,PHP逻辑层与后台服务之间通信协议的维护成本较高。同时,后台服务侧新增或修改接口字段,往往调用侧也要配合修改,很多时候无法保证接口的完全兼容而引发线上的运营问题。因此,这种二进制协议又要做到接口方便维护,同时又容易扩展。

除此之外,从开发效率上而言,原本的开发中总是包含大量的重复的,但又不得不去做的工作内容。因为每一次新协议的开发,代码很难复用,JSON和XML也并不允许你共用部分数据。同时一个很现实的问题是,不同HTTP接口的提供方,往往会视自己的心情和习惯来定义接口。

一个常见的例子就是对返回码的定义,有些人叫ret,有些人叫code,还有些人就叫r,简直是无所不包。因此这类重复无趣的开发工作,给调用方的开发同学带来了极大的生理和心理负担。基于这种需求,一种服务端和客户端都能够根据协议和接口自动生成调用代码,保证联调通畅的解决方案必不可少。

再者,调用方对后端服务的发现和调用的上报与监控,也是一个老生常谈的问题。后端服务如何被发现,后端的接口如何被发现,这都是调用方真真切切想知道的。同时,调用方非常有必要对后端服务的调用情况进行上报到中央服务器,中央服务器再根据收集上来的信息,对后端服务的负载进行动态的调整,保证服务的高可用。要实现这样的需求,必须引入一种集成了监控、主控寻址、上报通道、负载均衡功能的解决方案。

Tars作为腾讯公司的优秀RPC框架与服务部署运维解决方案,可以满足上述的所有需求。通过引入Tars-PHP的全套解决方案,开发者既可以使用二进制的Tars协议,大大压缩了服务请求的流量。同时也能够借助Tars协议解析的PHP扩展,提高了打包解包的性能进而提升了单进程的任务处理能力。再次,自动生成代码的工具也能够提升开发者的效率。


Tars-PHP解决方案

Tars-PHP的开源方案,首先从二进制的协议说起:


• 二进制协议

HTTP协议可能是在应用层上使用最为广泛的协议了。现有HTTP的版本主要是1.0和1.1版本。它在TCP协议的基础上做了十分简洁的应用层协议封装,纯文本的内容,以及Header和Body的区分。都使得这种协议的使用和理解十分的方便。但是不可避免的,使用和阅读的简单意味着信息的冗余,为了传输少量的内容,往往需要耗费大量的流量。

另外两个比较熟知的协议,就是JSON和XML了,这两位在API交互常用的协议中不分上下,可读性强、容易理解、语言客户端支持丰富、协议表述能力突出,都是两者的优势所在。先看看同样一段信息,两者需要的数据量。

假定有一所学校,一个学生,如果用JSON标识的话,如下所示:


很简单的结构,共需要65个字符来表述。

而如果换成XML:

则一共需要92个字符。从信息学的角度而言,信息熵明显就是太低了。所以为了实现通信的更高性能和更少带宽的使用,二进制协议的引入势在必行。

Tars协议作为一个二进制的协议,相比于上述两个协议的优势不言自明。从上文中的JSON和XML中发现其灵活性,也就是没有指定字段的类型。但是不可避免的,这种灵活带来了性能的大损失。因此Tars定义了八种基本的数据类型,通过对不同的数据类型进行编码优化:


而同时为了满足业务需求,扩展出了struct(包含任意字段)、vector(数组)、map(key-value结构)这三种可以嵌套数据,丰富协议表现力的复杂类型。

按照上文的表现结构,几个struct就可以完成。

首先是student结构体:

从注释中可以看到,三个字段需要的字节数为14,再加上结构体的开始和结构体结束的标识共2个字节,一共只需要16个字节而已。相比之下,这仅仅是JSON的1/4,是XML协议标识同样信息的1/5,高下立判. 巧妙地用协议强约定换传输可读性,这就是高信息熵的二进制协议的诀窍。

为了使得PHP能够充分与Tars结合,必须使其具备作为客户端和作为服务端两个方面的能力。


• Tars-PHP的客户端


作为客户端而言,要能够满足快速开发的需求,也要能够与PHP现有的常见使用方式相结合,同时还要给出远程调用的实例。基于这些需求,客户端方案中实现了如下的特性:

  • 实现了用TUP协议进行打包解包、编码解码的PHP扩展及相应的测试用;

  • 实现了从Tars协议文件生成对应PHP类文件的tars2php工具;

  • 实现了包含网络库的二次封装,以及远程调用的代码示例;

作为客户端实现的最核心一步,就是对TUP协议的支持。TUP协议是在Tars协议的上层,通过固定的数据结构封装一些收发包必须的信息,如返回值、输入输出参数、包本身的状态、包计数等,来给非Tars原生客户端与Tars服务端进行通信的协议。Tars-PHP在支持TUP协议的方案中,选择了使用PHP扩展作为实现方式。







请到「今天看啥」查看全文