一、核心概念、架构及生命周期

1、服务定义

gRPC 默认使用 protocol buffers

service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
} message HelloRequest {
string greeting = 1;
} message HelloResponse {
string reply = 1;
}

gRPC 可以定义四种类型服务:

  • Unary RPCs:一次请求,一次回复。

    rpc SayHello(HelloRequest) returns (HelloResponse);
  • 服务端流式请求:客户端发送一次请求,服务端流式返回一系列数据。

    rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
  • 客户端流式请求:客户端流式写入一系列请求,然后发送到服务端。客户端写完请求后,等待服务端接受并返回结果。

    rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
  • 双向流式请求:客户端和服务端双向发送数据流,各自独立。可以随读随写,或者一次性读完再写。

    rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);

2、API 使用

首先在 .proto 文件中定义一个服务,然后使用 gRPC 提供的 pb 编译插件来生成客户端和服务端代码。

  • 服务端:实现定义的服务,响应客户端请求。gRPC 框架解码请求,执行服务方法,编码返回结果。
  • 客户端:本地 stub 包含实现的服务方法,客户端可以直接调用 stub 的相应方法,以 pb 消息类型包装请求参数发送到服务器,同时返回服务器返回的结果。

3、同步和异步

同步 RPC 请求(发送请求,阻塞直到服务端返回结果)和我们通常所说的 RPC 定义最为接近。但是,在实际应用中,非阻塞异步请求更适合。

4、RPC 生命周期

a)Unary RPC

客户端发送一次请求,获取一次返回。

  • 客户端请求本地 stub 方法,服务端获取到通知,并伴随着客户端的请求数据,包括客户端 metadata、方法名及 deadline。服务端可以直接返回自身的 metadata(必须在业务结果返回前返回)或者等待客户端的请求消息(自定义)。
  • 服务端收到客户端请求消息,然后执行相应的方法,组装相应的数据结果,伴随着请求状态信息(状态码及可能状态消息)返回给客户端。
  • 如果状态为 OK,则客户端可以获取到结果进行处理,完成整个调用过程。

b)服务端流式 RPC

服务端返回的是一个数据流。在服务端发送完业务数据后,会继续返回状态信息。

c)客户端流式 RPC

客户端发送的是一个请求数据流。

d)双向流式 RPC

客户端和服务端双向发送数据流,各自独立。可以随读随写,或者一次性读完再写。

5、Deadlines/Timeouts

gRPC 允许客户端声明超时(请求 DEADLINE_EXCEEDED 异常之前等待的时间)。服务端可以通过此来判定请求是否超时及剩余处理时间。

6、RPC 终止

gRPC 中客户端和服务端都可以独立终止请求。比如服务端已经成功响应请求,但是客户端超时终止;服务端在接收完客户端请求数据前限频校验终止请求流程。

7、RPC 请求取消

客户端和服务端都可以在任何时候取消 RPC 流程。

8、Metadata

RPC 请求元数据,kv 列表形式,key 为 string 类型,value 通常为string,也可以为二进制。

key 大小写敏感,不能以 grpc- 做前缀(保留),二进制 value 的 key 以 -bin 结尾。

gRPC 不会使用用户自定义的元数据。

元数据使用,不同开发语言可能不同。

9、Channels

gRPC channel 是客户端到服务端的链接。用以创建客户端 stub。

channel 提供相应的参数配置控制 gRPC 请求行为,例如交互数据压缩等。

channel 的状态包括已建立链接及空闲。

二、最佳实践

rpc 请求初始化包括:客户端负载均衡,传输层 HTTP/2 请求创建及请求服务端相应的业务接口。

尽量重用 stubs 和 channels。

2、提供心跳机制以确保 HTTP/2 连接即使在系统业务不活跃时段仍能保持活跃,避免因 RPC 请求初始化导致的响应延迟。

3、对于可能存续长时间的数据流请求交互,适宜使用流式处理,避免频繁的 RPC 初始化。但是流式处理也存在无法动态均衡负载的及debug 困难的问题。虽然可以在小规模请求上提升性能,但是会因为负载均衡因素及复杂性降低整体扩展性。(python 除外)

