关于PRC框架

作者:用心阁
链接:https://www.zhihu.com/question/25536695/answer/36197244
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

关于RPC
你的题目是RPC框架,首先了解什么叫RPC,为什么要RPC,RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

比如说,一个方法可能是这样定义的:
Employee getEmployeeByName(String fullName)
那么:
  • 首先,要解决通讯的问题,主要是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享同一个连接。
  • 第二,要解决寻址的问题,也就是说,A服务器上的应用怎么告诉底层的RPC框架,如何连接到B服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么,这样才能完成调用。比如基于Web服务协议栈的RPC,就要提供一个endpoint URI,或者是从UDDI服务上查找。如果是RMI调用的话,还需要一个RMI Registry来注册服务的地址。
  • 第三,当A服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,内存中的参数的值要序列化成二进制的形式,也就是序列化(Serialize)或编组(marshal),通过寻址和传输将序列化的二进制发送给B服务器。
  • 第四,B服务器收到请求后,需要对参数进行反序列化(序列化的逆操作),恢复为内存中的表达方式,然后找到对应的方法(寻址的一部分)进行本地调用,然后得到返回值。
  • 第五,返回值还要发送回服务器A上的应用,也要经过序列化的方式发送,服务器A接到后,再反序列化,恢复为内存中的表达方式,交给A服务器上的应用

(图片来源: cs.rutgers.edu/~pxk/417

为什么RPC呢?就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如比如不同的系统间的通讯,甚至不同的组织间的通讯。由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用,

RPC的协议有很多,比如最早的CORBA,Java RMI,Web Service的RPC风格,Hessian,Thrift,甚至Rest API。

关于Netty
而Netty框架不局限于RPC,更多的是作为一种网络协议的实现框架,比如HTTP,由于RPC需要高效的网络通信,就可能选择以Netty作为基础。除了网络通信,RPC还需要有比较高效的序列化框架,以及一种寻址方式。如果是带会话(状态)的RPC调用,还需要有会话和状态保持的功能。

大体上来说,Netty就是提供一种事件驱动的,责任链式(也可以说是流水线)的网络协议实现方式。网络协议包含很多层次,很多部分组成,如传输层协议,编码解码,压缩解压,身份认证,加密解密,请求的处理逻辑,怎么能够更好的复用,扩展,业界通用的方法就是责任链,

一个请求应答网络交互通常包含两条链,一条链(Upstream)是从传输层,经过一系列步骤,如身份认证,解密,日志,流控,最后到达业务层,一条链(DownStream)是业务层返回后,又经过一系列步骤,如加密等,又回到传输层。
(图片来源: (图片来源: ChannelPipeline (The Netty Project API Reference (3.2.6.Final))

这样每一层都有一个处理接口,都可以进行不同的操作,比如身份认证,加解密,日志,流控,将不同的处理实现像拼积木那样插接起来就可以实现一个网络协议了(快速开发)。每一层都有自己的实现,上层不需要关注面向网络的操作(可维护)。Netty已经提供了很多实现。

(图片来源: (图片来源: docs.jboss.org/netty/3.
当然Netty还有许多好处,比如对非阻塞IO(NIO)的支持,比如在链上传递时最大程度的减少buffer的copy(高性能)。
TSMaster PRC(这里假设是某种协议或机制的缩写)的具体定义和内容我无法得知,因为没有足够的背景信息。但是,我可以向你说明如何在Python中实现一个通用的远程过程调用(RPC)机制。 在Python中实现RPC机制通常涉及以下几个步骤: 1. **定义服务接口**:首先需要定义一组服务接口,这些接口规定了客户端可以调用哪些远程方法以及它们的参数和返回值。 2. **选择或创建通信协议**:确定远程过程调用之间的通信协议,例如HTTP REST、XML-RPC、JSON-RPC或者其他自定义协议。 3. **实现服务端(服务器)**:服务端需要实现上述定义的接口,同时还需要处理网络通信和请求的分发。Python中常用的网络库如`socket`、`http.server`、`flask`、`tornado`等可以用来实现服务端。 4. **实现客户端(调用者)**:客户端需要知道如何与服务端通信,包括网络地址、端口和协议格式。客户端使用这些信息调用远程方法,就像调用本地方法一样。 5. **数据序列化与反序列化**:在客户端和服务端之间传输的数据需要被序列化(编码)和反序列化(解码)。Python中常用的数据序列化格式有JSON、pickle、XML等。 6. **异常处理和错误管理**:在远程调用过程中,需要处理可能出现的网络异常和远程方法调用的错误。 以下是一个非常简单的基于HTTP协议的RPC示例: 服务端代码示例(使用Flask框架): ```python from flask import Flask, jsonify, request app = Flask(__name__) @app.route('/add', methods=['POST']) def add(): data = request.get_json() a = data['a'] b = data['b'] return jsonify({'result': a + b}) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000) ``` 客户端代码示例: ```python import requests def add(a, b): response = requests.post('http://localhost:5000/add', json={'a': a, 'b': b}) return response.json()['result'] print(add(2, 3)) ``` 请注意,以上代码仅为示例,实际的TSMaster PRC机制可能有特定的实现细节和要求,需要根据具体的协议文档来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值