当前位置: 首页 > news >正文

Go RPC 和 gRPC 技术详解

引言

在分布式系统中,服务之间的通信是非常重要的组成部分。远程过程调用 (RPC) 是一种广泛使用的通信方式,它允许程序在不同的计算机上执行函数或过程,就像调用本地函数一样。随着微服务架构的流行,RPC 成为了连接各个服务的重要桥梁。本文将探讨 Go 语言中的 RPC 以及它的高级版本 gRPC。

什么是 RPC?

RPC 是一种协议,它允许客户端程序调用远程服务器上的函数或方法,而无需了解底层网络细节。通常,客户端和服务器通过网络通信,并且需要一种方式来序列化和反序列化数据。

特点

  • 透明性:客户端像调用本地函数一样调用远程函数。
  • 简单性:客户端不需要了解底层网络协议。
  • 安全性:可以通过加密和认证等手段保证通信的安全。

Go 语言中的标准 RPC

Go 提供了内置的支持来实现 RPC,主要通过 net/rpc 包。它支持多种序列化方式,包括 JSON 和 XML。

客户端示例

package mainimport ("log""net/rpc"
)func main() {client, err := rpc.DialHTTP("tcp", "localhost:1234")if err != nil {log.Fatal("dialing:", err)}defer client.Close()var reply interr = client.Call("Arith.Multiply", &ArithArgs{7, 8}, &reply)if err != nil {log.Fatal("arith error:", err)}log.Printf("Arith: %d", reply)
}

服务器端示例

package mainimport ("log""net/rpc""net/rpc/jsonrpc"
)type Arith intfunc (t *Arith) Multiply(args *ArithArgs, reply *int) error {*reply = args.A * args.Breturn nil
}type ArithArgs struct {A, B int
}func main() {server := rpc.NewServer()server.Register(new(Arith))listener, err := net.Listen("tcp", ":1234")if err != nil {log.Fatal("listening:", err)}for {conn, err := listener.Accept()if err != nil {log.Fatal("accepting:", err)}go jsonrpc.ServeConn(conn)}
}

gRPC

gRPC 是 Google 开发的一个高性能、开源和通用的 RPC 框架。它基于 HTTP/2 协议,提供了流式通信、消息压缩等功能。

为什么选择 gRPC?

  • 高效:使用 Protocol Buffers 作为默认的序列化方式。
  • 流式传输:支持双向流式传输。
  • 丰富的功能:支持认证、负载均衡等。
  • 广泛的客户端支持:支持多种编程语言。

gRPC 的工作流程

  1. 定义服务:使用 .proto 文件定义服务接口。
  2. 生成代码:使用 Protocol Buffers 编译器生成服务的存根代码。
  3. 实现服务:编写服务的具体逻辑。
  4. 客户端调用:客户端通过 gRPC 存根调用远程服务。

gRPC 示例

定义服务
syntax = "proto3";service CalculatorService {rpc Add (AddRequest) returns (AddResponse);
}message AddRequest {int32 x = 1;int32 y = 2;
}message AddResponse {int32 sum = 1;
}
实现服务
package mainimport ("context""log""net"pb "path/to/your/proto/package""google.golang.org/grpc"
)type server struct{}func (s *server) Add(ctx context.Context, in *pb.AddRequest) (*pb.AddResponse, error) {sum := in.GetX() + in.GetY()return &pb.AddResponse{Sum: sum}, nil
}func main() {lis, err := net.Listen("tcp", ":50051")if err != nil {log.Fatalf("failed to listen: %v", err)}s := grpc.NewServer()pb.RegisterCalculatorServiceServer(s, &server{})if err := s.Serve(lis); err != nil {log.Fatalf("failed to serve: %v", err)}
}
客户端
package mainimport ("context""log""time"pb "path/to/your/proto/package""google.golang.org/grpc"
)func main() {conn, err := grpc.Dial(":50051", grpc.WithInsecure())if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()client := pb.NewCalculatorServiceClient(conn)ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()r, err := client.Add(ctx, &pb.AddRequest{X: 2, Y: 2})if err != nil {log.Fatalf("could not add: %v", err)}log.Printf("Sum: %d", r.Sum)
}

结论

无论是传统的 RPC 还是新的 gRPC,在 Go 语言中实现远程服务调用都变得非常简单。gRPC 以其高性能和丰富的功能集成为分布式系统中的首选方案。


http://www.mrgr.cn/news/5511.html

相关文章:

  • 学习Math.random()的应用
  • 前端html+js实现懒加载的两种常见方法
  • 一文弄懂 LLM 结构化数据生成原理
  • 基于Python自动连接汕头大学校园网
  • Axios介绍;前后端分离开发的介绍;YAPI的使用;Vue项目简介、入门;Elementui的使用;nginx介绍
  • 支付宝开放平台-开发者社区——AI 日报「8 月23 日」
  • BaseCTF WEEK1 re复现-入土为安的第24天
  • halcon1
  • [Linux#40][线程] 线程控制 | 多线程
  • 设计模式六大原则:迪米特法则详细说明和案例示范
  • windows docker 执行apt-get 权限问题
  • 大数据-95 Spark 集群 SparkSQL Action与Transformation操作 详细解释与测试案例
  • Vue3 provide(父) + inject(子、子的子...)进行值的传递及显示
  • iOS 开发:Object-C 和 Swift 的区别 (AI问答)
  • 三种方法加密图纸!2024如何对CAD图纸进行加密?分享给你
  • 回归预测|基于NGO-TCN-BiGRU-Attention的数据预测Matlab程序 多特征输入单输出 含基础模型
  • 知识竞赛答题设备及答题方式有哪些
  • 学习记录第二十八天
  • langchian 批次调用 prompt
  • python 面试指南