MST
星途 面试题库

面试题:微服务架构下Go语言RPC实现的基础问题

在Go语言的微服务架构中,简述RPC(远程过程调用)的基本原理,以及使用Go标准库实现一个简单RPC服务端和客户端的关键步骤有哪些?
24.0万 热度难度
后端开发微服务架构

知识考点

AI 面试

面试题答案

一键面试

RPC基本原理

  1. 定义:RPC 允许程序像调用本地函数一样调用不同地址空间(通常是不同机器)的函数,而无需显式处理网络通信细节。
  2. 原理步骤
    • 客户端存根(Stub):客户端调用本地的 RPC 函数(存根),这个函数看起来像本地函数调用,但实际上是为了发起远程调用做准备。它负责将调用的参数进行序列化(编组),生成网络消息。
    • 网络传输:通过网络协议(如 TCP、UDP 等)将序列化后的消息发送到服务端。
    • 服务端存根:服务端接收到网络消息后,由服务端存根进行反序列化(解组),还原出原始的调用参数。然后根据调用信息找到对应的本地函数进行调用。
    • 结果返回:服务端本地函数执行完毕后,将结果返回给服务端存根,服务端存根再将结果序列化并通过网络发送回客户端。客户端存根接收到结果后进行反序列化,将结果返回给客户端调用者,就像本地函数调用返回一样。

使用Go标准库实现简单RPC服务端关键步骤

  1. 定义服务接口
    type Arith int
    
    type Args struct {
        A, B int
    }
    
    type Quotient struct {
        Quo, Rem int
    }
    
    func (t *Arith) Multiply(args *Args, reply *int) error {
        *reply = args.A * args.B
        return nil
    }
    
    func (t *Arith) Divide(args *Args, quo *Quotient) error {
        if args.B == 0 {
            return errors.New("divide by zero")
        }
        quo.Quo = args.A / args.B
        quo.Rem = args.A % args.B
        return nil
    }
    
  2. 注册服务
    func main() {
        arith := new(Arith)
        rpc.Register(arith)
    }
    
  3. 监听和服务
    l, e := net.Listen("tcp", ":1234")
    if e!= nil {
        log.Fatal("listen error:", e)
    }
    for {
        conn, err := l.Accept()
        if err!= nil {
            log.Fatal("accept error:", err)
        }
        rpc.ServeConn(conn)
    }
    

使用Go标准库实现简单RPC客户端关键步骤

  1. 连接服务端
    client, err := rpc.Dial("tcp", "localhost:1234")
    if err!= nil {
        log.Fatal("dialing:", err)
    }
    
  2. 调用远程方法
    var reply int
    args := &Args{7, 8}
    err = client.Call("Arith.Multiply", args, &reply)
    if err!= nil {
        log.Fatal("arith error:", err)
    }
    fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply)