1.  gRPC简述

RPC,远程方法调用,就是像调用本地方法一样调用远程方法。

gRPC是Google实现的一种RPC框架,基于HTTP/2标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持。

基本原理:在服务端提供方法,并运行服务器监听客户端请求;客户端调用RPC方法,gRPC客户端向服务端发送请求,并将结果返回给客户端调用函数。

gRPC 默认使用 protocol buffers,这是 Google 开源的一套成熟的结构数据序列化机制(当然也可以使用其他数据格式如 JSON)。推荐使用protobuf v3。

github:https://github.com/grpc/grpc

RPC框架要做到的最基本的三件事:

1)服务端如何确定客户端要调用的函数;

在远程调用中,客户端和服务端分别维护一个【ID->函数】的对应表, ID在所有进程中都是唯一确定的。客户端在做远程过程调用时,附上这个ID,服务端通过查表,来确定客户端需要调用的函数,然后执行相应函数的代码。

2)如何进行序列化和反序列化;

客户端和服务端交互时将参数或结果转化为字节流在网络中传输,那么数据转化为字节流的或者将字节流转换成能读取的固定格式时就需要进行序列化和反序列化,序列化和反序列化的速度也会影响远程调用的效率。

3)如何进行网络传输(选择何种网络协议);

多数RPC框架选择TCP作为传输协议,也有部分选择HTTP。如gRPC使用HTTP2。不同的协议各有利弊。TCP更加高效,而HTTP在实际应用中更加的灵活。

REST与RPC应用场景

REST和RPC都常用于微服务架构中。

1)HTTP相对更规范,更标准,更通用,无论哪种语言都支持http协议。如果你是对外开放API,例如开放平台,外部的编程语言多种多样,你无法拒绝对每种语言的支持,现在开源中间件,基本最先支持的几个协议都包含RESTful。

2)RPC 框架作为架构微服务化的基础组件,它能大大降低架构微服务化的成本,提高调用方与服务提供方的研发效率,屏蔽跨进程调用函数(服务)的各类复杂细节。让调用方感觉就像调用本地函数一样调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务。

REST调用及测试都很方便,RPC就显得有点繁琐,但是RPC的效率是毋庸置疑的,所以建议在多系统之间的内部调用采用RPC。对外提供的服务,Rest更加合适。

2.  安装

$ git clone https://github.com/grpc/grpc.git
$ cd grpc
$ git submodule update --init
$make
$sudo make install

注:执行submodule时时间较长

