门户网站建设好如何维护,品牌网站建设联系方式,网站的统计 怎么做,建筑网站设计模版RPCRPC, 远程过程调用#xff08;Remote Procedure Call#xff0c;RPC#xff09;是一个计算机通信协议#xff0c;该协议允许运行于一台计算机的程序程调用另一台计算机的上的程序。通俗讲#xff0c;RPC通过把网络通讯抽象为远程的过程调用#xff0c;调用远程的过程就…RPCRPC, 远程过程调用Remote Procedure CallRPC是一个计算机通信协议该协议允许运行于一台计算机的程序程调用另一台计算机的上的程序。通俗讲RPC通过把网络通讯抽象为远程的过程调用调用远程的过程就像调用本地的子程序一样方便从而屏蔽了通讯复杂性使开发人员可以无需关注网络编程的细节将更多的时间和精力放在业务逻辑本身的实现上提高工作效率。RPC本质上是一种 Inter-process communicationIPC——进程间通信的形式。常见的进程间通信方式如管道、共享内存是同一台物理机上的两个进程间的通信而RPC就是两个在不同物理机上的进程之间的通信。概括的说RPC就是在一台机器上调用另一台机器上的方法这种调用在远程机器上对代码的执行就像在本机上对代码的执行一样只是迁移了一个执行环境而已。RPC是一种C/S架构的服务模型server端提供接口供client调用client端向server端发送数据server端接收client端的数据进行相关计算并将结果返回给client端。执行一次RPC通常需要经历以下步骤摘自 Wikipedia1.The client calls the client stub. The call is a local procedure call, with parameters pushed on to the stack in the normal way.2.The client stub packs the parameters into a message and makes a system call to send the message. Packing the parameters is called marshalling.3.The clients local operating system sends the message from the client machine to the server machine.4.The local operating system on the server machine passes the incoming packets to the server stub.5.The server stub unpacks the parameters from the message. Unpacking the parameters is called unmarshalling.6.Finally, the server stub calls the server procedure. The reply traces the same steps in the reverse direction为了实现上述RPC步骤许多RPC工具被研发出来。这些RPC工具大多使用“接口描述语言” —— interface description language (IDL) 来提供跨平台跨语言的服务调用。现在生产中用的最多的IDL是Google开源的protobuf。在日常开发中通常有两种形式来使用RPC一种是团队内部完全实现上述RPC的6个步骤自己序列化数据然后自己利用socket或者http传输数据最常见的就是游戏开发了。另一种就是利用现成的RPC工具这些RPC工具实现了底层的数据通信开发人员只需要利用IDL定义实现自己的服务即可而不用关心数据是如何通信的最常见的RPC工具是Facebook开源的Thrift RPC框架。本文将重点讲解Thrift RPC。Thrift实际上是实现了C/S模式通过代码生成工具将接口定义文件生成服务器端和客户端代码可以为不同语言从而实现服务端和客户端跨语言的支持。用户在Thirft描述文件中声明自己的服务这些服务经过编译后会生成相应语言的代码文件然后用户实现服务客户端调用服务服务器端提服务便可以了。其中protocol协议层, 定义数据传输格式可以为二进制或者XML等和transport传输层定义数据传输方式可以为TCP/IP传输内存共享或者文件共享等被用作运行时库。Thrift的协议栈如下图所示在Client和Server的最顶层都是用户自定义的处理逻辑也就是说用户只需要编写用户逻辑就可以完成整套的RPC调用流程。用户逻辑的下一层是Thrift自动生成的代码这些代码主要用于结构化数据的解析,发送和接收同时服务器端的自动生成代码中还包含了RPC请求的转发Client的A调用转发到Server A函数进行处理。协议栈的其他模块都是Thrift的运行时模块底层IO模块负责实际的数据传输包括Socket文件或者压缩数据流等。TTransport负责以字节流方式发送和接收Message是底层IO模块在Thrift框架中的实现每一个底层IO模块都会有一个对应TTransport来负责Thrift的字节流(Byte Stream)数据在该IO模块上的传输。例如TSocket对应Socket传输TFileTransport对应文件传输。TProtocol主要负责结构化数据组装成Message或者从Message结构中读出结构化数据。TProtocol将一个有类型的数据转化为字节流以交给TTransport进行传输或者从TTransport中读取一定长度的字节数据转化为特定类型的数据。如int32会被TBinaryProtocol Encode为一个四字节的字节数据或者TBinaryProtocol从TTransport中取出四个字节的数据Decode为int32。TServer负责接收Client的请求并将请求转发到Processor进行处理。TServer主要任务就是高效的接受Client的请求特别是在高并发请求的情况下快速完成请求。Processor(或者TProcessor)负责对Client的请求做出相应包括RPC请求转发调用参数解析和用户逻辑调用返回值写回等处理步骤。Processor是服务器端从Thrift框架转入用户逻辑的关键流程。Processor同时也负责向Message结构中写入数据或者读出数据。Thrift的模块设计非常好在每一个层次都可以根据自己的需要选择合适的实现方式。同时也应该注意到Thrift目前的特性并不是在所有的程序语言中都支持。例如C实现中有TDenseProtocol没有TTupleProtocol而Java实现中有TTupleProtocol没有TDenseProtocol。利用Thrift用户只需要做三件事(1). 利用IDL定义数据结构及服务(2). 利用代码生成工具将(1)中的IDL编译成对应语言如C、JAVA编译后得到基本的框架代码(实现接口定义)(3). 在(2)中框架代码基础上完成完整代码纯C代码、JAVA代码等实现业务逻辑Linux下安装 Thrift的安装包括上面提到生成代码生成器和应用框架库网页http://thrift.apache.org/docs/install/描述了安装依赖项除了gcc及其编译工具本身外编译Thrift最大的依赖就是boost。安装过程并不复杂请参阅相关网上文章。Windows下Thrift的使用下载thrift服务的安装包thrift-0.14.1.exe-其它文档类资源-CSDN下载 下载下来是一个.exe的运行文件将下载下来的thrift-0.14.1.exe 文件重命名为thrift.exe配置thrift的环境变量即为了能够执行thrift指令测试window环境thrift是否安装完成Thrift基本概念与应用Thrift有以下几个概念类型系统typesystemThrift定义了一套数据传输描述语言有点类似IDL它是“语言中性”的这个就是它的类型系统。它分为五种类型数据类型表达3种预定义类/结构1种接口表达1种基本类型(basictype)也就是bool、byte、i16、i32、i64、double、string任何语言都有这些基本类型比较有意思的是string它即表达text也表达binary bytes。另一个特点是整型没有unsigned原因比较简单因为有些语言不支持。 结构类型(struct)就是C语言中的struct将基本类型组合起来。 容器类型(container)就是集合类型list/set/map其中的元素是任何Thrift可识别的基本、结构、容器类型。【不知道是否有不支持list/set/map的语言那么Thrift如何处理呢】 异常类型(exception)从数据结构讲就是结构类型可以认为是便于异常的处理而单独拿出来的、预定义的、有特殊意义的结构类型。 服务定义类型(service)这个类型实际是用来定义接口的Thrift代码生成器会根据这个定义生成代码框架。传输(transport)也就是信息的传输渠道以及读写方式例如介质可以是socket、shared memory或fileThrift规定了一些基本的操作open/close/isOpen/read/write/flush对server再加上listen/accept。特别的针对Socket方式有TScoket类对file方式有TFileTransport类上面类比较底层还有几个实用的类TBufferedTransportTFramedTransportTMemoryBuffer等。协议protocol是对传输协议的封装也就是传输采用二进制、XML或者text来表示信息它的功能有两个1.双向的消息队列2.信息的编码和解码也就是对上面类型的读/写。关于流式格式thrift数据类型是自我分割的意思是说thrift会自己在数据域的分割处插入标志在解码的时候即使没有数据域定义thrift也能成功分割出各数据域。在若干篇文章中都提到thrift的二进制流式编码有相当的效率可以配合压缩因此首选的协议应该是binary协议。版本versioning如果一个程序分开来开发那版本问题就是绕不过去的问题。Thrift的版本是通过“field identifiers”来实现的每个结构由其标识结构中的每个域有其标识这两个标识唯一决定了一个数据域。在解码的时候数据域的标识被检查如果不能识别则该数据域被抛弃。Thrift也可以通过”Isset”机制来明确某些域的设置与否发送端用来指明是否设置接收端用来检测是否设置。四种情况 添加了数据域, 旧客户端,新服务器端客户端发送的数据中没有该域服务器端能检测出来可按缺省值处理。 删除了数据域, 旧客户端,新服务器端客户端发送的数据中有该域服务器端忽略该域。 添加了数据域, 新客户端,旧服务器端客户端发送的数据中有该域服务器端忽略该域。 删除了数据域, 新客户端,旧服务器端客户端发送的数据中没有该域服务器端可能不知道如何处理这种情况。 处理器processor就是如何将各部分协调起来形成代码或用户代码的框架。它有两个重要的类TProcessor和TServer。TProcessor用来实现RPC调用TServer是所有Server类的基类TServer类主要处理连接和线程而不管诸如传输、编码等。用户代码主要关注的一是.thrift文件二就是这个接口。Thrift为此实现了TSimpleServer(单线程), TThreadedServer每连接一个线程和 TThreadPoolServer线程池等类。下图是thrift生成代码的基本结构(C)。图中ServiceIf是根据接口文件.thrift生成的虚接口类用户的具体实现在ServiceHandler中。各种调用方式在TServer中实现。【详细的描述见实例】2.Thrift实现上的几个考虑目标语言虽然有多种选择但最常用的可能也是支持最好的是C, Java, and Python。生成的结构体数据域成员都是公有的没有set,get之类的东西虽然建议采用isset但也可以不用系统足够强健来处理类似“FieldNotSetException”之类的问题因而也没有涉及该异常。Read和write方面也是公有的这样用户可以在固有的RPC之外来使用它们。RPC方法标识实现RPC时建立函数名与函数指针之间的映射大致如下不同的语言表达方式不同Cmap:std::mapstd::string,函数指针 processMap_;这样加快函数调用。多线程对C实现在开发过程中thrift开发人员研究过boostACE中与thread,timer相关的东西开发人员不想引入过多的第三方依赖因此thrift中只有对boost::shared_ptr的引用是必须的但为了跨平台或获得更多的功能一般情况下boost中threadtimer及其依赖库也是需要的。ThreadManager和TimerManager线程管理类用来管理线程池定时器管理类可以定时触发Runnable的对象开启一件事情可以放到或不放到一个单独线程。NonblockingOperation这个东西需要libevent的支持。Compiler代码生成器这个东西是用C写的依赖于lex/yacc。代码生成分两步第一检查包含的文件和类型定义文件生成“解析树”the parse tree第二将各类型放到解析树中根据解析树生成代码。TFileTransport这个类及其继承类可以将request消息记入文件为提高性能它先缓存记录并存入磁盘。记录文件是分块的文件固定大小采用padding记录不能跨块。thrift示例1、thrift的协议namespace java com.wangyong.tripartite.wechatservice Hello {string helloString(1:string word)}经过thrift服务进行编译会得到相应语言的接口例如java的thrift --gen java helloService.thrift在当前目录下生成gen-java目录里面生成了HelloService.java文件。Thrift --gen py helloService.thrift 可以生成python相关代码。使用java实现server方式