目前微服務這麼流行,RPC架構也是百花齊放,本文講述一下mac下grpc的開發環境搭建,其中server端使用golang,用戶端使用php。
服務端
golang grpc安裝
這裡列出了一個參考,由於grpc在github上的檔案目錄有改動,所以直接按官方的安裝,會出404資源無法找到的問題。
需要先在本地安裝golang+grpc。具體可參考:golang安裝grpc
操作完之後,在終端運行:protoc --version,能看到版本資訊
同時,protoc-gen-go命令應該也已經被安裝
查看protoc版本資訊
php grpc用戶端
擴充有幾個,推薦使用官方的。
當然,另外一個也相當不錯,datto的protobuf擴充。使用datto的這個的時候,我用perl根據其文檔安裝失敗,既然官方的ok了,也就懶得再去折騰了。
官方的具體的安裝流程,剛剛給的github的網址上有詳細的說明,根據步驟走,就ok了。
安裝完之後,為了在nginx下使用,應該裝grpc這個擴充:
php的grpc擴充安裝成功查看
開始Demo
官方給了一個helloworld.proto的demo,咱們按樣子,增加一個,目錄結構如下:demo目錄結構
app和meta,放的是protoc編譯之後的服務端的go的源碼。
grpc,將protoc編譯成PHP所需要的工具及源碼(即:grpc_php_plugin)
phpClient,是protoc編譯出來的php的源碼,下面的vendor檔案夾是composer載入的grpc/grpc的php用戶端的串連服務端的源碼
上源碼
先建立檔案夾:mkdir grpc_demo
meta.proto的源碼
syntax = "proto3";package meta;service Agent { rpc GetInfo (MetaRequest) returns (MetaResponse);}message MetaRequest { string appId = 1;}message MetaResponse { string appId = 1; string title = 2; string name = 3; string logo = 4;}
編譯成golang檔案:
protoc --go_out=plugins=grpc:./meta ./meta.proto
編譯成php檔案:
protoc --proto_path=./ \ --php_out=phpClient/meta \ --grpc_out=phpClient/meta \ --plugin=protoc-gen-grpc=./grpc/bins/opt/grpc_php_plugin \ meta.proto
編寫main.go檔案:(此處把helloworld.proto這個demo也加進來了)
package mainimport ( "log" "net" pb "grpc_demo/app" meta "grpc_demo/meta" "golang.org/x/net/context" "google.golang.org/grpc")const ( port = ":50051")// server is used to implement helloworld.GreeterServer.type server struct{}// SayHello implements helloworld.GreeterServerfunc (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello " + in.Name + "--from jacky_chen"}, nil}func (s *server) GetInfo(ctx context.Context, in *meta.MetaRequest) (*meta.MetaResponse, error) { return &meta.MetaResponse { AppId: in.AppId, Title: "my title", Name: "My Name", Logo: "https://xxx.com", }, nil} func main() { lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) meta.RegisterAgentServer(s, &server{}) s.Serve(lis)}
agent_client.php源碼:
<?phprequire dirname(__FILE__).'/../vendor/autoload.php';print_r(get_declared_classes());exit;include_once dirname(__FILE__).'/Meta/AgentClient.php';include_once dirname(__FILE__).'/Meta/MetaRequest.php';include_once dirname(__FILE__).'/Meta/MetaResponse.php';include_once dirname(__FILE__).'/GPBMetadata/Meta.php';$appId = "123";try { $client = new Meta\AgentClient('localhost:50051', [ 'credentials' => Grpc\ChannelCredentials::createInsecure(), ]); $request = new Meta\MetaRequest(); $request->setAppId($appId); list($reply, $status) = $client->GetInfo($request)->wait(); echo $reply->serializeToJsonString();} catch (\Throwable | \Error | \Exception $e) { echo "error : " . $e->getMessage();}
運行服務端:
go run main.go
運行用戶端:
php
結果
php調用go的rpc服務
由於php本身的原因(官方是基於php-fpm,非常駐記憶體),所以grpc官方並沒有php的服務端。當然,基於swoole開發的grpc的服務端在github上已經有了。