[INSTALL] Installing public C headers
[MAKE] Generating cache.mk
[STRIP] Stripping libaddress_sorting.a
[STRIP] Stripping libgpr.a
[STRIP] Stripping libgrpc.a
[STRIP] Stripping libgrpc_cronet.a
[STRIP] Stripping libgrpc_unsecure.a
[INSTALL] Installing C pkg-config files
[INSTALL] Installing libaddress_sorting.a
[INSTALL] Installing libgpr.a
[INSTALL] Installing libgrpc.a
[INSTALL] Installing libgrpc_cronet.a
[INSTALL] Installing libgrpc_unsecure.a
[STRIP] Stripping libaddress_sorting.so.7.0.
[STRIP] Stripping libgpr.so.7.0.
[STRIP] Stripping libgrpc.so.7.0.
[STRIP] Stripping libgrpc_cronet.so.7.0.
[STRIP] Stripping libgrpc_unsecure.so.7.0.
[INSTALL] Installing libaddress_sorting.so.7.0.
[INSTALL] Installing libgpr.so.7.0.
[INSTALL] Installing libgrpc.so.7.0.
[INSTALL] Installing libgrpc_cronet.so.7.0.
[INSTALL] Installing libgrpc_unsecure.so.7.0.
[INSTALL] Installing public C++ headers
[AR] Creating /home/wang/repo/grpc/libs/opt/libgrpc_plugin_support.a
[HOSTCXX] Compiling src/compiler/cpp_plugin.cc
[HOSTLD] Linking /home/wang/repo/grpc/bins/opt/grpc_cpp_plugin
[HOSTCXX] Compiling src/compiler/csharp_plugin.cc
[HOSTLD] Linking /home/wang/repo/grpc/bins/opt/grpc_csharp_plugin
[HOSTCXX] Compiling src/compiler/node_plugin.cc
[HOSTLD] Linking /home/wang/repo/grpc/bins/opt/grpc_node_plugin
[HOSTCXX] Compiling src/compiler/objective_c_plugin.cc
[HOSTLD] Linking /home/wang/repo/grpc/bins/opt/grpc_objective_c_plugin
[HOSTCXX] Compiling src/compiler/php_plugin.cc
[HOSTLD] Linking /home/wang/repo/grpc/bins/opt/grpc_php_plugin
[HOSTCXX] Compiling src/compiler/python_plugin.cc
[HOSTLD] Linking /home/wang/repo/grpc/bins/opt/grpc_python_plugin
[HOSTCXX] Compiling src/compiler/ruby_plugin.cc
[HOSTLD] Linking /home/wang/repo/grpc/bins/opt/grpc_ruby_plugin
[PROTOC] Generating protobuf CC file from src/proto/grpc/channelz/channelz.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/channelz/channelz.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/health/v1/health.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/health/v1/health.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/echo_messages.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/echo_messages.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/simple_messages.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/echo.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/simple_messages.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/echo.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/duplicate/echo_duplicate.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/duplicate/echo_duplicate.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/core/stats.proto
[CXX] Compiling /home/wang/repo/grpc/gens/src/proto/grpc/core/stats.pb.cc
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/core/stats.proto
[CXX] Compiling /home/wang/repo/grpc/gens/src/proto/grpc/core/stats.grpc.pb.cc
[CXX] Compiling src/cpp/util/core_stats.cc
[AR] Creating /home/wang/repo/grpc/libs/opt/libgrpc++_core_stats.a
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/payloads.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/stats.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/control.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/payloads.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/stats.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/control.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/messages.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/messages.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/benchmark_service.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/benchmark_service.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/report_qps_scenario_service.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/report_qps_scenario_service.proto
[PROTOC] Generating protobuf CC file from src/proto/grpc/testing/worker_service.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/testing/worker_service.proto
[CXX] Compiling src/cpp/codegen/codegen_init.cc
[AR] Creating /home/wang/repo/grpc/libs/opt/libgrpc++.a
[AR] Creating /home/wang/repo/grpc/libs/opt/libgrpc++_cronet.a
[PROTOC] Generating protobuf CC file from src/proto/grpc/status/status.proto
[CXX] Compiling /home/wang/repo/grpc/gens/src/proto/grpc/status/status.pb.cc
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/status/status.proto
[CXX] Compiling /home/wang/repo/grpc/gens/src/proto/grpc/status/status.grpc.pb.cc
[CXX] Compiling src/cpp/util/error_details.cc
[AR] Creating /home/wang/repo/grpc/libs/opt/libgrpc++_error_details.a
[PROTOC] Generating protobuf CC file from src/proto/grpc/reflection/v1alpha/reflection.proto
[GRPC] Generating gRPC's protobuf service CC file from src/proto/grpc/reflection/v1alpha/reflection.proto
[CXX] Compiling src/cpp/ext/proto_server_reflection.cc
[CXX] Compiling src/cpp/ext/proto_server_reflection_plugin.cc
[CXX] Compiling /home/wang/repo/grpc/gens/src/proto/grpc/reflection/v1alpha/reflection.pb.cc
[CXX] Compiling /home/wang/repo/grpc/gens/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
[AR] Creating /home/wang/repo/grpc/libs/opt/libgrpc++_reflection.a
[AR] Creating /home/wang/repo/grpc/libs/opt/libgrpc++_unsecure.a
[CXX] Compiling src/cpp/server/channelz/channelz_service.cc
[CXX] Compiling src/cpp/server/channelz/channelz_service_plugin.cc
[CXX] Compiling /home/wang/repo/grpc/gens/src/proto/grpc/channelz/channelz.pb.cc
[CXX] Compiling /home/wang/repo/grpc/gens/src/proto/grpc/channelz/channelz.grpc.pb.cc
[AR] Creating /home/wang/repo/grpc/libs/opt/libgrpcpp_channelz.a
[STRIP] Stripping libgrpc++.a
[STRIP] Stripping libgrpc++_cronet.a
[STRIP] Stripping libgrpc++_error_details.a
[STRIP] Stripping libgrpc++_reflection.a
[STRIP] Stripping libgrpc++_unsecure.a
[STRIP] Stripping libgrpcpp_channelz.a
[INSTALL] Installing C++ pkg-config files
[INSTALL] Installing libgrpc++.a
[INSTALL] Installing libgrpc++_cronet.a
[INSTALL] Installing libgrpc++_error_details.a
[INSTALL] Installing libgrpc++_reflection.a
[INSTALL] Installing libgrpc++_unsecure.a
[INSTALL] Installing libgrpcpp_channelz.a
[LD] Linking /home/wang/repo/grpc/libs/opt/libgrpc++.so.1.20.
[LD] Linking /home/wang/repo/grpc/libs/opt/libgrpc++_cronet.so.1.20.
[LD] Linking /home/wang/repo/grpc/libs/opt/libgrpc++_error_details.so.1.20.
[LD] Linking /home/wang/repo/grpc/libs/opt/libgrpc++_reflection.so.1.20.
[LD] Linking /home/wang/repo/grpc/libs/opt/libgrpc++_unsecure.so.1.20.
[LD] Linking /home/wang/repo/grpc/libs/opt/libgrpcpp_channelz.so.1.20.
[STRIP] Stripping libgrpc++.so.1.20.
[STRIP] Stripping libgrpc++_cronet.so.1.20.
[STRIP] Stripping libgrpc++_error_details.so.1.20.
[STRIP] Stripping libgrpc++_reflection.so.1.20.
[STRIP] Stripping libgrpc++_unsecure.so.1.20.
[STRIP] Stripping libgrpcpp_channelz.so.1.20.
[INSTALL] Installing libgrpc++.so.1.20.
[INSTALL] Installing libgrpc++_cronet.so.1.20.
[INSTALL] Installing libgrpc++_error_details.so.1.20.
[INSTALL] Installing libgrpc++_reflection.so.1.20.
[INSTALL] Installing libgrpc++_unsecure.so.1.20.
[INSTALL] Installing libgrpcpp_channelz.so.1.20.
[INSTALL] Installing grpc protoc plugins
[INSTALL] Installing root certificates

