热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

TarsPHP新版本发布,支持Protobuf协议

Tars是腾讯从2008年到今天一直在使用的后台逻辑层的统一应用框架TAF(TotalApplicationFramework),目前支持C++、Java、PHP、Nodejs与Go语言。该框架为用户提供了涉及到开发、运维,以及测试的一整套解决方案,

Tars是腾讯从2008年到今天一直在使用的后台逻辑层的统一应用框架TAF(Total Application Framework),目前支持C++、 Java 、 PHP 、Nodejs与 Go 语言。该框架为用户提供了涉及到开发、运维,以及测试的一整套解决方案,帮助一个产品或者服务快速开发、部署、测试、上线。它集可扩展协议编解码、高性能RPC通信框架、名字路由与发现、发布监控、日志统计、配置管理等于一体,通过它可以快速用微服务的方式构建自己的稳定可靠的分布式应用,并实现完整有效的服务治理。

TarsPHP作为Tars在PHP语言的解决方案,设计的时候主要考虑如下四个方面:

  • 功能完善:对标现有C++、Java与NodeJS体系功能
  • 灵活:论灵活,谁与PHP争锋?
  • 轻量:用最轻量的设计,点到即止,即插即用
  • 高效:插上Swoole协程的翅膀,不得不飞

Protobuf简介

Protocol buffers (简称PB)是Google开源的语言中立,平台无关,可扩展的序列化数据的格式,可用于通信协议,数据存储等。它和XML类似,但比XML更小,更快,更简单。

PB是编码协议,如果涉及到网络传输和RPC调用,就需要引入通讯协议。Google开源的RPC框架gRPC就使用Http2作为通讯协议,PB作为编码协议。

和TarsGo中关于PB支持的不同

TarsGo中关于PB的支持,本质是对proto协议文件的支持,提供将proto协议文件转换为tars协议的能力,在相互调用中实际使用的是tars协议。这个服务可以和其他Tars服务相互工作。

TarsPHP中关于PB的支持,是构建了一个gRPC服务,这个服务部署在Tars平台上,参与tars平台寻址,受tars平台管理。这个服务使用gRPC on Http2作为网络通讯协议,使用Protobuf作为编码协议,可以和其他PB client 相互工作。

两者方向不同,不能混合使用,希望大家区分。

相关数据

我们使用相同Http服务,分别使用Tars和Pb协议和后端服务通讯并进行压测。

  • 服务器环境:2核 4G,php 7.2.16,swoole 4.4.0
  • 服务空跑指的是简单的ping到后端服务,不进行任何业务处理直接返回;
  • 单次简单RPC指的是向后端服务获取弹幕数量返回一个int,数量值rand生成,并没有使用mysql count;
  • 单次复杂PRC会实际向后端获取弹幕列表结构体,包含多条弹幕对象完整结构。
QDPS PB TARS
服务空跑 3800 6200
单次简单RPC 3600 6150
单次复杂RPC 1050 1150

从压测数据来看,Tars性能比PB高出一截,但对比两者打包解包性能发现PB打包解包性能略优于Tars,导致这样结果的主要原因我认为是gRPC使用Http2作为通讯协议相比Tars的自定义通讯协议需要跟多开销。

使用TarsPHP 构建 PB Server

初始化环境

  • Protoc 安装

    • 首先需要安装protoc库,这个库的主要作用是打包解包protobuf协议数据。可以参考 https://github.com/protocolbuffers/protobuf/tree/master/src 直接安装。

      ./autogen.sh
      ./configure
      make
      make install
      

      如果 protoc –version 可以正常输出,说明安装完成

  • php protobuf安装

    • 之后需要安装 php protobuf扩展,这个扩展主要用作php和protoc库中间的一个桥梁。

      git clone https://github.com/protocolbuffers/protobuf.git
      cd ./php/ext/google/protobuf/
      phpize
      ./configure
      make
      make install
      (需要编辑php.ini文件,开启protobuf扩展)
      

      如果 php –ri protobuf 有输出,说明安装正常。

  • Swoole 安装

    • 建议使用4.4.0或以上版本,需要开启http2 和 openssl支持。

编写一个proto文件

参考TarsPHP中ActDemo中评论服务的tars文件,我们写了一个actComment.proto的协议文件。

和tars协议文件不同,proto协议中规定输入输出参数必须也只能是一个message结构体,因此需要对输入输出参数单独在封装一个message。

syntax = "proto3";  
  
