Grpc介紹 — Go-Service To PHP-Client

筆者現在公司項目大部分是PHP進行開發,要完成整體微服務化必須要考慮PHP使用上的可行性,Grpc也是支持PHP作爲client端發起Grpc請求,但是依賴的擴展等都相對複雜(畢竟不是親兒子),那麼本文就接受怎麼使用PHP調用Grpc服務。

附上:

喵了個咪的博客:w-blog.cn

博文實例demo:GitHub - sunmi-OS/grpc-php-to-golang-demo

grpc官網:grpc / grpc.io

protobuf代碼倉庫:Releases · protocolbuffers/protobuf · GitHub

一,初始化PHP環境

PHP在使用過程中依賴一下幾項內容

1、先編譯grpc_php_plugin

> git clone https://github.com/grpc/grpc.git
> cd grpc
> git pull --recurse-submodules && git submodule update --init --recursive
> make
> sudo make install
# make install 會在 /usr/local/bin 目錄下生成以下文件
#grpc_cpp_plugin  
#grpc_csharp_plugin  
#grpc_node_plugin  
#grpc_objective_c_plugin  
#grpc_php_plugin  
#grpc_python_plugin  
#grpc_ruby_plugin

# 或者只變編譯grpc_php_plugin
> make grpc_php_plugin
Package libcares was not found in the pkg-config search path.
Perhaps you should add the directory containing `libcares.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libcares' found
[C]       Compiling third_party/address_sorting/address_sorting.c
[C]       Compiling third_party/address_sorting/address_sorting_posix.c
[C]       Compiling third_party/address_sorting/address_sorting_windows.c
[AR]      Creating /Users/wenzhenxi/Downloads/grpc/libs/opt/libaddress_sorting.a
[HOSTCXX] Compiling src/compiler/cpp_generator.cc
[HOSTCXX] Compiling src/compiler/csharp_generator.cc
[HOSTCXX] Compiling src/compiler/node_generator.cc
[HOSTCXX] Compiling src/compiler/objective_c_generator.cc
[HOSTCXX] Compiling src/compiler/php_generator.cc
[HOSTCXX] Compiling src/compiler/python_generator.cc
[HOSTCXX] Compiling src/compiler/ruby_generator.cc
[AR]      Creating /Users/wenzhenxi/Downloads/grpc/libs/opt/libgrpc_plugin_support.a
[HOSTCXX] Compiling src/compiler/php_plugin.cc
Package libcares was not found in the pkg-config search path.
Perhaps you should add the directory containing `libcares.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libcares' found
Package libcares was not found in the pkg-config search path.
Perhaps you should add the directory containing `libcares.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libcares' found
[HOSTLD]  Linking /Users/wenzhenxi/Downloads/grpc/bins/opt/grpc_php_plugin

最終得到了grpc_php_plugin

2、安裝PHP運行依賴

最簡單的方式就是直接通過pecl進行安裝:

pecl install grpc
pecl install protobuf

如果無法使用pecl可以使用編譯的方式進行安裝,PHP依賴的源文件已經存放在grpc中:

> cd grpc/src/php/ext/grpc
> phpize
> ./configure
> make
> sudo make install

> git clone https://github.com/allegro/php-protobuf
> phpize
> ./configure
> make
> sudo make install

最後需要在php.ini裏面增加如下內容:

extension=grpc.so
extension=protobuf.so

通過phpinfo(); 可以正常看到這兩個模塊正常即可

PS:protobuf可以不通過擴展的方式通過composer引入也可,對效率來說更加推薦通過SO擴展,demo中已經準備了7.1和7.2版本的so文件

二,生成 PHP protobuf 文件

> cd $GOPATH/src/grpc-php-to-golang-demo/protobuf
> mkdir -p php-client/helloworld
> protoc --proto_path=./ --php_out=php-client/helloworld --grpc_out=php-client/helloworld --plugin=protoc-gen-grpc=../grpc_php_plugin-all/osx-64/grpc_php_plugin  helloworld.proto
> cd php-client/helloworld/
> ll
total 0
drwxr-xr-x  4 wenzhenxi  staff  128  2 15 15:09 ./
drwxr-xr-x  3 wenzhenxi  staff   96  2 15 15:09 ../
drwxr-xr-x  3 wenzhenxi  staff   96  2 15 15:09 GPBMetadata/
drwxr-xr-x  5 wenzhenxi  staff  160  2 15 15:09 Helloworld/

三,使用PHP調用go服務

拷貝依賴文件:

cd $GOPATH/src/grpc-php-to-golang-demo
mkdir -p php
cd php
mv $GOPATH/src/grpc-php-to-golang-demo/protobuf/php-client/helloworld helloworld

使用composer獲取依賴文件:

> vim composer.json

{
  "name": "grpc/grpc-demo",
  "description": "gRPC example for PHP",
  "require": {
    "grpc/grpc": "^v1.3.0"
  },
  "autoload": {
    "psr-4": {
      "": "route_guide/"
    }
  }
}

>  composer install 

編寫測試文件:

> vim client.php

require 'vendor/autoload.php';

include_once 'helloworld/Helloworld/GreeterClient.php';
include_once 'helloworld/Helloworld/HelloReply.php';
include_once 'helloworld/Helloworld/HelloRequest.php';
include_once 'helloworld/GPBMetadata/Helloworld.php';

function greet($name)
{
    $client = new Helloworld\GreeterClient('localhost:50051', [
        'credentials' => Grpc\ChannelCredentials::createInsecure(),
    ]);
    $request = new Helloworld\HelloRequest();
    $request->setName($name);
    list($reply, $status) = $client->SayHello($request)->wait();
    $message = $reply->getMessage();

    return $message;
}

$name = !empty($argv[1]) ? $argv[1] : 'world';
echo greet($name)."\n";

結果:

> php client.php 
holle world
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章