install log

安装的文件包含:bin,include,lib,share(根证书)。

3.  应用

examples下有各语言版本的示例,examples/protoc是protoc示例文件。

如下演示的是helloworld示例,examples中不仅支持同步调用,还支持异步调用。

1. proto文件定义RPC方法及参数

helloworld.proto

syntax = "proto3";

option java_package = "io.grpc.examples";

package helloworld;

// The greeter service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
} // The request message containing the user's name.
message HelloRequest {
string name = ;
} // The response message containing the greetings
message HelloReply {
string message = ;
}

编译生成c++源文件(grpc和应用)

protoc --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` helloworld.proto
protoc --cpp_out=. helloworld.proto

2. server端代码

#include <iostream>
#include <memory>
#include <string> #include <grpcpp/grpcpp.h> #ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using helloworld::HelloRequest;
using helloworld::HelloReply;
using helloworld::Greeter; // Logic and data behind the server's behavior.
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
return Status::OK;
}
}; void RunServer() {
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service; ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl; // Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
} int main(int argc, char** argv) {
RunServer(); return ;
}

编译执行:

g++ -o server helloworld.pb.cc helloworld.grpc.pb.cc server.cc -L/usr/local/lib `pkg-config --cflags protobuf grpc` -std=c++ `pkg-config --libs protobuf grpc++ grpc` -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed -ldl
$ ./server
Server listening on 0.0.0.0:

3 client端代码

#include <iostream>
#include <memory>
#include <string> #include <grpcpp/grpcpp.h> #ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using helloworld::HelloRequest;
using helloworld::HelloReply;
using helloworld::Greeter; class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {} // Assembles the client's payload, sends it and presents the response back
// from the server.
std::string SayHello(const std::string& user) {
// Data we are sending to the server.
HelloRequest request;
request.set_name(user); // Container for the data we expect from the server.
HelloReply reply; // Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context; // The actual RPC.
Status status = stub_->SayHello(&context, request, &reply); // Act upon its status.
if (status.ok()) {
return reply.message();
} else {
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
} private:
std::unique_ptr<Greeter::Stub> stub_;
}; int main(int argc, char** argv) {
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint (in this case,
// localhost at port 50051). We indicate that the channel isn't authenticated
// (use of InsecureChannelCredentials()).
GreeterClient greeter(grpc::CreateChannel(
"127.0.0.1:50051", grpc::InsecureChannelCredentials()));
std::string user("world");
std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl; return ;
}

编译执行:

g++ -o client helloworld.pb.cc helloworld.grpc.pb.cc client.cc -L/usr/local/lib `pkg-config --cflags protobuf grpc` -std=c++ `pkg-config --libs protobuf grpc++ grpc` -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed -ldl
$ ./client
Greeter received: Hello world

参考:

1. https://www.grpc.io/docs/ 官网

2. http://doc.oschina.net/grpc 中文官网

3. 花了一个星期,我终于把RPC框架整明白了!

4. Grpc+Grpc Gateway实践一 介绍与环境安装

5. grpc 的安装和使用

6. 面试问题:REST与RPC区别?

7.  实现一个 RESTful API 服务器 RSET和RPC比较

8. gRPC(HTTP / 2)比使用HTTP / 2的REST更快吗?  默认情况下,gRPC不比HTTP / REST更快,但它为您提供了更快的工具。有些事情对于REST来说很难或不可能做到。

gRPC应用C++的更多相关文章

  1. gRPC源码分析1-SSL/TLS

    引子 前几天看到微信后台团队分享了TLS相关文章,正好gRPC里TLS数据加密是很重要的一块,于是整理出了这篇文章. 在gRPC里,如果仅仅是用来做后端微服务,可以考虑不加密.本文太长,先给个大纲. ...

  2. gRPC源码分析2-Server的建立

    gRPC中,Server.Client共享的Class不是很多,所以我们可以单独的分别讲解Server和Client的源码. 通过第一篇,我们知道对于gRPC来说,建立Server是非常简单的,还记得 ...

  3. gRPC源码分析0-导读

    gRPC是Google开源的新一代RPC框架,官网是http://www.grpc.io.正式发布于2016年8月,技术栈非常的新,基于HTTP/2,netty4.1,proto3.虽然目前在工程化方 ...

  4. 谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC

    Google 刚刚开源了grpc,  一个基于HTTP2 和 Protobuf 的高性能.开源.通用的RPC框架.Protobuf 本身虽然提供了RPC  的定义语法,但是一直以来,Google 只开 ...

  5. gRPC .NET Core跨平台学习

    前些天发布gRPC C# 学习,在.NET Framework 中使用gRPC ,今天来学习 .NET Core gRPC. gRPC 的.NET Core 包在NuGet 上发布了,结合.NET C ...

  6. gRPC C#学习

    前些天gRPC 发布1.0 版本,代表着gRPC 已经正式进入稳定阶段. 今天我们就来学习gRPC C# .而且目前也已经支持.NET Core 可以实现完美跨平台. 传统的.NET 可以通过Mono ...

  7. .net core 用grpc实现微服务

    GRPC 是Google发布的一个开源.高性能.通用RPC(Remote Procedure Call)框架.提供跨语言.跨平台支持.以下以.NET Core 使用控制台.docker中演示如何使用G ...

  8. rpc框架之gRPC 学习 - hello world

    grpc是google在github于2015年开源的一款RPC框架,虽然protobuf很早google就开源了,但是google一直没推出正式的开源框架,导致github上基于protobuf的r ...

  9. Android开发笔记之《远程控制(MQTT|mosquitto) && (ProtocalBuffer | GRPC)》

    Android推送方案分析(MQTT/XMPP/GCM): http://www.open-open.com/lib/view/open1410848945601.htmlMQTT官网: http:/ ...

  10. gRPC+etcd的优势分析

    相比webService等可跨平台,跨语言的服务相比,gRPC更增加了以下优势 1.可以采用二进制传输,速度更快 (使用TCP传输层,而不是Http2应用层) 2.集群服务,统一注册,可靠性高( 好的 ...

随机推荐

  1. angular4.x实现一个全选,反选,外加从下一页返回上一页,选中上一次的操作记录

    productMap:any = new Map<string, string>(); //定义一个map的数据模型 //只要操作这个checkbox 那么只管把数据全部勾起了就行了 刷新 ...

  2. spring较为常用注解

    @Configuration 从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被Annotat ...

  3. Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activate 'xxxxx.Controllers.xxxxController'.

    Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' while attempting to activa ...

  4. Java学习笔记二——正则表达式

    Java正则表达式 正则表达式的规则 “abc” 匹配字符串abc [abc] 匹配[]里任意一个字符 [a-z]: 匹配所有小写字母中的任意一个字符 [A-Z]: 匹配所有大写字母中的任意一个字符 ...

  5. 测试类——python编程从入门到实践

    1.各种断言方法 常用断言方法: 方法 用途 assertEqual(a, b) 核实a == b assertNotEqual(a, b) 核实a != b assertTrue(x) 核实x为Tr ...

  6. 进程池和线程池、协程、TCP单线程实现并发

    一.进程池和线程池 当被操作对象数目不大时,我们可以手动创建几个进程和线程,十几个几十个还好,但是如果有上百个上千个.手动操作麻烦而且电脑硬件跟不上,可以会崩溃,此时进程池.线程池的功效就能发挥了.我 ...

  7. 不会前后端,用vps搭建个人博客(二)

    <接上一篇>   四.添加网页内容 1.下载安装WordPress 输入以下命令: wget https://wordpress.org/latest.tar.gz 当然你也可以用浏览器进 ...

  8. es常用操作

    1.查看所有索引 _cat/indices?v 2.删除索引 DELETE my_index 3.查询缓存 curl /my_index/_search?request_cache=true' -d' ...

  9. 【题解】Luogu P5300 [GXOI/GZOI2019]与或和

    原题传送门 我们珂以拆位,拆成一个个0/1矩阵 贡献珂以用全0,全1的子矩阵的个数来计算 全0,全1的子矩阵的个数珂以用悬线法/单调栈解决 #include <bits/stdc++.h> ...

  10. ArcGIS Engine中C#开发不能引用ESRI.ArcGIS.AxControls问题

    问题:ArcGIS Engine中C#开发不能引用ESRI.ArcGIS.AxControls问题 解决方法:将这里的特定版本改成“False”即可.