Go 中 RPC 的使用教程

打印 上一主题 下一主题

主题 1612|帖子 1612|积分 4836

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
前言

RPC(Remote Procedure Call)是一种允许程序调用远程服务器上函数的方法,调用过程对于开发者来说像是调用本地函数一样方便。Go 语言自带了强大的 net/rpc 库,可以大概让开发者轻松实现基于 Go 的 RPC 服务。本文将先容 Go 中 RPC 的使用方法,并通过简单示例展示如何搭建 RPC 服务和客户端。

一、什么是 RPC?

RPC(远程过程调用)是一种跨网络通讯协议,允许程序在不同的主机上执行代码而不需要明确处理底层网络通讯。使用 RPC,开发者只需编写服务端的逻辑,然后客户端可以像调用本地函数一样调用服务端的函数,底层的网络传输、序列化和反序列化都由 RPC 框架处理。
在 Go 中,RPC 是通过 net/rpc 包实现的,Go 标准库还支持 JSON-RPC 和 HTTP 传输协议。

二、Go 中 RPC 的基本原理

Go 中的 RPC 框架遵循以下几条规则:

  • 服务对象是公开的结构体类型。
  • 服务对象的方法必须是公开的,并且方法必须有两个参数和一个返回值。第一个参数是输入参数,第二个参数是指针类型用于吸收返回结果,返回值是 error 类型。
  • 客户端通过 net/rpc 库向服务端发出哀求,服务端执行对应的函数,返回结果。

三、Go 中 RPC 的使用步调

1. 界说服务

起首,我们需要界说一个服务。这个服务是一个 Go 结构体,此中包含一些方法供客户端调用。
  1. package main
  2. import (
  3.     "errors"
  4.     "net"
  5.     "net/rpc"
  6.     "fmt"
  7. )
  8. // 定义服务结构体
  9. type Arith struct{}
  10. // 定义输入参数
  11. type Args struct {
  12.     A, B int
  13. }
  14. // 定义服务方法
  15. func (t *Arith) Multiply(args *Args, reply *int) error {
  16.     *reply = args.A * args.B
  17.     return nil
  18. }
  19. func (t *Arith) Divide(args *Args, reply *int) error {
  20.     if args.B == 0 {
  21.         return errors.New("divide by zero")
  22.     }
  23.     *reply = args.A / args.B
  24.     return nil
  25. }
复制代码
在上面的代码中,我们界说了 Arith 结构体,它有两个方法 Multiply 和 Divide,分别用于乘法和除法运算。
2. 启动 RPC 服务

接下来,我们需要启动一个 RPC 服务器,让客户端可以通过网络调用这个服务。
  1. func main() {
  2.     arith := new(Arith)
  3.     rpc.Register(arith)  // 注册服务
  4.     listener, err := net.Listen("tcp", ":1234")  // 监听端口
  5.     if err != nil {
  6.         fmt.Println("Error starting server:", err)
  7.     }
  8.     fmt.Println("Server is listening on port 1234...")
  9.     for {
  10.         conn, err := listener.Accept()  // 接收连接
  11.         if err != nil {
  12.             fmt.Println("Error accepting connection:", err)
  13.             continue
  14.         }
  15.         go rpc.ServeConn(conn)  // 使用 goroutine 处理每个连接
  16.     }
  17. }
复制代码
这段代码启动了一个监听在 1234 端口的 RPC 服务器。每当有客户端哀求毗连时,服务器会处理该毗连并执行相应的 RPC 方法。
3. 创建 RPC 客户端

服务端已经预备好了,接下来我们需要编写客户端代码,客户端将通过 RPC 远程调用服务端的函数。
  1. package main
  2. import (
  3.     "fmt"
  4.     "log"
  5.     "net/rpc"
  6. )
  7. type Args struct {
  8.     A, B int
  9. }
  10. func main() {
  11.     client, err := rpc.Dial("tcp", "localhost:1234")  // 连接服务端
  12.     if err != nil {
  13.         log.Fatal("dialing:", err)
  14.     }
  15.     // 调用 Multiply 方法
  16.     args := Args{A: 7, B: 8}
  17.     var reply int
  18.     err = client.Call("Arith.Multiply", args, &reply)
  19.     if err != nil {
  20.         log.Fatal("arith error:", err)
  21.     }
  22.     fmt.Printf("Arith: %d * %d = %d\n", args.A, args.B, reply)
  23.     // 调用 Divide 方法
  24.     args = Args{A: 10, B: 2}
  25.     err = client.Call("Arith.Divide", args, &reply)
  26.     if err != nil {
  27.         log.Fatal("arith error:", err)
  28.     }
  29.     fmt.Printf("Arith: %d / %d = %d\n", args.A, args.B, reply)
  30. }
复制代码
在这段代码中,客户端起首通过 rpc.Dial 函数毗连到服务端。毗连创建后,客户端调用远程的 Multiply 和 Divide 方法,并输出结果。
4. 运行程序

起首在一个终端启动服务端:
  1. go run server.go
复制代码
然后在另一个终端运行客户端:
  1. go run client.go
复制代码
运行后,客户端会输出雷同以下内容:
  1. Arith: 7 * 8 = 56
  2. Arith: 10 / 2 = 5
复制代码

四、Go 中的 RPC 进阶

1. 异步调用

Go 的 RPC 框架支持异步调用,可以通过 Go 方法实现。它会返回一个 Call 对象,通过该对象可以获取异步调用的结果。
  1. call := client.Go("Arith.Multiply", args, &reply, nil)
  2. replyCall := <-call.Done  // 等待结果
  3. fmt.Printf("Async result: %d * %d = %d\n", args.A, args.B, replyCall.Reply)
复制代码
2. 使用 HTTP 作为传输协议

Go 也支持通过 HTTP 协议举行 RPC 通讯,只需稍加设置:
  1. rpc.HandleHTTP()
  2. listener, err := net.Listen("tcp", ":1234")
  3. go http.Serve(listener, nil)
复制代码
在客户端中,通过 rpc.DialHTTP 毗连服务端:
  1. client, err := rpc.DialHTTP("tcp", "localhost:1234")
复制代码

五、总结

通过 net/rpc,Go 提供了一个简单而高效的 RPC 实现。它让开发者可以轻松地构建分布式体系,并且底层的通讯和序列化都由库主动处理,极大地低沉了开发复杂性。本文通过一个简单的示例展示了如安在 Go 中使用 RPC,盼望能为你的开发提供帮助。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

羊蹓狼

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表