【知识】RPC和gRPC

转载请注明出处:小锋学长生活大爆炸xfxuezhagn.cn

如果本文帮助到了你,欢迎***点赞、收藏、关注***哦~

RPC

1. RPC 的定义

RPC(Remote Procedure Call,远程过程调用) 是一种进程间通信协议 。它允许程序调用另一台机器(或同一台机器的其他进程)上的函数/过程,好像在调用本地函数一样,隐藏了网络通信的细节。

核心思想:

  • 调用者像调用本地函数一样调用远程函数。

  • 底层通过序列化(编码)请求、网络传输、远程解码执行,再将结果返回。

2. RPC 的基本流程

  1. 客户端调用本地代理(Stub)方法。

  2. Stub 将方法名、参数等序列化(通常称为 封送/marshalling)。

  3. 序列化后的数据通过网络发送到服务端。

  4. 服务端收到后,反序列化(解封装),调用真正的服务函数。

  5. 服务函数执行完,将结果序列化,通过网络返回。

  6. 客户端 Stub 收到后反序列化,返回结果。

👉 即:Client -> stub -> network -> server -> real function -> return

3. RPC 的优点

  • 把远程调用封装得像本地函数调用一样,降低了分布式编程的复杂度。

  • 可以跨语言、跨平台。

  • 能在微服务架构中实现服务间解耦。

4. 实现示例

这是使用 socket + pickle 来模拟最原始的 RPC,帮助理解核心原理。

服务端(Server)

python 复制代码
# server.py
import socket
import pickle

def add(x, y):
    return x + y

def handle_request(data):
    func_name, args = pickle.loads(data)
    if func_name == 'add':
        return pickle.dumps(add(*args))
    return pickle.dumps("Unknown function")

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 8000))
server.listen(5)
print("RPC Server running on port 8000...")

while True:
    client, addr = server.accept()
    data = client.recv(1024)
    result = handle_request(data)
    client.send(result)
    client.close()

客户端(Client)

python 复制代码
# client.py
import socket
import pickle

def remote_call(func_name, args):
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.connect(('localhost', 8000))
    client.send(pickle.dumps((func_name, args)))
    data = client.recv(1024)
    client.close()
    return pickle.loads(data)

print("Calling remote add(5, 7)...")
result = remote_call('add', (5, 7))
print("Result:", result)

启动方式

bash 复制代码
python server.py
# 另开终端
python client.py

输出结果

bash 复制代码
Calling remote add(5, 7)...
Result: 12

gRPC

1. gRPC 的定义

gRPC 是 Google 开源的高性能、通用的RPC 框架,用来在分布式系统中进行服务间通信。它基于:

  • HTTP/2(高效双向流传输,支持多路复用、头部压缩、流控)

  • Protocol Buffers(protobuf)(高效序列化)

2. gRPC 的特点

  • **多语言支持:**官方支持 Go、Java、C++、Python、C#、Node.js、PHP、Ruby 等。

  • IDL(接口定义语言)统一规范:.proto 文件定义服务接口和消息结构。自动生成客户端 & 服务端代码。

  • **高效序列化:**使用 protobuf,比 JSON / XML 更紧凑、更快。

  • 基于 HTTP/2:

    • 支持多路复用(一个 TCP 连接上多条流),减少连接数量

    • 头部压缩减少带宽

    • 支持流式数据(Client Streaming、Server Streaming、Bi-directional Streaming)

  • 内置健康检查、超时、重试、负载均衡、认证

3. gRPC 的工作原理

  1. 使用 .proto 文件定义服务和消息。

  2. 通过 protoc 生成客户端 & 服务端代码。

  3. 客户端通过生成的 Stub 调用服务端,就像调用本地方法。

4. 使用示例

下面是一个标准的 gRPC 示例,用 .proto 文件定义接口,然后生成 Python 代码并运行。

定义 proto 文件:新建 helloworld.proto

bash 复制代码
syntax = "proto3";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

生成 Python 代码

bash 复制代码
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto

会生成:

  • helloworld_pb2.py (消息类)

  • helloworld_pb2_grpc.py (服务类)

实现服务端:新建 server.py

python 复制代码
from concurrent import futures
import grpc
import helloworld_pb2
import helloworld_pb2_grpc

class Greeter(helloworld_pb2_grpc.GreeterServicer):
    def SayHello(self, request, context):
        return helloworld_pb2.HelloReply(message=f"Hello, {request.name}")

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    print("gRPC server running on port 50051...")
    server.wait_for_termination()

if __name__ == '__main__':
    serve()

实现客户端:新建 client.py

python 复制代码
import grpc
import helloworld_pb2
import helloworld_pb2_grpc

def run():
    with grpc.insecure_channel('localhost:50051') as channel:
        stub = helloworld_pb2_grpc.GreeterStub(channel)
        response = stub.SayHello(helloworld_pb2.HelloRequest(name="Alice"))
        print("Greeter client received:", response.message)

if __name__ == '__main__':
    run()

启动方式

bash 复制代码
python server.py
# 另开终端
python client.py

输出结果

bash 复制代码
Greeter client received: Hello, Alice

RPC 与 gRPC 的关系与区别

维度 RPC (泛指) gRPC(具体实现)
概念 一种通信思想 / 模式 Google 实现的开源高性能 RPC 框架
传输协议 不固定,可用 HTTP/TCP 等 固定基于 HTTP/2
序列化 XML/JSON/自定义二进制等 Protobuf(默认)
语言支持 取决于具体 RPC 框架 官方支持多语言
IDL 可以是 Thrift/IDL/自定义 Proto 文件(.proto)
性能 通常依赖实现 gRPC 性能优异
流式支持 不一定 原生支持流式(stream)调用
生态工具 分散,因框架而异 gRPC 官方提供丰富工具链
相关推荐
女神下凡6 小时前
这是 Cursor(Composer) 的五种核心交互模式
服务器·人工智能·windows·vscode·microsoft
IT WorryFree7 小时前
三套 Zabbix7.4 API 可直接复制 params 模板
运维·服务器·网络
RisunJan7 小时前
Linux命令-pmap(进程内存映射报告工具)
linux·服务器·网络
未来侦察班7 小时前
网络协议 网络层,万物归于IP
网络·网络协议·协议·ip·网络层·tcpip
luj_17688 小时前
FreeDOS vs MS-DOS PC-DOS 对比解析
服务器·c语言·开发语言·经验分享·算法
Full Stack Developme8 小时前
Linux rm-rf 执行后,硬盘空间变化
linux·运维·服务器
colofullove8 小时前
实时游玩页与 WebSocket 状态管理实现
websocket·网络协议·状态模式
小短腿的代码世界8 小时前
WebSocket协议在Qt中的工业级实现:5层架构设计与万级并发压测验证
qt·websocket·网络协议
沪漂阿龙8 小时前
LangChain 系列之Agent:从固定流程到模型自主决策
服务器·数据库·langchain
生信碱移9 小时前
Vscode 连接 ipynb 选择内核无法自动显示 conda 环境对应的 python
服务器·人工智能·经验分享·vscode·python