RPC原理与实践 | 青训营笔记

89 阅读3分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 11 天

今天的内容主要是RPC相关的学习,RPC指的是是一种远程调用协议,可以使得不同进程或者不同机器上的程序之间进行函数调用和数据交互,实现分布式计算。
RPC 的基本原理是:客户端向服务端发起请求,服务端接收请求并执行相应的函数,然后将结果返回给客户端。在这个过程中,RPC 会将数据序列化和反序列化,从而实现不同语言之间的调用。

RPC原理与实践

基本实现

RPC实现通常需要涉及到几个方面:
  1. 定义接口:在客户端和服务端之间定义需要进行的函数以及参数和返回值的格式。
  2. 序列化和反序列化:将数据格式转换为可以在网络上传输的格式。
  3. 传输协议:选择一种可靠的传输协议(如TCP),以保证数据的可靠性和完整性。
  4. 服务注册和发现:将服务注册到一个中心化的服务注册表中,并在客户端发起请求时进行服务的发现。
RPC简单实现如下:

服务端

package main



import (

    "errors"

    "net"

    "net/rpc"

)



type Arith struct{}



type Args struct {

    A, B int

}



type Result int



func (t *Arith) Multiply(args *Args, result *Result) error {

    *result = Result(args.A * args.B)

    return nil

}



func (t *Arith) Divide(args *Args, result *Result) error {

    if args.B == 0 {

    return errors.New("divide by zero")

    }

    *result = Result(args.A / args.B)

    return nil

}



func main() {

    arith := new(Arith)

    rpc.Register(arith)



    l, err := net.Listen("tcp", ":1234")

    if err != nil {

    panic(err)

   }



for {

    conn, err := l.Accept()

    if err != nil {

    continue

}

    go rpc.ServeConn(conn)

    }
}
    

客户端

package main

import (
        "fmt"
        "net/rpc"
)

type Args struct {
        A, B int
}

type Result int

func main() {
        client, err := rpc.Dial("tcp", "localhost:1234")
        if err != nil {
                panic(err)
        }

        args := &Args{7, 8}
        var result Result
        err = client.Call("Arith.Multiply", args, &result)
        if err != nil {
                panic(err)
        }
        fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, result)

        args = &Args{8, 0}
        err = client.Call("Arith.Divide", args, &result)
        if err != nil {
                panic(err)
        }
        fmt.Printf("Arith: %d/%d=%d\n", args.A, args.B, result)
}

常用框架

1、grpc

gRPC 是 Google 开源的高性能 RPC 框架,支持多种编程语言,包括 C++, Java, Python, Ruby 等。它使用 Protocol Buffers(一种高效的序列化和反序列化工具)来定义接口和数据格式,并使用 HTTP/2 作为传输协议。gRPC 支持客户端流和服务器流等多种流式传输模式,能够满足复杂应用场景的需求。

2、kitex

Kitex是字节跳动内部的 Golang 微服务 RPC 框架,具有高性能、可扩展的特点,在字节内部已广泛使用。如果对微服务性能有要求,又希望定制扩展融入自己的治理体系,Kitex 会是一个不错的选择。kitex也是我们本次训练营介绍过的框架

3、2. Apache Thrift

Apache Thrift 是 Facebook 开源的跨语言的 RPC 框架,支持多种编程语言,包括 C++, Java, Python, Ruby 等。它使用 IDL(Interface Description Language)来定义接口和数据格式,并支持多种传输协议和序列化方式,包括 TBinaryProtocol、TCompactProtocol、TJSONProtocol 等。Apache Thrift 可以用于构建高性能、可扩展的分布式系统。