RPC—thrift

yuanheci 2025年01月26日 46次浏览

1.RPC介绍

  RPC全称为Remote Procedure Call,意为远程过程调用。

  假设有两台服务器A,B.A服务器上部署着一个应用a,B服务器上部署着一个应用b,现在a希望能够调用b应用的某个函数(方法),但是二者不在同一个进程内,不能直接调用,就需要通过网络传输,在AB服务器之间建一条网络传输通道,a把参数传过去,b接收到参数调用自己的方法得到结果,再通过网络传回给a。

  简单讲就是A通过网络来调用B的过程,这个过程要涉及的东西很多,比如多线程、Socket、序列化反序列化、网络I/O,很复杂。于是大佬把这些封装起来做成一套框架供大家使用,就是RPC框架。

image-1737825976545

  thrift通过一个中间语言IDL(接口定义语言)来定义RPC的数据类型和接口,这些内容写在以.thrift结尾的文件中,然后通过特殊的编译器来生成不同语言的代码,以满足不同需要的开发者。比如java开发者,就可以生成java代码,c++开发者可以生成c++代码,生成的代码中不但包含目标语言的接口定义、方法、数据类型,还包含有RPC协议层和传输层的实现代码。

  HTTP和RPC最本质的区别,就是 RPC 主要是基于 TCP/IP 协议的,而 HTTP 服务主要是基于 HTTP 协议的。
我们都知道 HTTP 协议是在传输层协议 TCP 之上的,所以效率来看的话,RPC 当然是要更胜一筹啦!
HTTP和RPC的相同点是,底层通讯都是基于socket,都可以实现远程调用,都可以实现服务调用服务


用thrift实现匹配系统的原因:
  因为匹配会有延时,比如OJ评测,或者平时打车需要等待。如果这些放在server中,那么相当于连接阻塞,那么会消耗server服务器的性能,且网页卡顿。
  理想的实现方式:client将信息传到server,然后连接就可以断开了。server将信息再传到匹配系统,然后匹配系统进行匹配。当匹配成功后,再通知server,然后server通知client。
  因此匹配系统作为一个独立的模块,可以运行在独立的的服务器去做计算(且可以用不同语言实现,如用C++做复杂计算,速度更快)。

匹配系统与server之间的通信,使用thrift框架来实现(rpc)

system


2.thrift介绍

image-1737825852717

image-1737825865533

Thrift是一种c/s的架构体系。TServer主要任务是高效的接受客户端请求,并将请求转发给Processor处理。

  • 最上层是用户自行实现的业务逻辑代码;
  • Processor是由thrift编译器自动生成的代码,它封装了从输入数据流中读数据和向数据流中写数据的操作,它的主要工作是:从连接中读取数据,把处理交给用户实现impl,最后把结果写到连接上。
  • TProtocol是用于数据类型解析的,将结构化数据转化为字节流给TTransport进行传输。从TProtocol以下部分是thirft的传输协议和底层I/O通信。
  • TTransport是与底层数据传输密切相关的传输层,负责以字节流方式接收和发送消息体,不关注是什么数据类型。
  • 底层IO负责实际的数据传输,包括socket、文件和压缩数据流等。

3.thrift实战理解

  django项目中,匹配系统和web server在同一个服务器上,所以server通过thrift请求到匹配系统后,匹配系统直接调用了channel_layer进行了操作。正常情况应该是匹配系统返回值,然后再web server端操作channel_layer。

system-1737967436149
框架为:
client(javascript)

  • webapp客户端:与web服务端交互

django server(python3)

  • web 服务端
  • thrift客户端a:与匹配系统交互

匹配系统(python3)

  • thrift服务端a (match_server):与web server交互

  在linux thrift基础课中,是有一个数据存储结点,跑在另一个服务器B上。此时在匹配系统上额外单开一个thrift作为客户端,对应的thrift server跑在服务器B上。

image-1737967966880

此时框架为:
游戏应用端(Python3),直接通过thrift与匹配系统交互

  • thrift客户端a (match_client):与 匹配系统服务器 的服务端交互

匹配系统服务器(C++, match_system)

  • thrift服务端a (match_server):与 游戏应用端 的客户端交互
  • thrift客户端b (save_client):与 数据存储服务器 的服务端交互

数据存储服务器(已经实现,save_server)

  • thrift服务端b:与 匹配系统服务器 的客户端交互(save.thrift)