4、每一个 gRPC channel 可以使用 0 个或多个 HTTP/2 链接,每个链接可以承载一定数量的的并发数据流。当链接上活跃的 RPC 请求达到上限,新进的请求会进入调用端等待队列。因此,对于高负载或持久的流式请求会因此产生性能问题。对于此,可以使用如下两种方式处理:

  • 对于此类业务请求使用额外的 chennel。
  • 使用 gRPC 连接池来均衡处理请求(需要特定的处理来避免重复使用同一个 channel)

5、对于 Java 语言

  • 使用非阻塞 stubs 来并行处理 RPC 请求。

  • 提供自定义连接池,根据实际的业务负载来配置相关参数。

gRPC 应用指引的更多相关文章

  1. 浅议Grpc传输机制和WCF中的回调机制的代码迁移

    浅议Grpc传输机制和WCF中的回调机制的代码迁移 一.引子 如您所知,gRPC是目前比较常见的rpc框架,可以方便的作为服务与服务之间的通信基础设施,为构建微服务体系提供非常强有力的支持. 而基于. ...

  2. Akka-CQRS(10)- gRPC on SSL/TLS 安全连接

    使用gRPC作为云平台和移动前端的连接方式,网络安全应该是必须考虑的一个重点.gRPC是支持ssl/tls安全通讯机制的.用了一个周末来研究具体使用方法,实际上是一个周末的挖坑填坑过程.把这次经历记录 ...

  3. 旧 WCF 项目迁移到 asp.net core + gRPC 的尝试

    一个月前,公司的运行WCF的windows服务器down掉了,由于 AWS 没有通知,没有能第一时间发现问题. 所以,客户提出将WCF服务由C#改为JAVA,在Linux上面运行:一方面,AWS对Li ...

  4. 流量染色与gRPC服务托管 微服务协作开发、灰度发布之流量染色 灰度发布与流量染色

    大规模微服务场景下灰度发布与流量染色实践 https://mp.weixin.qq.com/s/UBoRKt3l91ffPagtjExmYw [go-micro]微服务协作开发.灰度发布之流量染色 - ...

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

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

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

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

  7. gRPC源码分析0-导读

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

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

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

  9. gRPC .NET Core跨平台学习

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

  10. gRPC C#学习

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

随机推荐

  1. hello cnb

    Huawei executive Meng Wanzhou freed by Canada arrives home in China 目录 关于git merge冲突时候的想法 Git修改commi ...

  2. C/C++ 数据结构优先级队列的实现(使用二级指针)

    #include <iostream> #include <Windows.h> #include <iomanip> //优先级队列的实现 using names ...

  3. js 字符串和16进制的互相转换(转)

    字符串转16进制 function strToHexCharCode(str) { if(str === "") return ""; var hexCharC ...

  4. maven插件汇总

    编译Java源码,一般只需设置编译的jdk版本 <plugin> <groupId>org.apache.maven.plugins</groupId> <a ...

  5. unidbgrid显示图片

    column设置imageoptions属性,visible=true,设置width

  6. js对象深拷贝方法

    JSON.stringify()是目前前端开发过程中最常用的深拷贝方式, 原理是把有个对象序列化成为一个 JSON 字符串,将对象的内容转换成字符串的形式再保存到磁盘上, 再用 JSON.parse( ...

  7. redis的数据操作和python操作redis+关系非关系数据库差异

    关系型数据库(RMDBS) 数据库中表与表的数据之间存在某种关联的内在关系,因为这种关系,所以我们称这种数据库为关系型数据库. 典型:Mysql/MariaDB.postgreSQL.Oracle.S ...

  8. AI 脸部美容,一键让你变瘦变美变老变年轻

    目录 项目效果 项目安装 安装环境 项目使用 项目效果 随着 AI 技术的发展,你不仅随时可以看到自己的老了之后的样子,还能看到自己童年的样子 随着这部分技术的开源,会有越来越多的应用,当然我觉得前景 ...

  9. ASP.NET Core Web API Swagger 按标签Tags分组排序显示

    需求 swagger页面按标签Tags分组显示. 没有打标签Tags的接口,默认归到"未分组". 分组内按接口路径排序 说明 为什么没有使用GroupName对接口进行分组? 暂时 ...

  10. Jan Ozer:高清直播互动场景下的硬编码如何选型?

    前言 高清直播逐渐普及,硬编码也成为大势所趋.在 RTE 2022 大会上,来自 NETINT 的 Jan Ozer 通过一系列的对比测试结果,详细分享了如何为高清直播互动场景进行硬编码的技术选型. ...