gRPC 是一個高性能、開源和通用的 RPC 框架,面向移動和 HTTP/2 設計。目前提供 C、Java 和 Go 語言版本,分別是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C#。java
gRPC 基於 HTTP/2 標準設計,帶來諸如雙向流、流控、頭部壓縮、單 TCP 鏈接上的多複用請求等特。這些特性使得其在移動設備上表現更好,更省電和節省空間佔用。ios
環境部署:c++
一、查看centos版本:git
二、安裝grpc的提早準備(g++, autoconf等)github
yum install -y gcc-c++ autoconf libtool yum groupinstall -y "Development Tools"
三、下載grpc源碼和相關子模塊centos
git clone https://github.com/grpc/grpc.git cd grpc git submodule update --init
四、編譯安裝protobuf(grpc須要用到的組件)bash
網上有不少方法是使用curl的方式直接從github上使用腳本下載,可是新版(libprotoc 3.6.1)好像不支持修改文件autogen.sh,固然這一步徹底能夠藉助third_party/protobuf/README.txt來部署protobuf,這裏我採用直接從github上下載的方式部署:服務器
https://github.com/protocolbuffers/protobuf/releases/
直接終端命令:(在目錄third_party下)框架
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-all-3.6.1.tar.gz
解壓後:curl
mv protobuf-all-3.6.1 protobuf
cd protobuf
./autogen.sh
./configure
make
make check
make install
若是make check成功,則顯示:
上述操做若是出現了錯誤,能夠查看同級目錄下的config.log裏面的日誌。好比gcc的版本太低等問題。
以後咱們可使用命令:
protoc --version
來驗證protobuf是否安裝成功,若是出現:
command not found
則須要添加環境變量或者將生成的protoc二進制拷貝到/usr/bin/目錄下。
五、編譯安裝grpc
首先在進到以下的目錄下:
而後分別執行命令:
1 make 2 make install
六、demo測試
官方自帶有個HelloWorld的Demo,能夠編譯這個Demo看是否咱們已經安裝成功了。
執行:
make
若是報錯:
則須要以下兩條語句:
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig pkg-config --libs protobuf grpc++ grpc
此時再次make發現:
而後分別啓動服務器和客戶端
./greeter_server
./greeter_clien
效果:(說明部署成功)
補充:
gcc升級到5.3.1:(centos7.3下)
yum install centos-release-scl yum install devtoolset-4-toolchain scl enable devtoolset-4 bash gcc --version
上述內容參考:
http://blog.dreamlikes.cn/archives/555
https://www.jianshu.com/p/efc9167e7044
【grpc配置問題彙總】
一、grpc默認是使用動態庫,若是使用靜態庫編譯的話,編譯能經過,可是運行時,會報錯:
[admin@iz2zehztwxfrcdbc0z worker]$ ./worker_server 127.0.0.1:21111 127.0.0.1:8001 E0304 13:59:33.725495889 3454 uri_parser.cc:46] bad uri.scheme: '127.0.0.1:21111' E0304 13:59:33.725607759 3454 uri_parser.cc:52] ^ here E0304 13:59:33.725615018 3454 resolver_registry.cc:80] don't know how to resolve '127.0.0.1:21111' or 'dns:///127.0.0.1:21111' E0304 13:59:33.725665096 3454 resolver_registry.cc:80] don't know how to resolve 'dns:///127.0.0.1:21111' or 'dns:///dns:///127.0.0.1:21111' E0304 13:59:33.725687178 3454 channel.cc:99] channel stack builder failed: {"created":"@1551679173.725672811","description":"resolver creation failed","file":"src/core/ext/filters/client_channel/resolving_lb_policy.cc","file_line":160} Register fail, error_code: 2, error_message: lame client channel
參考github上的類似問題:https://github.com/grpc/grpc/issues/11366
即須要本身初始化grpc,直接調用grpc_init()
就咱們的helloworld例子來講,代碼應該變成:
server端:greeter_server.cc
1 #include <iostream> 2 #include <memory> 3 #include <string> 4 #include <grpc/grpc.h> 5 #include <grpc++/server.h> 6 #include <grpc++/server_builder.h> 7 #include <grpc++/server_context.h> 8 #include <grpc++/server_credentials.h> 9 #include <grpc++/status.h> 10 #include "helloworld.pb.h" 11 12 using grpc::Server; 13 using grpc::ServerBuilder; 14 using grpc::ServerContext; 15 using grpc::Status; 16 using helloworld::HelloRequest; 17 using helloworld::HelloReply; 18 using helloworld::Greeter; 19 20 class GreeterServiceImpl final : public Greeter::Service { 21 Status SayHello(ServerContext* context, const HelloRequest* request, HelloReply* reply) override { 22 std::string prefix("Hello "); 23 reply->set_message(prefix + request->name()); 24 return Status::OK; 25 } 26 }; 27 28 void RunServer() { 29 std::string server_address("0.0.0.0:50051"); 30 GreeterServiceImpl service; 31 ServerBuilder builder; 32 builder.AddListeningPort(server_address, 33 grpc::InsecureServerCredentials()); 34 builder.RegisterService(&service); 35 std::unique_ptr<Server> server(builder.BuildAndStart()); 36 std::cout << "Server listening on " << server_address << std::endl; 37 server->Wait(); 38 } 39 40 int main(int argc, char** argv) { 41 grpc_init(); 42 RunServer(); 43 grpc_shutdown(); 44 return 0; 45 }
client端:greeter_client.cc
1 #include <iostream> 2 #include <memory> 3 #include <string> 4 #include <grpc/grpc.h> 5 #include <grpc++/channel_arguments.h> 6 #include <grpc++/channel_interface.h> 7 #include <grpc++/client_context.h> 8 #include <grpc++/create_channel.h> 9 #include <grpc++/credentials.h> 10 #include <grpc++/status.h> 11 #include "helloworld.pb.h" 12 13 using grpc::ChannelArguments; 14 using grpc::ChannelInterface; 15 using grpc::ClientContext; 16 using grpc::Status; 17 using helloworld::HelloRequest; 18 using helloworld::HelloReply; 19 using helloworld::Greeter; 20 21 class GreeterClient { 22 public: 23 GreeterClient(std::shared_ptr<ChannelInterface> channel) : stub_(Greeter::NewStub(channel)) {} 24 25 std::string SayHello(const std::string& user) { 26 HelloRequest request; 27 request.set_name(user); 28 HelloReply reply; 29 ClientContext context; 30 Status status = stub_->SayHello(&context, request, &reply); 31 if (status.IsOk()) { 32 return reply.message(); 33 } else { 34 return "Rpc failed"; 35 } 36 } 37 void Shutdown() { stub_.reset(); } 38 private: 39 std::unique_ptr<Greeter::Stub> stub_; 40 }; 41 42 int main(int argc, char** argv) { 43 grpc_init(); 44 GreeterClient greeter( 45 grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials(), 46 ChannelArguments())); 47 std::string user("world"); 48 std::string reply = greeter.SayHello(user); 49 std::cout << "Greeter received: " << reply << std::endl; 50 greeter.Shutdown(); 51 grpc_shutdown(); 52 }