Python 实现 gRPC 与 原始 RPC 的对比:理解 RPC 的基本功能

在分布式系统中,远程过程调用(Remote Procedure Call,RPC) 是一项关键技术,它允许不同计算机之间像调用本地函数一样进行通信。本文通过 Python 代码对比 gRPC 和 原始 RPC(基于 Socket) 来分析 RPC 的基本功能。


1. 什么是 RPC?

RPC(Remote Procedure Call) 是一种允许程序在 不同的进程、机器 之间像调用本地函数一样执行远程函数的技术。本地进程(客户端)调用远程服务器上的方法,服务器执行方法后将结果返回给客户端。

RPC 的核心功能

  1. 客户端-服务器通信:通过网络请求调用远程方法
  2. 序列化与反序列化:将数据转换成可传输格式(JSON、Protobuf)
  3. 自动化传输:隐藏底层通信逻辑,让调用方式更直观
  4. 错误处理:支持异常返回

2. gRPC 与 原始 RPC(基于 Socket) 对比

功能gRPC原始 RPC(Socket)
序列化Protobuf(二进制,高效)JSON(文本格式,易读但体积大)
传输协议HTTP/2(高性能)纯 TCP(需手写协议)
代码生成支持 .proto 自动生成需手写所有请求/响应逻辑
流式通信支持(客户端流、服务器流、双向流)需要手动实现
多语言支持Python、Go、Java 等仅限 Python(除非自行实现跨语言支持)
安全性内置 TLS/SSL 支持需手动加密
性能高效、低延迟较低(TCP+JSON 开销大)

接下来,我们分别实现 gRPC 和 原始 RPC 进行对比。


3. gRPC 实现

gRPC 使用 Protobuf 进行序列化,并自动生成 客户端和服务器端代码

3.1 定义 gRPC 服务

创建 rpc_service.proto

syntax = "proto3";package rpcdemo;service MathService {rpc Add (AddRequest) returns (AddResponse);
}message AddRequest {int32 a = 1;int32 b = 2;
}message AddResponse {int32 result = 1;
}

生成 Python 代码:

python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. rpc_service.proto

3.2 gRPC 服务器

import grpc
from concurrent import futures
import rpc_service_pb2
import rpc_service_pb2_grpcclass MathService(rpc_service_pb2_grpc.MathServiceServicer):def Add(self, request, context):return rpc_service_pb2.AddResponse(result=request.a + request.b)def serve():server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))rpc_service_pb2_grpc.add_MathServiceServicer_to_server(MathService(), server)server.add_insecure_port('[::]:50051')server.start()print("gRPC Server started on port 50051")server.wait_for_termination()if __name__ == "__main__":serve()

3.3 gRPC 客户端

import grpc
import rpc_service_pb2
import rpc_service_pb2_grpcdef run():channel = grpc.insecure_channel('localhost:50051')stub = rpc_service_pb2_grpc.MathServiceStub(channel)response = stub.Add(rpc_service_pb2.AddRequest(a=10, b=20))print("gRPC Response:", response.result)if __name__ == "__main__":run()

4. 原始 RPC(Socket 实现)

使用 Python 原生 socket 来模拟 RPC 机制。

4.1 原始 RPC 服务器

import socket
import json# 定义计算服务
def add(a, b):return a + b# 注册可调用的函数
FUNCTIONS = {"add": add
}def handle_client_connection(client_socket):""" 处理客户端请求 """try:# 接收数据data = client_socket.recv(1024).decode('utf-8')request = json.loads(data)# 获取方法名和参数method = request.get("method")params = request.get("params", [])# 执行方法if method in FUNCTIONS:result = FUNCTIONS[method](*params)response = {"status": "success", "result": result}else:response = {"status": "error", "message": "Method not found"}# 发送响应client_socket.send(json.dumps(response).encode('utf-8'))except Exception as e:response = {"status": "error", "message": str(e)}client_socket.send(json.dumps(response).encode('utf-8'))finally:client_socket.close()def start_server(host='localhost', port=5000):""" 启动RPC服务器 """server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind((host, port))server.listen(5)print(f"RPC Server listening on {host}:{port}")while True:client_sock, _ = server.accept()handle_client_connection(client_sock)if __name__ == "__main__":start_server()

4.2 原始 RPC 客户端

