Author Yang Zhangyong
Editor's Little Assistant TARS
Introduction to Tars TarsPHP
Tars is a micro-service development framework that Tencent has been using from 2008 to today. It became an open source project of the Linux Foundation in 2018. It currently supports C++, Java, PHP, NodeJS and Go languages. The framework provides users with a set of solutions involving development, operation and maintenance, as well as testing, to help a product or service develop, deploy, test and go online quickly. It integrates scalable protocol coding and decoding, high performance RPC communication framework, name routing and discovery, publishing and monitoring, log statistics and configuration management. It can quickly build its own stable and reliable distributed applications in the way of micro services, and achieve complete and effective service governance.
TarsPHP, as a solution of Tars in PHP language, is mainly designed in the following four aspects:
- Perfect Functions: Marking Existing C++, Java and NodeJS System Functions
- Flexibility: On Flexibility, Who Competes with PHP
- Lightweight: Use the lightest design, point to point, plug and play
- Efficiency: Plug Swoole's wings and have to fly
Introduction to Protobuf
Protocol buffers (PB) is an open source language neutral, platform independent, extensible format for serialized data, which can be used for communication protocols, data storage, etc. It is similar to XML, but smaller, faster and simpler than XML.
PB is a coding protocol. If it involves network transmission and RPC calls, it is necessary to introduce a communication protocol. Google's open source RPC framework gRPC uses Http2 as the communication protocol and PB as the coding protocol.
Building PB Server with TarsPHP
Initialization environment
Protoc Installation
First, you need to install the protoc library, whose main function is to package and unpack protobuf protocol data. For reference https://github.com/protocolbu... Direct installation.
./autogen.sh ./configure make make install
If protoc-version can output normally, the installation is complete
php protobuf installation
Then you need to install the php protobuf extension, which serves as a bridge between the php and protoc libraries.
git clone https://github.com/protocolbuffers/protobuf.git cd ./php/ext/google/protobuf/ phpize ./configure make make install (Need editing php.ini Document, Open protobuf Extension)
If php-ri protobuf has an output, the installation is normal.
Swoole Installation
It is recommended to use version 4.4.0 or above, and http2 and openssl support need to be turned on.
Write a proto file
Referring to the tars file of comment service in ActDemo in TarsPHP, we have written a protocol file of actComment.proto.
Unlike tars protocol file, proto protocol stipulates that input and output parameters must and can only be a message structure, so it is necessary to encapsulate a message for input and output parameters separately.
syntax = "proto3"; package protocol.QD.ActCommentPbServer; //The package name generates the php class path based on the package name service CommentObj { rpc ping(PingRequest) returns (PingResponse) {}; rpc getCommentCount(CountRequest) returns (CountResponse) {}; rpc createComment(CreateRequest) returns (CreateResponse) {}; rpc getComment(GetRequest) returns (GetResponse) {}; } //General Structures for Input Parameters message CommonInParam { int32 appId = 1; int32 areaId = 2; int64 userId = 3; //User Information string userIp = 4; //Source name string serverIp = 5; //Caller server ip }; //Universal structure for output parameters message CommonOutParam { int32 code = 1; //Interface Return Code string message = 2; //Interface returns prompt information }; 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; };
Generate server-side code
protoc can generate corresponding php class code based on proto file, but the official does not support proto file to generate server-side code, you can use gRPC plug-in to generate client code. If we need to use the generated client code, we also need to install the grpc library and the grpc php extension.
So our idea is to use protoc to generate the classes needed by php, and then parse the proto file to generate the server-side interface. This process is very similar to the existing tars2php process, so we call it proto2php.
Because of the difficulty of using two tools to generate proto, we integrate the process of calling proto into proto2php for your convenience.
Let's first build a tars.proto.php setting up some basic information.
return array( 'appName' => 'QD', 'serverName' => 'ActCommentPbServer', 'objName' => 'CommentObj', 'withServant' => true, //Decide whether it's the server or the automatic generation of the client 'tarsFiles' => array( './actComment.proto', ), 'dstPath' => '../src/protocol', //This specifies the location where impl underlying interface is generated 'protocDstPath' => '../src', //The problem specified here is protoc generation 'namespacePrefix' => 'Protocol', );
Then execute php... / src/vendor/php tars/tars2php/src/proto2php.php. / tars.proto.php
The GPBMetadata and protocol directories are then generated. The PHP class generated by proto file is in protocol, and CommentObjServant.php is the server-side interface class generated by proto2php file. To build TarsPHP pb server, you need to implement this class.
Deployment of TarsPHP PB server
Deploy tarsphp pb server according to Readme in Demo.
A few points should be noted:
- The interface logic needs to be implemented in the impl directory.
- In services.php under src, specify the home-api, home-class location, protocolName is pb, serverType is grpc
- The protocol type on tars platform is tcp, which is not tars protocol.
- require "google/protobuf" needs to be added to composer.json, and Protocol and GPBMetadata need to be configured in autoload, such as the following:
{ "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" } }
Finally, composer run-script deploy is executed, code package is generated and uploaded to Tars platform for publication.
Access with client
You can use the php client generated by gRPC to access the test, or you can use swoole's http2 client directly to build a grpc client.
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); //Note here that it may not be possible to modify the ip 127.0.0.1 that your service binds to tars $response = new GetResponse(); $response->mergeFromString(substr($ret, 5)); foreach ($response->getList() as $row) { var_dump($row->getContent()); } }); } }
Perform php client.php observation to return.
Generate client-side code
The client mentioned above is just a simple demo for accessing PB server, which can help us test the status of PB server. How should PB server be used if it needs to be invoked in other Tars services? Similar to Tars, we also provide a way to generate PB client-side code.
Here we use QD.ActHttpServer under TarsActDemo as an example to demonstrate how to generate Tars PB client code and call PB service.
- Copy the actComment.proto file to the tars directory
- Construct actCommentPb.proto.php file, content is consistent with tars.proto.php content used to generate server code, modify withServant = false
- Execute php... / src/vendor/phptars/tars2php/src/proto2php.php. / actCommentPb.proto.php
- The generated code can then be seen in protocol/QD/ActCommentPbServer. (Similar to Server-side code, CommentObjServant.php is generated by proto2php and other files are generated by proto2php calling protoc plug-ins)
- Similar to Server, GPBMetadata and Proteocol need to be added to psr-4 of composer.json.
- Similar to Tars calls, you can directly call related methods of CommentObjServant class and PB service communication. Note that the socket model in the incoming Communicator Config needs to be set to 4 grpc mode.
Examples are as follows:
$inParam = new CountRequest(); $outParam = new CountResponse(); $conf = self::getConfig(); $conf->setSocketMode(4); $servant = new CommentObjServant($conf); $servant->getCommentCount($inParam, $outParam); return $outParam->getCount();
Different from the PB support in TarsGo
The support of PB in TarsGo is essentially the support of proto protocol file, which provides the ability to convert proto protocol file into tars protocol. The tars protocol is actually used in mutual invocation. This service can work with other Tars services.
The support of PB in TarsPHP is to build a gRPC service, which is deployed on the Tars platform, participates in the addressing of the Tars platform and is managed by the Tars platform. This service uses gRPC on Http2 as the network communication protocol, Protobuf as the coding protocol, and can work with other PB client s.
The two directions are different and can not be mixed. I hope you can distinguish them.
related data
We use the same Http service, using Tars and Pb protocol and back-end service to communicate and measure.
Server environment: 2 core 4G, php 7.2.16, swoole 4.4.0
Service empty run refers to a simple ping to back-end service, which returns directly without any business processing.
A single simple RPC refers to the return of an int to the number of barrages retrieved from the back-end service, the quantity rand generated, and the mysql count is not used.
A single complex PRC will actually retrieve the structure of the bullet list from the back end, including the complete structure of multiple bullet objects.
From the piezometric data, the performance of Tars is better than that of PB, but comparing the performance of PB with that of Tars, it is found that the performance of PB is slightly better than that of Tars. The main reason for this result is that gRPC uses Http2 as its communication protocol, which requires more overhead than Tars'custom communication protocol.
Write at the end
TarsPHP project source address: https://github.com/TarsPHP/Ta...
All versions of TARS source address: https://github.com/TarsCloud
(If you like, remember to order a star for the project!)
TARS-PHP QQ Group: 7695317344