5分钟学会 gRPC(下)

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

Bidirectional Stream


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


同理,当客户端、服务端同时都在发送消息也是支持的。


// 服务端
func (o *Order) BdStream(rs v1.OrderService_BdStreamServer) error {
  var value []int64
  for {
    recv, err := rs.Recv()
    if err == io.EOF {
      log.Println(value)
      return nil
    }
    if err != nil {
      panic(err)
    }
    value = append(value, recv.OrderId)
    log.Printf("BdStream receiv msg %v", recv.OrderId)
    rs.SendMsg(&v1.Order{
      OrderId: recv.OrderId,
      Reason:  nil,
    })
  }
  return nil
}
// 客户端
  for i := 0; i < 5; i++ {
    messages, _ := GetMsg(data)
    // 发送消息
    rpc.SendMsg(messages[0])
    // 接收消息
    receive, _ := rpc.RecvMsg()
    marshalIndent, _ := json.MarshalIndent(receive, "", "\t")
    fmt.Println(string(marshalIndent))
  }
  rpc.CloseSend()


其实就是将上诉两则合二为一。


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


通过调用示例很容易理解。


元数据


gRPC 也支持元数据传输,类似于 HTTP 中的 header


// 客户端写入
  metaStr := `{"lang":"zh"}`
  var m map[string]string
  err := json.Unmarshal([]byte(metaStr), &m)
  md := metadata.New(m)
  // 调用时将 ctx 传入即可
  ctx := metadata.NewOutgoingContext(context.Background(), md)
  // 服务端接收
  md, ok := metadata.FromIncomingContext(ctx)
  if !ok {
    return nil, status.Errorf(codes.DataLoss, "failed to get metadata")
  }
  fmt.Println(md) 


gRPC gateway


gRPC 虽然功能强大使用也很简单,但对于浏览器、APP的支持还是不如 REST 应用广泛(浏览器也支持,但应用非常少)。


为此社区便创建了 github.com/grpc-ecosys… 项目,可以将 gRPC 服务暴露为 RESTFUL API。


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


为了让测试可以习惯用 postman 进行接口测试,我们也将 gRPC 服务代理出去,更方便的进行测试。


反射调用


作为一个 rpc 框架,泛化调用也是必须支持的,可以方便开发配套工具;gRPC 是通过反射支持的,通过拿到服务名称、pb 文件进行反射调用。


github.com/jhump/proto… 这个库封装了常见的反射操作。


上图中看到的可视化 stream 调用也是通过这个库实现的。


负载均衡


由于 gRPC 是基于 HTTP/2 实现的,客户端和服务端会保持长连接;这时做负载均衡就不像是 HTTP 那样简单了。


而我们使用 gRPC 想达到效果和 HTTP 是一样的,需要对请求进行负载均衡而不是连接。


通常有两种做法:


  • 客户端负载均衡


  • 服务端负载均衡


客户端负载均衡在 rpc 调用中应用广泛,比如 Dubbo 就是使用的客户端负载均衡。

gRPC 中也提供有相关接口,具体可以参考官方demo。


github.com/grpc/grpc-g…


客户端负载均衡相对来说对开发者更灵活(可以自定义适合自己的策略),但相对的也需要自己维护这块逻辑,如果有多种语言那就得维护多份。


所以在云原生这个大基调下,更推荐使用服务端负载均衡。


可选方案有:


  • istio


  • envoy


  • apix


这块我们也在研究,大概率会使用 envoy/istio


总结


gRPC 内容还是非常多的,本文只是作为一份入门资料希望能让不了解 gRPC 的能有一个基本认识;这在云原生时代确实是一门必备技能。


对文中的 gRPC 客户端感兴趣的朋友,可以参考这里的源码:


github.com/crossoverJi…



相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
Java Go Apache
gRPC vs Thrift
远程过程调用(Remote Procedure Call,RPC)服务于分布式架构,本文从分布式构架面临的问题,期望的结果,引出两种比较受关注的RPC框架,并从框架的出身、实现原理、特性、性能等方面做了对比分析,从而给出两者之间的选择建议。
11087 0
|
3月前
|
Dubbo Java 应用服务中间件
grpc&rpc
grpc&rpc
|
5月前
|
负载均衡 监控 安全
介绍grpc
gRPC(gRPC Remote Procedure Call)是一种高性能、开源的远程过程调用(RPC)框架,最初由Google开发并开源。它基于HTTP/2协议传输,使用Protocol Buffers(ProtoBuf)作为默认的序列化机制,支持多种编程语言,并提供了强大的功能和特性。
|
4月前
|
JSON 网络协议 API
GRPC远程调用
GRPC远程调用
88 0
|
5月前
|
XML Go 开发工具
RPC简介和grpc的使用
RPC简介和grpc的使用
59 0
|
6月前
|
XML JSON 网络协议
gRPC介绍
gRPC介绍
|
7月前
|
JSON Go 网络架构
《gRPC vs REST:何时选择哪一个》
《gRPC vs REST:何时选择哪一个》
53 0
|
XML JSON 自然语言处理
gRPC系列 :RPC 框架原理是?gRPC 是什么?gRPC设计原则
gRPC系列 :RPC 框架原理是?gRPC 是什么?gRPC设计原则
1490 0
gRPC系列 :RPC 框架原理是?gRPC 是什么?gRPC设计原则
|
JSON 网络协议 Dubbo
gRPC(一)入门:什么是RPC?
RPC是一种方法,而HTTP是一种协议。两者都常用于实现服务,在这个层面最本质的区别是RPC服务主要工作在TCP协议之上(也可以在HTTP协议),而HTTP服务工作在HTTP协议之上。由于HTTP协议基于TCP协议,所以RPC服务天然比HTTP更轻量,效率更胜一筹。
330 0
gRPC(一)入门:什么是RPC?
|
网络协议 大数据 Go
gRPC(四)基础:gRPC流
Client发送完成后需要手动调用Close()或者CloseSend()方法关闭stream,Server端则return nil就会自动 Close。
626 0
gRPC(四)基础:gRPC流