gRPC项目搭建
Posted 程序媛小小平
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gRPC项目搭建相关的知识,希望对你有一定的参考价值。
什么是gRPC
PRC(Remote Procedure Call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信。
google开发,一款语言中立、平台中立、开源的远程过程调用(RPC)系统.
gRPC中客户端应用可以像本地对象一样直接调用另一台不同机器上服务端应用的方法,使得能够更容易创建分布式应用和服务。
基于Http2.0且依赖protobuf。
定义一个服务,指定其能够被远程调用的方法(参数和返回类型),在服务端实现这个接口,并允许一个gRPC服务器来处理客户端调用,
在客户端拥有一个存根能够像服务端一样的方法。
特性
基于Http/2:
HTTP/2提供了连接多路复用、双向流、服务器推送、请求优先级、首部压缩等机制。
可节省带宽、降低TCP链接次数、节省CPU,帮助移动设备延长电池寿命等。
IDL使用ProtoBuf(proto3):
gRPC使用ProtoBuf定义服务,ProtoBuf由Google开发的一种数据序列化协议,能够将数据进行序列化。
应用在数据存储、通信协议等方面。
压缩和传输效率高,语法简单,表达力强。
多语言支持:
C、C++、Node、Python、Rubuy、Objective-C、php和C#。
应用场景
低延迟、高扩展性、分布式的系统;
同云服务器进行通信的引动应用客户端;
涉及语言独立、高效、精确的新协议;
便于各方面扩展的分层,如认证、负载均衡、日志记录、监控等;
优点
protobuf二进制编码,大幅减少需要传输的数据量,性能好、效率高;
proto文件生成目标代码,简单易用;
protobuf定义接口,更加严格的接口约束条件;
grpc可以方便的支持流式通信;
序列化反序列化直接对应程序中的数据类,不需要解析后再进行映射;
支持向前兼容(新加字段采用默认值)和向后兼容(忽略新加字段),简化升级;
支持多种语言;
Netty等一些框架集成;
缺点
grpc尚未实现连接池,需要自行实现;
尚未提供“服务发现”、“负载均衡”机制;
nginx不能讲Grpc请求作为http请求来负载均衡,而是作为普通的TCP请求;
protobuf二进制可读写差;
基础
.proto文件定义服务;
protocol buffer编译器生成服务器和客户端代码;
使用grpc的NodeJS API为服务实现一个简单的客户端和服务器;
为什么使用gRPC?
允许客户端获取路由特性的信息,生成路由的总结,及交互路由信息。
四种通信方式
Simple RPC
一个请求对象对应一个返回对象
Server-side streaming RPC
服务端流式rpc,一个请求对象,服务端返回多个结果对象
Client-side streaming RPC
客户端流式rpc,客户端传入多个请求对象,服务端返回一个相应结果
Bidirectional streaming RPC
双向流式rpc,结合客户端流式rpc和服务端流式rpc,可以传入多个对象,返回多个响应对象
Project Examples
cd examples/node-test
安装
cnpm i grpc --save
cnpm i grpc-tools --save-dev
cnpm i grpc_tools_node_protoc_ts --save-dev
cnpm i google-protobuf --save
3. 定义服务
使用protocol buffers去定义gRPC service和方法request及response类型;
4. .proto文件
.proto文件也包含了所有请求的protocol buffer消息类型定义及在服务方法中使用的响应类型。
syntax = "proto3"; // 指定使用proto3语法,默认是proto2,且放在proto文件的非空非注释的第一行。
package helloworld;
// 指定service
service Greeter {
// 一个简单的rpc, 客户端使用存根发送请求到服务器并等待响应返回;
rpc SayHello (HelloRequest) returns (HelloReply) {}
// 一个服务端流式rpc 客户端发送请求到服务器,拿到一个流去读取返回的消息序列。
// 客户端读取返回的流,直到里面没有任何消息。
rpc ListFeatures(Rectangle) returns (stream Feature) {}
// 一个客户端流式rpc 客户端写入一个消息序列并将其发送到服务器,同样适用流
// 一旦客户端完成写入信息,它等待服务器完成读取返回它的响应
rpc RecordRoute(stream Point) returns (RouteSummary) {}
// 一个双向流式rpc 双方适用读写流去发送一个消息序列。两个流独立操作,因此客户端和服务端可以任曦喜欢的顺序读写
rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
5. 编译proto文件
cd protos
grpc_tools_node_protoc --js_out=import_style=commonjs,binary:../protos --grpc_out=../protos --plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin` helloword.proto
生成两个文件:
helloword_pb.js
helloword_grpc_pb.js
6. 创建服务器
const grpc = require('grpc');
const messages = require('./helloworld_pb');
const services = require('./helloworld_grpc_pb');
/**
* Implements the SayHello RPC method.
*/
function sayHello(call, callback) {
const reply = new messages.HelloReply();
reply.setMessage('Hello ' + call.request.getName());
// 第一个参数为null,表示没有错误
callback(null, reply);
}
// 启动服务器
function main() {
const server = new grpc.Server();
server.addService(services.GreeterService, {sayHello: sayHello});
server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
server.start();
}
main();
7. client
const grpc = require('grpc');
const messages = require('./helloworld_pb');
const services = require('./helloworld_grpc_pb');
function main() {
const client = new services.GreeterClient('localhost:50051', grpc.credentials.createInsecure());
const request = new messages.HelloRequest();
const user;
if (process.argv.length >= 3) {
user = process.argv[2];
} else {
user = 'world';
}
request.setName(user);
client.sayHello(request, function (err, response) {
console.log('Greeting:', response.getMessage());
});
}
main();
8. 启动
cd ../node-test
node ./static-codegen/test_server.js
node ./static-codegen/test_client.js
9. 项目目录
以上是关于gRPC项目搭建的主要内容,如果未能解决你的问题,请参考以下文章