介绍

gRPC(Google Remote Procedure Call)是一种高性能、开源和通用的远程过程调用(RPC)框架,最初由Google开发,现已成为CNCF(Cloud Native Computing Foundation)的一部分。它基于HTTP/2协议,并使用Protocol Buffers(protobuf)作为默认的接口定义语言和消息交换格式。gRPC旨在简化跨服务通信的实现,提供高效、可扩展的解决方案。支持多种编程语言(如 C、C++、Java、Go、Python 等),并提供强大的特性和工具来简化分布式系统之间的通信。

使用方法与普通的http调用相同,也分为server端与client端。

server端提供一些方法。并启动一个server并为其进程指定一个端口。

client端则通过传入ip和端口寻找到server端,并通过在本地执行这个方法,在远程执行相应的方法,并获取返回值。

image-20241126154512613

特性

RPC利用HTTP/2进行通信,这为低延迟、高并发、双向流式数据传输等提供了支持。它采用了以下几个特性来优化性能和用户体验:

  • Multiplexing:允许多个请求和响应通过一个连接并行传输,减少了连接数和延迟。

  • 流式传输:支持客户端流、服务端流和双向流式通信,可以处理实时数据流或大规模数据传输。

  • 头部压缩:使用HTTP/2的头部压缩来减少传输的大小,提升效率。

  • 连接复用:客户端与服务器之间的TCP连接可以保持活跃,避免了频繁建立和销毁连接的开销。

  • 安全性: gRPC默认支持TLS(传输层安全)加密,确保了客户端和服务端之间的通信安全。此外,gRPC还支持认证、授权等机制,便于集成到安全要求较高的环境中。

demo

Protocol Buffers 文件(example.proto):

syntax = "proto3";
​
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}
​
message HelloRequest {
  string name = 1;
}
​
message HelloResponse {
  string message = 1;
}

生成grpc代码:

protoc --go_out=. --go-grpc_out=. example.proto

服务端

package main
​
import (
    "context"
    "log"
    "net"
​
    "google.golang.org/grpc"
    pb "path/to/your/generated/code"
)
​
type server struct{}
​
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
    return &pb.HelloResponse{Message: "Hello, " + in.GetName()}, nil
}
​
func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    log.Println("Server started on port 50051...")
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

客户端

package main
​
import (
    "context"
    "log"
    "google.golang.org/grpc"
    pb "path/to/your/generated/code"
)
​
func main() {
    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("failed to connect: %v", err)
    }
    defer conn.Close()
​
    c := pb.NewGreeterClient(conn)
    name := "World"
    r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Greeting: %s", r.GetMessage())
}

本地套接字实现进程间通信:IPC

通过套接字进行本地进程间通信(IPC)是一个常见的方法,尤其在 UNIX 和类 UNIX 系统中。套接字可以在同一台机器上的两个进程之间建立通信通道。以下是一个简单的介绍和示例,说明如何通过 Unix 套接字进行本地进程间通信。

Unix 套接字:

Unix 套接字是一种特殊类型的文件,可以在文件系统中被引用,并且允许两个进程在同一主机上通过读写这个文件进行通信。与网络套接字不同,Unix 套接字只在本地系统上有效。

步骤:

1.创建服务器和客户端套接字

2.服务器绑定套接字到一个文件路径

3.服务器监听连接

4.客户端连接到服务器

5.读写数据

6.关闭套接字

在 Kubernetes 的上下文中,Kubelet 和容器运行时(如 containerd、CRI-O 等)之间的通信通过 gRPC 实现。gRPC 是一种高性能、开源和通用的 RPC 框架,它使用 Protocol Buffers 作为接口定义语言(IDL)。在本地进程间通信的场景下,gRPC 可以通过 Unix 套接字进行通信。