package protocol.QD.ActCommentPbServer;  //包名,会根据包名生成 php类路径

service CommentObj {  
  rpc ping(PingRequest) returns (PingResponse) {};  
  
  rpc getCommentCount(CountRequest) returns (CountResponse) {};  
  
  rpc createComment(CreateRequest) returns (CreateResponse) {};  
  
  rpc getComment(GetRequest) returns (GetResponse) {};  
}  
  
//输入参数通用结构体  
message CommonInParam {  
    int32 appId = 1;  
    int32 areaId = 2;  
    int64 userId = 3; //用户信息  
    string userIp = 4; //来源名称  
    string serverIp = 5; //调用方服务器ip  
};  
  
//输出参数通用结构体  
message CommonOutParam {  
    int32 code = 1;  //接口返回码  
    string message = 2;  //接口返回提示信息  
};  
  
message SimpleComment {  
    int32 id = 1;  
    int64 activityId = 2;  
    int64 userId = 3;  
    string cOntent= 4;  
    string title = 5;  
    string ext1 = 6;  
    int64 createTime = 7;  
};  
  
message QueryParam {  
    int64 activityId = 1;  
    int32 page = 2;  
    int32 size = 3;  
    int32 orderType = 4;  
};  
  
message CreateRequest {  
    CommonInParam inParam = 1;  
    SimpleComment comment = 2;  
};  
  
message CreateResponse {  
    CommonOutParam outParam = 1;  
};  
  
message GetRequest {  
    CommonInParam inParam = 1;  
    QueryParam queryParam = 2;  
};  
  
message GetResponse {  
    CommonOutParam outParam = 1;  
    repeated SimpleComment list = 2;  
};  
  
message PingRequest {  
};  
  
message PingResponse {  
};  
  
message CountRequest {  
};  
message CountResponse {  
    int32 count = 1;  
};

生成server端代码

protoc可以根据proto文件生成对应的php类代码,但是官方并不支持proto文件生成server端代码,可以使用gRPC插件生成client代码。如果需要使用生成的client代码我们还需要安装grpc库和grpc php扩展。

因此我们的思路是,先使用protoc生成php需要的类,然后自己解析proto文件生成server 端interface,这个过程非常像现有的tars2php的过程,因此我们叫它proto2php。

由于使用两个 工具 生成还比较麻烦,我们把调用proto的过程集成到proto2php中方便大家使用。

我们先构建一个tars.proto.php设置一些基本信息。

return array(
    'appName' => 'QD',
    'serverName' => 'ActCommentPbServer',
    'objName' => 'CommentObj',
    'withServant' => true, //决定是服务端,还是客户端的自动生成
    'tarsFiles' => array(
        './actComment.proto',
    ),
    'dstPath' => '../src/protocol', //这里指定的是 impl 基础interface 生成的位置
    'protocDstPath' => '../src', //这里指定的是 protoc 生成的问题
    'namespacePrefix' => 'Protocol',
);

然后执行 php …/src/vendor/phptars/tars2php/src/proto2php.php ./tars.proto.php
之后会生成GPBMetadata目录和protocol目录。其中protocol中就是proto文件生成的php类,另外CommentObjServant.php就是proto2php文件生成的server端interface类。构建TarsPHP pb server需要实现这个类。

部署TarsPHP PB server

按照Demo中 Readme部署tarsphp pb server即可。

几点注意:

  1. 需要在impl目录中实现interface逻辑。
  2. 在src下的services.php中指定home-api,home-class位置,protocolName是pb,serverType是grpc
  3. tars平台上协议类型是 tcp,非tars协议。
  4. 需要在composer.json中添加require “google/protobuf”,autoload中需要配置 Protocol 和 GPBMetadata,范例如下:
    {
        "name" : "tars-tcp-server-demo",
        "description": "tars tcp server",
        "require": {
            "phptars/tars-server": "~0.3",
            "phptars/tars-deploy": "~0.1",
            "phptars/tars-log": "~0.1",
            "phptars/tars2php": "~0.1",
            "ext-zip" : ">=0.0.1",
            "google/protobuf": "^3.8"
        },
        "autoload": {
            "psr-4": {
                "Server\\" : "./",
                "Protocol\\" : "./protocol",
                "GPBMetadata\\" : "./GPBMetadata"
            }
        },
        "minimum-stability": "stable",
        "scripts" : {
            "deploy" : "\\Tars\\deploy\\Deploy::run"
        }
    }
    

最后执行 composer run-script deploy,生成代码包,上传到Tars平台上发布。

