gRPC

RPC

RPC(Remote Procedure Call,远程过程调用)是一种计算机通信协议,允许程序像调用本地函数一样调用另一台计算机上的函数或过程。RPC 屏蔽了底层网络通信的细节,使开发者可以专注于业务逻辑开发,而无需关心数据如何在网络上传输。

RPC 的基本原理

  1. 客户端调用本地代理(Stub)函数,就像调用本地方法一样。
  2. 代理函数将请求序列化(编码),通过网络发送到远程服务器。
  3. 服务器端接收请求并反序列化,调用对应的服务端函数。
  4. 服务器端函数执行后返回结果,服务器将结果序列化并通过网络返回给客户端。
  5. 客户端代理函数接收并反序列化结果,最终返回给调用者。

RPC 的常见实现

  • gRPC:基于 HTTP/2 和 Protocol Buffers,支持多语言。
  • Thrift:Apache 提供的高性能跨语言 RPC 框架。
  • JSON-RPC / XML-RPC:基于 JSON 或 XML 的轻量级协议。
sequenceDiagram participant Caller as Caller (Client) participant Callee as Callee (Server) Caller->>Callee: Invoke procedure Callee->>Callee: Receive procedure Callee->>Callee: Execute procedure Callee->>Callee: Send result Callee-->>Caller: Result from procedure execution

Hello World

使用 Go 语言运行一个简单的 gRPC 项目。

  1. 准备工作:

    brew install go protobuf  # 安装 Go 和 Protobuf
    # 安装 protocol 编译器的 Go 语言插件
    go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
    go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
    

    参见:Protocol Buffer Compiler Installation | Protocol Buffers Documentation

  2. 克隆示例代码:

    git clone -b v1.73.0 --depth 1 https://github.com/grpc/grpc-go
    cd grpc-go/examples/helloworld
    
  3. 使用示例代码进行一次远程过程调用:

    go run greeter_server/main.go  # 启动服务端
    
    go run greeter_client/main.go  # 使用客户端调用服务端过程
    

更新 gRPC 服务

  1. .proto 文件中更新服务定义:

    vim helloworld/helloworld.proto
    
     // The greeting service definition.
     service Greeter {
       // Sends a greeting
       rpc SayHello (HelloRequest) returns (HelloReply) {}
    +  // Sends another greeting
    +  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
     }
    
     // The request message containing the user's name.
     message HelloRequest {
       string name = 1;
     }
    
     // The response message containing the greetings
     message HelloReply {
       string message = 1;
     }
    
  2. 重新生成 gRPC 代码:

    protoc --go_out=. \
           --go_opt=paths=source_relative \
           --go-grpc_out=. \
           --go-grpc_opt=paths=source_relative \
           helloworld/helloworld.proto
    

    将生成 helloworld/helloworld.pb.gohelloworld/helloworld_grpc.pb.go 文件。

  3. 更新服务端代码:

    vim greeter_server/main.go
    
    func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
        return &pb.HelloReply{Message: "Hello again " + in.GetName()}, nil
    }
    
  4. 更新客户端代码:

    vim greeter_client/main.go
    
    func main() {
       // (原有代码)
       r, err = c.SayHelloAgain(ctx, &pb.HelloRequest{Name: *name})
       if err != nil {
           log.Fatalf("could not greet: %v", err)
       }
       log.Printf("Greeting: %s", r.GetMessage())
    }
    
  5. 运行:

    go run greeter_server/main.go  # 启动服务端
    
    go run greeter_client/main.go --name=Alice  # 启动客户端
    

参考:Quick start | gRPC

posted @ 2025-06-28 23:09  Undefined443  阅读(10)  评论(0)    收藏  举报