当前位置: 首页 > 后端技术 > PHP

gRPC入坑

时间:2023-03-29 14:02:16 PHP

总结由于gRPC主要由Google开发,由于一些已知的原因,gRPC的demo还是不太顺利。单独写这篇文章,主要是gRPC安装过程中坑太多,记录一下,免得大家走弯路。主要坑:如果使用PHP或者Python开发gRPC客户端,需要编译gRPC命令行工具生成proto代码生成插件,否则无法编译proto中定义的服务。编译需要使用GCC4.8以上版本,否则报不支持C++11。然后下周需要加速grpc源码,下载大量的第三方依赖。这个过程非常痛苦。使用golang和java的可以忽略。PHP也需要遵循grpc的c扩展。编译需要使用GCC4.8或更高版本。如果使用golang开发服务,依赖的第三方服务基本下载不了。github仓库需要使用gomod添加映射规则,github下载速度慢。本文在讲解gRPCdemo的同时说明了如何解决这些陷阱。本文对应的Github地址:https://github.com/52fhy/grpc...。仓库存放demo示例和一些系统编译好的二进制包。每个人都认为有些步骤花费的时间太长。可以直接clone仓库,把二进制包复制到对应目录下(只做测试开发,生产环境还是老老实实自己编译吧)。升级GCCgRPC命令行工具编译,需要使用GCC4.8及以上版本。CentOS6系列内置版本为GCC4.7。使用gcc--version查看版本。如果您的系统GCC版本>=4.8,您可以忽略此部分。如果你只使用golang、java,请忽略此部分。注意:不建议大家下载GCC源码包或者使用yum下载GCC4.8及以上版本。原因:1)安装源码包真的非常非常慢2)yum源码的下载速度慢得像蜗牛。下面的SCL安装方法推荐给大家使用,安装后还是可以使用原版的。如果需要将gcc升级到4.8或更高版本,建议安装SCL源后直接安装devtoolset-6(devtoolset-6当前gcc版本为6.3),因为devtoolset-4及之前的版本已经结束支持和只能通过其他方式安装。升级到gcc6.3:yum-yinstallcentos-release-sclyum-yinstalldevtoolset-6-gccdevtoolset-6-gcc-c++devtoolset-6-binutilssclenabledevtoolset-6bash需要注意的是scl命令的启用只是暂时的。退出shell或重启都会恢复原来的系统gcc版本。如果想长期使用gcc6.3:echo"source/opt/rh/devtoolset-6/enable">>/etc/profile,然后退出shell,重新打开就可以看到新版本的gcc了。这同样适用于其他版本。升级到gcc7.3:yum-yinstallcentos-release-sclyum-yinstalldevtoolset-7-gccdevtoolset-7-gcc-c++devtoolset-7-binutilssclenabledevtoolset-7bash已经停止支持devtoolset4(gcc5.2)及之前的了版本的安装方法可能比较慢,有兴趣的可以试试。升级到gcc4.8:wgethttp://people.centos.org/tru/devtools-2/devtools-2.repo-O/etc/yum.repos.d/devtoolset-2.repoyum-yinstalldevtoolset-2-gccdevtoolset-2-gcc-c++devtoolset-2-binutilsscl启用devtoolset-2bash升级到gcc4.9:wgethttps://copr.fedoraproject.org/coprs/rhscl/devtoolset-3/repo/epel-6/rhscl-devtoolset-3-epel-6.repo-O/etc/yum.repos.d/devtoolset-3.repoyum-yinstalldevtoolset-3-gccdevtoolset-3-gcc-c++devtoolset-3-binutilsscl启用devtoolset-3bash升级到gcc5.2:wgethttps://copr.fedoraproject.org/coprs/hhorak/devtoolset-4-rebuild-bootstrap/repo/epel-6/hhorak-devtoolset-4-rebuild-bootstrap-epel-6.repo-O/etc/yum.repos.d/devtoolset-4.repoyuminstalldevtoolset-4-gccdevtoolset-4-gcc-c++devtoolset-4-binutils-ysclenabledevtoolset-4bashcompilegRPCcommandlinetools如果只使用golang,java,请忽略此部分。gRPC分为C、JAVA、GO、NodeJS版本。C版本包括C++、Python、Ruby、Objective-C、PHP和C#。这些语言都是基于C版本开发的,共享一个代码库。C版:https://github.com/grpc/grpcJAVA版:https://github.com/grpc/grpc-...GO版:https://github.com/grpc/grpc-goNode版:https://github.com/grpc/grpc-...如果你使用的是C版本的gRPC,你最终会从源码中编译出以下工具:对于原型编译器。你需要先在grpc/grpcgithub上下载源码。gitclone-b$(curl-Lhttps://grpc.io/release)https://github.com/grpc/grpccdgrpcgitsubmoduleupdate--initmake&&sudomakeinstall#生成的插件路径ll./bins/opt/#复制到bin目录cp-r./bins/opt/*/usr/local/bin/这里有2个坑:1.grpc/grpc仓库比较大。鉴于国内访问速度,建议使用国内镜像。码云(https://gitee.com)提供了一个同步更新的镜像地址:gitclonehttps://gitee.com/mirrors/grpc-frameworkgrpc这样下载速度提升不少。2.gitsubmoduleupdate命令实际上是将.gitmodules文件中定义的第三方依赖下载到third_party目录下。有很多依赖关系。您可以打开.gitmodules文件查看详细信息。依赖的仓库都在github上,下载几个小时都下载不下来,只能等下载慢了。回过头来看,我们花了很多时间,才搞定grpc的proto编译插件。好处:Mac下编译好的二进制包:https://files.cnblogs.com/fil...。下载并解压以上文件,将bins/opt/下的所有文件复制到/usr/local/bin/下。如果您只使用golang和java进行PHP相关支持,请忽略本节。PHP目前不支持充当grpc服务器。作为客户端,可以并且需要在机器上安装:protoc编译工具protobufcextensiongRPC命令行工具(grpc_php_plugin)grpccextensiongrpcphplibrary其中protoc和protobufcextension已经在Protobufsmall中介绍过了测试,这里就不赘述了。如果上一节安装成功,那么grpc_php_plugin也是可用的。下面介绍如何安装PHP版的gRPC库。安装grpcc扩展:要求:GCC编译器需要4.8及以上版本。可以使用pecl安装:peclinstallgrpc也可以指定版本:peclinstallgrpc-1.12.0或者下载源码(http://pecl.php.net/package/grpc)安装:wgethttp:///pecl.php.net/get/grpc-1.21.3.tgztarzxvfgrpc-1.21.3.tgz&&cdgrpc-1.21.3phpize./configuremakemakeinstallgrpc/grpc代码库还有PHP扩展的C源码,在grpc/src/php/ext/grpc目录也可以直接编译。编译后在php.ini中添加,使用php--rigrpc查看信息。安装C扩展后,还需要使用composer安装grpc库:composerrequiregrpc/grpcgRPCExampleWritinggRPCproto定义了三个文件:└──proto├──GreeterService.proto├──Response.proto└──在User.proto中,User定义为Model,Response用于RPC统一返回定义,GreeterService定义为服务接口。限于篇幅,proto文件详见https://github.com/52fhy/grpc...仓库的proto目录。GreeterService.proto文件内容如下:syntax="proto3";packageSample.Model;//namesapceimport"User.proto";import"Response.proto";serviceGreeter{//发送一个问候rpcSayHello(User)returns(Response){}}这里定义了一个服务,相当于定义了一个服务接口。我们定义了方法名和参数,后面需要实现。由于gRPC不支持PHP作为服务端,这里我们使用Golang作为服务端。首先需要使用proto工具编译golang代码:mkdir-pPb_Go#Compilecdprotoprotoc--go_out=plugins=grpc:../Pb_Go/*.protocd-如果提示protoc-gen-go找不到,请参考文章介绍(https://www.cnblogs.com/52fhy...)进行安装。如果执行成功,会在Pb_Go目录下生成Go代码:Pb_Go├──GreeterService.pb.go├──Response.pb.go└──User.pb.go如果需要生成PHP客户端代码,你需要使用grpcphp命令行工具grpc_php_plugin,如果前面的总结执行成功,说明这个工具已经存在了。然后:out=output/phpmkdir-p$out#Compilecdprotoprotoc--php_out=../$out--grpc_out=../$out--plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin*.protocd-#修改命名空间cd$outmvGPBMetadataSample/Model/find.-名称'*.php'!-nameexample.php-execsed-i""-e's#GPBMetadata#Sample\\Model\\GPBMetadata#g??'-e's#\\Sample\\Model\\GPBMetadata\\Google#\\GPBMetadata\\谷歌#g'{}\;以上是在Mac下操作,命令与Linux有些区别。gRPC编译工具在CentOS下没有编译。最终生成的文件:├──output│└──php│└──Sample│└──Model│├──GPBMetadata││├──GreeterService.php││├──Response.php││└──User.php│├──GreeterClient.php│├──Response.php│├──User.php│└──UserList.php注意:如果不加--grpc_out=../$out--plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin,生成的PHP类没有GreeterClient。该文件由gRPC编译工具自动生成,用于连接gRPC服务器。Go编写服务我们使用Golang来编写服务端。上面虽然生成了部分Golang代码,但是真正的服务还没有写出来。main.go首先,让我们创建一个新的main.go。代码不多,直接贴出来:golang.org/grpc")const(addr=":50051")//server用来实现helloworld.GreeterServer.typeserverstruct{}//SayHello实现helloworld.GreeterServerfunc(s*server)SayHello(ctxcontext.Context,u*pb.User)(*pb.Response,error){return&pb.Response{ErrCode:0,ErrMsg:"success",Data:map[string]string{"name":"Hello"+u.Name}},nil}funcmain(){lis,err:=net.Listen("tcp",addr)iferr!=nil{log.Fatalf("failedtolisten:%v",err)}fmt.Printf("%sserverstartat%s\n",time.Now(),addr)s:=grpc.NewServer()pb.RegisterGreeterServer(s,&server{})s.Serve(lis)}然后它可以被编译。有个大坑:gobuildmain.go时,会先下载go.mod中定义的依赖(依赖有很多,详见:https://github.com/52fhy/grpc...),下面的非常慢,repo太大了,虽然重定向到github:替换google.golang.org/api=>github.com/googleapis/google-api-go-clientv0.6.1-0.20190616000641-99157d28da34快速下载,我在码云上做了一个镜像,地址:gitee.com/52fhy/google-api-go-client。更改后,下载速度更快。编译成功后生成二进制文件main。我们可以直接运行:$./main2019-06-3017:16:07.752508+0800CSTm=+0.028838467serverstartat:50051gotest为了测试我们写的服务是否正常,我们可以写一个测试用例:test_client.gopackagemainimport("context""google.golang.org/grpc"pb"grpc-sample/Pb_Go""testing")funcTestExec(t*testing.T){conn,err:=grpc.Dial(":50051",grpc.WithInsecure())iferr!=nil{t.Errorf("dialerror:%v\n",err)}deferconn.Close()//实例化客户端client:=pb.NewGreeterClient(conn)//调用服务user:=pb.User{}user.Id=1user.Name="test"result,err:=client.SayHello(context.Background(),&user)iferr!=nil{t.Errorf("grpcerror:%v\n",err)}t.Logf("Recevied:%v\n",result)}运行:$gotest-vclient_test.go===RUNTestExec---PASS:TestExec(0.01s)client_test.go:29:Recevied:errMsg:"success"data:PASSokcommand-line-arguments0.021s运行有点慢,而且感觉依赖librar太多了即。php客户端使用gRPCPHP客户端,确保你已经安装:protobufcextendsgrpccextendsgrpcphplibrary例子:client_test.phpsetId(1)->setName("test");$client=newGreeterClient("192.168.99.1:50051",['credentials'=>ChannelCredentials::createInsecure(),//不加密//'timeout'=>3000000,]);//分别响应,状态对象列表($reply,$status)=$client->SayHello($user)->wait();if(!$reply){echojson_encode($status);return;}//序列化为字符串echo$reply->serializeToJsonString(true).PHP_EOL;回显$reply->getErrCode()。PHP_EOL;//errCodeecho$reply->getErrMsg().PHP_EOL;//errMsg//dataforeach($reply->getData()as$key=>$value){echo$key.“-”。$价值。PHP_EOL;}运行后输出:$phptests/client_test.php{"errMsg":"success","data":{"name":"Hellotest"}}0successname-Hello测试FAQ1.CentOS6使用gomod获取第三方依赖包unknownrevisionxxx错误解决方法:其实在gomod的调用链中使用了一些git指令。提示信息不明确的方法是升级git版本,CentOS6自带的git是1.7版本。升级后,再次尝试gomod。快速升级方法:centos6:#安装yum源wgethttp://opensource.wandisco.com/centos/6/git/x86_64/wandisco-git-release-6-1.noarch.rpm&&rpm-ivhwandisco-git-release-6-1.noarch.rpm##Installgit2.xyuminstallgit-y##Verifygit--versiongitversion2.14.12,PHPerror:Fatalerror:Class'GoogleProtobufInternalMessage'notfound解决方法:请安装PHPprotobuf-c扩展名。3.PHP报错:Fatalerror:Class'GrpcBaseStub'notfound解决方法:使用composerrequiregrpc/grpc安装grpc。另外,相应的grpcC扩展也要安装。4、github发布包下载慢怎么办?解决方法:下载Mac版的FreeDownloadManager下载工具,解决GitHub下载慢或失败的问题。速度呼啸而过。参考1、CentOS6、7升级gcc到4.8、4.9、5.2、6.3、7.3等高版本http://www.vpser.net/manage/c...2、使用centos6.x/7。xyum升级git版本-夜空https://blog.slogra.com/post-...3.Protobuf小测-飞鸿鹰https://www.cnblogs.com/52fhy...