使用client 访问

可以使用gRPC生成的php客户端访问测试,也可以直接使用swoole 的http2客户端构建一个grpc客户端。

class TestGrpcClient
{
    public static function callGrpc($ip, $port, $path, $requestBuf)
    {
        $cli = new Swoole\Coroutine\Http2\Client($ip, $port, false);
        $cli->connect();
        $req = new swoole_http2_request;
        $req->method = 'POST';
        $req->path = $path;
        $req->headers = [
            "user-agent" => 'grpc-c/7.0.0 (linux; chttp2; gale)',
            "content-type" => "application/grpc",
            "grpc-accept-encoding" => "identity,deflate,gzip",
            "accept-encoding" => "identity,gzip",
            "te" => "trailers",
        ];
        $req->pipeline = false;
        $req->data = $requestBuf;
        $cli->send($req);
        $respOnse= $cli->recv();
        return $response->data;
    }

    public static function main()
    {
        $commOnIn= new CommonInParam();
        $commonIn->setUserId(0);
        $commonIn->setAppId(1);
        $commonIn->setAreaId(10);
        $commonIn->setServerIp('127.0.0.1');
        $commonIn->setUserIp('');

        $query = new QueryParam();
        $query->setActivityId(123);
        $query->setPage(1);
        $query->setSize(10);
        $query->setOrderType(1);

        $request = new GetRequest();
        $request->setInParam($commonIn);
        $request->setQueryParam($query);
        
        $requestBuf = $request->serializeToString();
        $packBuf = pack('CN', 0, strlen($requestBuf)) . $requestBuf;

        go(function () use ($packBuf){
            $path = "/protocol.QD.ActCommentServer.CommentObj/getComment";
            $ret = self::callGrpc('127.0.0.1', 10008, $path, $packBuf); //这里注意要修改成你服务在tars上绑定的ip 127.0.0.1不一定可以
            $respOnse= new GetResponse();
            $response->mergeFromString(substr($ret, 5));
            foreach ($response->getList() as $row) {
                var_dump($row->getContent());
            }
        });
    }
}

执行php client.php观察返回。

生成client端代码

前面提到的client,只是我们访问PB server 的简单demo,可以帮助我们测试PB server的状态。如果需要在其他Tars服务中调用PB server应该如何使用呢?和Tars类似我们也提供了生成PB client端代码的方式。

这里使用TarsActDemo下的QD.ActHttpServer为范例演示如何生成Tars PB client代码并调用PB服务。

  1. 拷贝actComment.proto文件到tars目录
  2. 构建actCommentPb.proto.php 文件,内容和生成server代码用的tars.proto.php内容一致,修改 withServant = false
  3. 执行 php …/src/vendor/phptars/tars2php/src/proto2php.php ./actCommentPb.proto.php
  4. 之后在protocol/QD/ActCommentPbServer 中可以看到相关生成代码。(和Server 端代码类似,CommentObjServant.php是 proto2php生成的,其他文件是proto2php 调用 protoc 插件生成的)
  5. 和Server端类似需要添加 GPBMetadata 和 Protocol 到composer.json 的psr-4中。
  6. 和Tars 调用类似,可以直接调用CommentObjServant类的相关方法和PB 服务通讯。需要注意的是 传入的 CommunicatorConfig 中的socketModel 需要设置为 4 grpc 模式。

范例如下:

$inParam = new CountRequest();  
$outParam = new CountResponse();  
  
$cOnf= self::getConfig();  
$conf->setSocketMode(4);  
  
$servant = new CommentObjServant($conf);  
$servant->getCommentCount($inParam, $outParam);  
  
return $outParam->getCount();

欢迎给项目点 star 并参与贡献。

https://github.com/TarsPHP/TarsPHP

作者:张勇


以上所述就是小编给大家介绍的《TarsPHP 新版本发布,支持 Protobuf 协议》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 我们 的支持!


推荐阅读
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • mysql-cluster集群sql节点高可用keepalived的故障处理过程
    本文描述了mysql-cluster集群sql节点高可用keepalived的故障处理过程,包括故障发生时间、故障描述、故障分析等内容。根据keepalived的日志分析,发现bogus VRRP packet received on eth0 !!!等错误信息,进而导致vip地址失效,使得mysql-cluster的api无法访问。针对这个问题,本文提供了相应的解决方案。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 先看一段错误日志:###Errorqueryingdatabase.Cause:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransie ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
author-avatar
嘉sen
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有