gRPC - Go语言中文社区

gRPC


什么是gRPC

PRC(Remote Procedure Call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信。

google开发,一款语言中立、平台中立、开源的远程过程调用(RPC)系统.
gRPC里客户端应用可以像本地对象一样直接调用另一台不同机器上服务端应用的方法,使得能够更容易创建分布式应用和服务。
基于Http2.0且依赖protobuf

定义一个服务,指定其能够被远程调用的方法(参数和返回类型),在服务端实现这个接口,并允许一个gRPC服务器来处理客户端调用,
在客户端拥有一个存根能够像服务端一样的方法。

在这里插入图片描述

特性

基于Http/2:
    HTTP/2提供了连接多路复用、双向流、服务器推送、请求优先级、首部压缩等机制。
    可节省带宽、降低TCP链接次数、节省CPU,帮助移动设备延长电池寿命等。
    
IDL使用ProtoBuf:
    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,可以传入多个对象,返回多个响应对象

Examples

  1. cd examples/node-test

  2. 安装

	cnpm i grpc --save
	cnpm i grpc-tools --save-dev
	cnpm i grpc_tools_node_protoc_ts --save-dev
	cnpm i google-protobuf --save 
  1. 定义服务:
    使用protocol buffers去定义gRPC service和方法request及response类型;

  2. .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;
    }
    
  1. 编译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

  1. 创建服务器:
    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();
    
  1. 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();
    
  1. 启动
  	cd ../node-test

    node ./static-codegen/test_server.js

    node ./static-codegen/test_client.js
    

在这里插入图片描述

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/mo_247/article/details/102910987
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