import socket
import jsondef rpc_call(method, params, host='localhost', port=5000):""" 发送 RPC 请求 """client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect((host, port))# 构造请求数据request = json.dumps({"method": method,"params": params})# 发送数据client.send(request.encode('utf-8'))# 接收响应response_data = client.recv(1024).decode('utf-8')response = json.loads(response_data)client.close()return responseif __name__ == "__main__":result = rpc_call("add", [10, 20])print("RPC Response:", result)

5. 总结

5.1 gRPC 与 原始 RPC 的区别

特性gRPC原始 RPC(Socket)
序列化方式Protobuf(高效二进制)JSON(文本格式)
传输协议HTTP/2TCP
自动代码生成支持(通过 .proto不支持(需手动实现)
流式传输支持(双向流、流式响应)需要手动实现
多语言支持支持多种语言(Python、Go、Java 等)仅支持 Python
性能高效,低延迟相对较慢(TCP+JSON 有额外开销)

5.2 选择哪种 RPC?

gRPC 适用于:

  • 分布式系统(微服务架构)
  • 多语言通信(前端、后端不同语言)
  • 高性能数据传输(Protobuf + HTTP/2)

原始 RPC(Socket) 适用于:

  • 小型应用(轻量级进程间通信)
  • 学习 RPC 原理
  • 内部服务(单机内进程间通信)

若有错误与不足请指出,关注DPT一起进步吧!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/14947.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CANoe工具使用技巧 --- 如何使用 “on ethernetPacket “事件处理程序

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

数据库5(MySQL版)

作业要求 触发器 mysql> create trigger after_order_insert -> after insert on orders -> for each row -> update goods set num num - new.onum where gid new.gid; mysql> create trigger after_order_delete -> after delete on or…

【异常解决】在idea中提示 hutool 提示 HttpResponse used withoud try-with-resources statement

博主介绍:✌全网粉丝22W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

浅析Ruby类污染及其在Sinatra框架下的利用

和JavaScript中的原型链污染类似,Ruby中也存在类似的概念——类污染,两者都是对象进行不安全的递归合并导致的。 网上也没有相关的分析文章,只有下面这篇文章应该是第一次谈到这个问题 Class Pollution in Ruby: A Deep Dive into Exploiti…

SamWaf开源轻量级的网站应用防火墙(安装包),私有化部署,加密本地存储的数据,易于启动,并支持 Linux 和 Windows 64 位和 Arm64

一、SamWaf轻量级开源防火墙介绍 (文末提供下载) SamWaf网站防火墙是一款适用于小公司、工作室和个人网站的开源轻量级网站防火墙,完全私有化部署,数据加密且仅保存本地,一键启动,支持Linux,Wi…

14vue3实战-----获取用户信息和用户的菜单树信息

14vue3实战-----获取用户信息和用户的菜单树信息 1.获取用户信息1.1封装接口1.2优化 2.获取用户的菜单树信息 1.获取用户信息 1.1封装接口 后端有根据id获取用户信息的接口,前端需要把该接口封装一下: service/login/login.ts: import hyRequest from…

洛谷算法1-3 暴力枚举

目录 1 P2241统计方形 2 三连击 3 选数 4 P1088 [NOIP2004 普及组] 火星人 5 P3799 小 Y 拼木棒 排列组合 6 P2392 kkksc03考前临时抱佛脚 7 P2036 [COCI2008-2009 #2] PERKET 1 P2241统计方形 思路: 本题中,矩阵数量正方形数量长方形数量&#xff0…

CSS Overflow 属性详解:控制内容溢出的利器

在前端开发中,处理内容溢出是一个常见的需求。CSS 提供了 overflow 属性,帮助我们控制当内容超出元素框时的显示方式。本文将详细介绍 overflow 属性的各种取值及其应用场景。 1. 什么是 overflow 属性? overflow 属性用于控制当元素的内容…

链表和 list

一、单链表的模拟实现 1.实现方式 链表的实现方式分为动态实现和静态实现两种。 动态实现是通过 new 申请结点,然后通过 delete 释放结点的形式构造链表。这种实现方式最能体 现链表的特性; 静态实现是利用两个数组配合来模拟链表。一个表示数据域&am…

面向对象程序设计-实验3

题目1 &#xff08;给出题目描述&#xff09;设计一个类CRectangle 代码清单&#xff1a; #include<iostream> using namespace std; class CRectangle { public: CRectangle() { m_l1.0; m_w1.0; } void get() { cin>>m_l; if(m_l>50) { m_l1.0; } cin&g…

2025.1.8(qt图形化界面之消息框)

笔记&#xff08;后期复习补充&#xff09; 作业 1> 手动将登录项目实现&#xff0c;不要使用拖拽编程 并且&#xff0c;当点击登录按钮时&#xff0c;后台会判断账号和密码是否相等&#xff0c;如果相等给出登录成功的提示&#xff0c;并且关闭当前界面&#xff0c;发射一…

windows10 wsa 安卓子系统终结版

windows10 wsa 安卓子系统终结版 链接&#xff1a;https://pan.xunlei.com/s/VOIdoPPmqdUcgw3daFSbh2dAA1?pwdbe3r# windows10 wsa 安卓子系统终结版&#xff0c;包含三个文件. 1: windows10 wsa v2407.40000.4.0 x64 安卓子系统终结版。 2: Apk lnstaller v1.7 用于识别A…

计算机网络应用层:模型、系统与协议全解析!!!

应用层 应用层对应用程序的通信提供服务 应用层协议定义: 应用进程交换的报文类型&#xff0c;请求还是响应? 各种报文类型的语法&#xff0c;如报文中的各个字段及其详细描述&#xff0c; 字段的语义&#xff0c;即包含在字段中的信息的含义。 进程何时、如何发送报文&#x…

【分布式理论8】分布式调用之:四种IO模型

文章目录 一. 四种IO模型1. 同步阻塞 IO&#xff08;Blocking IO&#xff09;2. 同步非阻塞 IO&#xff08;Non-blocking IO&#xff09;3. IO 多路复用&#xff08;IO Multiplexing&#xff09;4. 异步 IO&#xff08;Asynchronous IO&#xff09;在 RPC 中的作用5. 总结 选择…

元宇宙中的隐私与数据保护:Facebook 的挑战与机遇

随着数字技术的飞速发展&#xff0c;元宇宙&#xff08;Metaverse&#xff09;正逐渐成为未来互联网的新舞台。Meta&#xff0c;作为这一领域的先行者&#xff0c;正面临着隐私与数据保护的双重挑战。本文将探讨 Meta 在元宇宙中的隐私与数据保护问题&#xff0c;并分析其可能的…

Word中Ctrl+V粘贴报错问题

Word中CtrlV粘贴时显示“文件未找到&#xff1a;MathPage.WLL”的问题 Word的功能栏中有MathType&#xff0c;但无法使用&#xff0c;显示灰色。 解决方法如下&#xff1a; 首先找到MathType安装目录下MathPage.wll文件以及MathType Commands 2016.dotm文件&#xff0c;分别复…

Stability AI 联合 UIUC 提出单视图 3D 重建方法SPAR3D,可0.7秒完成重建并支持交互式用户编辑。

Stability AI 联合 UIUC 提出一种简单而有效的单视图 3D 重建方法 SPAR3D&#xff0c;这是一款最先进的 3D 重建器&#xff0c;可以从单视图图像重建高质量的 3D 网格。SPAR3D 的重建速度很快&#xff0c;只需 0.7 秒&#xff0c;并支持交互式用户编辑。 相关链接 论文&#xf…

Spring Cloud 04 - 负载均衡和外部服务访问

Ribbon & Feign 文章目录 Ribbon & Feign一&#xff1a;Ribbon负载均衡1&#xff1a;介绍 2&#xff1a;ribbon的五大核心组件二&#xff1a;Feign外部接口访问1&#xff1a;Feign概述2&#xff1a;Feign vs OpenFeign3&#xff1a;使用示例3.1&#xff1a;注解支持3.2…

力扣--链表

相交链表 法一&#xff1a; 把A链表的节点都存HashSet里&#xff0c;遍历B链表找相同的节点 法二&#xff1a; 把A、B指针都移到末尾&#xff0c;再同时往回走&#xff0c;每次往回走都比较 当前节点的下一节点&#xff08;a.next b.next ?)是否相同&#xff0c;当不相同…

antd pro常见代码示例-ProTable

1、protable使用 这是antd Pro 封装的一个table组件&#xff0c;提供了很多好用的方法&#xff0c; proTable地址&#xff1a; protable官网 代码示例&#xff1a; <ProTableactionRef{actionRef}pagination{{ //分页设置defaultPageSize: 10,showQuickJumper: true,sh…