5分钟学会 gRPC(上)

简介: 我猜测大部分长期使用 Java 的开发者应该较少会接触 gRPC,毕竟在 Java 圈子里大部分使用的还是 Dubbo/SpringClound 这两类服务框架。我也是近段时间有机会从零开始重构业务才接触到 gRPC 的,当时选择 gRPC 时也有几个原因

介绍


我猜测大部分长期使用 Java 的开发者应该较少会接触 gRPC,毕竟在 Java 圈子里大部分使用的还是 Dubbo/SpringClound 这两类服务框架。


我也是近段时间有机会从零开始重构业务才接触到 gRPC 的,当时选择 gRPC 时也有几个原因:


网络异常,图片无法展示
|


  • 基于云原生的思路开发部署项目,而在云原生中 gRPC 几乎已经是标准的通讯协议了。


  • 开发语言选择了 Go,在 Go 圈子中 gRPC 显然是更好的选择。


  • 公司内部有部分业务使用的是 Python 开发,在多语言兼容性上 gRPC 支持的非常好。


经过线上一年多的平稳运行,可以看出 gRPC 还是非常稳定高效的;rpc 框架中最核心的几个要点:


  • 序列化


  • 通信协议


  • IDL(接口描述语言)


这些在 gRPC 中分别对应的是:


  • 基于 Protocol Buffer 序列化协议,性能高效。


  • 基于 HTTP/2 标准协议开发,自带 stream、多路复用等特性;同时由于是标准协议,第三方工具的兼容性会更好(比如负载均衡、监控等)


  • 编写一份 .proto 接口文件,便可生成常用语言代码。


HTTP/2


学习 gRPC 之前首先得知道它是通过什么协议通信的,我们日常不管是开发还是应用基本上接触到最多的还是 HTTP/1.1 协议。


网络异常,图片无法展示
|


由于 HTTP/1.1 是一个文本协议,对人类非常友好,相反的对机器性能就比较低。

需要反复对文本进行解析,效率自然就低了;要对机器更友好就得采用二进制,HTTP/2 自然做到了。


除此之外还有其他优点:


  • 多路复用:可以并行的收发消息,互不影响


  • HPACK 节省 header 空间,避免 HTTP1.1 对相同的 header 反复发送。


Protocol


gRPC 采用的是 Protocol 序列化,发布时间比 gRPC 早一些,所以也不仅只用于 gRPC,任何需要序列化 IO 操作的场景都可以使用它。


它会更加的省空间、高性能;之前在开发 github.com/crossoverJi… 时就使用它来做数据交互。


package order.v1;
service OrderService{
  rpc Create(OrderApiCreate) returns (Order) {}
  rpc Close(CloseApiCreate) returns (Order) {}
  // 服务端推送
  rpc ServerStream(OrderApiCreate) returns (stream Order) {}
  // 客户端推送
  rpc ClientStream(stream OrderApiCreate) returns (Order) {}
  // 双向推送
  rpc BdStream(stream OrderApiCreate) returns (stream Order) {}
}
message OrderApiCreate{
  int64 order_id = 1;
  repeated int64 user_id = 2;
  string remark = 3;
  repeated int32 reason_id = 4;
}


使用起来也是非常简单的,只需要定义自己的 .proto 文件,便可用命令行工具生成对应语言的 SDK。


具体可以参考官方文档:grpc.io/docs/langua…


调用


protoc --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
    test.proto


网络异常,图片无法展示
|


生成代码之后编写服务端就非常简单了,只需要实现生成的接口即可。


func (o *Order) Create(ctx context.Context, in *v1.OrderApiCreate) (*v1.Order, error) {
  // 获取 metadata
  md, ok := metadata.FromIncomingContext(ctx)
  if !ok {
    return nil, status.Errorf(codes.DataLoss, "failed to get metadata")
  }
  fmt.Println(md)
  fmt.Println(in.OrderId)
  return &v1.Order{
    OrderId: in.OrderId,
    Reason:  nil,
  }, nil
}


网络异常,图片无法展示
|


客户端也非常简单,只需要依赖服务端代码,创建一个 connection 然后就和调用本地方法一样了。


这是经典的 unary(一元)调用,类似于 http 的请求响应模式,一个请求对应一次响应。


网络异常,图片无法展示
|


相关文章
|
数据采集 人工智能
LLM2LLM:LLM2LLM:用 LLM 来增强 LLM !通过教师模型合成数据,增强学生模型的训练数据集
LLM2LLM 是一种创新的迭代数据增强技术,通过教师模型生成合成数据,显著提升大语言模型在数据稀缺任务中的性能。
821 90
LLM2LLM:LLM2LLM:用 LLM 来增强 LLM !通过教师模型合成数据,增强学生模型的训练数据集
|
安全 网络安全
Kali渗透测试:使用Armitage扫描网络
Kali渗透测试:使用Armitage扫描网络
308 3
|
机器学习/深度学习 人工智能 算法
人工智能中的知识表示与推理
人工智能中的知识表示与推理
1023 1
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
418 3
Mysql(4)—数据库索引
|
安全 Linux
探索Linux操作系统的启动过程
在这篇文章中,我们将深入探讨Linux系统的启动流程,从电源开启到登录界面呈现的每一个步骤。我们将揭示BIOS、引导加载器、内核以及初始化进程如何协同工作,使Linux系统顺利启动。通过了解这些过程,读者将能更好地理解Linux系统的工作原理,并为可能出现的启动问题提供解决思路。
332 14
|
网络安全 知识图谱 Python
自监督学习在多模态数据融合中的实践与探索
【8月更文第9天】自监督学习(Self-Supervised Learning, SSL)是一种机器学习方法,它利用未标记的数据来训练模型。这种方法通过设计预训练任务来挖掘数据的内在结构,无需人工标注,从而减少了对大量标注数据的依赖。当应用于多模态数据时,自监督学习可以帮助模型学习到不同模态之间的关联性,进而提高模型在特定下游任务上的表现。
920 7
|
Java Spring 容器
什么情况下会导致@Async异步方法会失效?
什么情况下会导致@Async异步方法会失效?
351 1
|
存储 关系型数据库 Linux
Linux0.11 80X86知识(七)(上)
Linux0.11 80X86知识(七)
278 0
|
测试技术 Python
python 命令行参数 argparse详解
这篇文章是关于Python命令行参数解析库`argparse`的详细解释和使用教程。文中提供了完整的代码模板,包括如何定义命令行参数、如何添加位置参数、可选参数和布尔参数,以及如何解析和使用这些参数。文章还包含了示例代码和测试用例,以展示如何在实际程序中应用`argparse`库。
370 0
|
数据采集 搜索推荐 UED
做的国内网站如何让谷歌收录?
答案是:国内网站的谷歌快速收录可以通过GPC爬虫池技术完成。 理解谷歌的收录机制 了解谷歌的收录机制是至关重要的。 谷歌会通过它的爬虫来搜索和收录网站,但它更偏向于收录具有高质量内容和良好用户体验的网站。 提供高质量的内容 内容是王道。确保你的网站内容是原创的、高质量的,并且为用户提供真正的价值。 确保网站结构清晰 一个清晰的网站结构不仅有助于用户更好地导航你的网站,而且还可以帮助谷歌爬虫更容易地抓取你的网页。
633 2
做的国内网站如何让谷歌收录?