05.apache thrift-深入
一、Thrift架构
此架构不但是thrift架构,也代表着大部分RPC框架的架构
- your code:对应上节例子中man方法中的代码
- FooService.Client与FooService.Processor对应上节例子中的 PersonService.Client client与PersonService.Processor<PersonServiceImpl> processor
- Write与Read是由thrift自动生成的代码
- Tprotocol:(应用层协议)传输的数据格式,编解码协议,决定数据如何进行压缩(解码与编码),比如:JSON、二进制
- TTransport:(传输层协议)传输的数据协议,决定底层以什么形式将数据由一端传给另一端
其中第一个T代表Thrift。
二、Thrift传输数据格式(Tprotocol)
协议 | 说明 | 备注 | 使用频率 |
TBinaryProtocol |
二进制格式 | 高 | |
TCompactProtocol | 压缩格式 |
TCompactProtocol比TBinaryProtocol压缩率还要高 |
相当高 |
TJSONProtocol | JSON格式 | 一般 | |
TSimpleJSONProtocol | 简单JSON格式 |
TSimpleJSONProtocol是TJSONProtocol的扩展,极少使用(数据中缺少元数据信息, 只能写出去,不能读回来) |
极少 |
TDebugProtocol | debug使用的格式 |
TDebugProtocol用于对thrift不了解+查看消息具体内容时进行debug时使用 |
一般 |
三、Thrift数据传输方式(TTransport)
传输 | 说明 | 使用频率 |
TSocket | 阻塞式socket(相当于BIO) | 低 |
TFramedTransport | 以frame为单位进行传输(将传输内容切分成若干frame,类似于websocket中的frame),非阻塞式服务(TNonblockingServer、THsHaServer)中使用 | 高 |
TFileTransport | 以文件形式进行传输 | 一般 |
TMemoryTransport | 将内存用于I/O,java实现时内部实际使用了简单的ByteArrayOutputStream | 一般 |
TZlibTransport | 使用zlib进行压缩,与其他传输方式联合时殷弘。当前无java实现 | 低 |
四、Thrift服务模型(线程模型)(TServer)
线程模型 | 说明 | 特点 |
TSimpleServer | 简单的单线程服务模型,常用于测试 | TSimpleServer接收一个连接,处理这个连接上的请求直到client关闭该连接,才去重新接受一个新连接。因为所有事情都在一个线程且是阻塞I/O, 它仅能同时服务一个连接,其他client不得不等待直到被接收。TSimpleServer主要用于测试目的,不要在生产环境中使用。 |
TNonblockingServer | 多线程服务模型,使用非阻塞I/O,需要使用TFramedTransport数据传输的方式 | TNonblockingServer 是一个单线程 NIO 的 Server,NIO 通过 Selector 循环监听所有 Socket,每次 selector 结束时,处理所有就绪状态的 Socket。 它使用 java.nio.channels.Selector, 通过调用select()允许你阻塞在多个连接上而不是一个连接。当一个或多个连接可接受/读/写时 select() 返回。TNonblockingServer 处理这些连接要么接受连接,要么从此读数据或写数据到连接,并再次调用select()等待下个可用的连接。按照这种方式,可以服务多个client而不会一个client饿死其他client |
THsHaServer (HsHa半同步/半异步) |
THsHa引入了线程池去处理,其模型把读写任务放到线程池去处理;Half-sync/Half-async的处理模式,把处理分成了两部分:Half-aysnc是在处理IO事件上(accept/read/write io),Half-sync用于handler对rpc的同步处理,需要使用TFramedTransport数据传输的方式 | THsHaServer 是 TNonBlockingServer 的子类,在 TNonBlockingServer 模式中,采用一个线程来完成对所有的 Socket 监听和业务处理,造成了效率低下,而 THsHaServer 模式使用了一个线程池来专门进行业务处理 |
TThreadedSelectorServer | Thrift 0.8引入另一种server,TThreadedSelectorServer。TThreadedSelectorServer和THsHaServer最大的不同是允许你有为网络I/O分配多个线程。它保持两个线程池,一个为了处理网络I/O, 一个处理请求。TThreadedSelectorServer在网络io是瓶颈时表现比THsHaServer好 |
|
TThreadPoolServer | 多线程服务模型(使用的线程池),使用标准的阻塞式IO,此线程模型为one client one thread的服务模型 |
有一个专用线程接受连接,一旦一个连接被接受了,被安排给ThreadPoolExecutor中一个工作线程来处理,这个工作线程服务该指定client连接直到关闭。一旦该连接关闭,该工作线程回到线程池,你可以配置线程池的最小和最大线程数。对应的默认值事5和Integer.MAX_VALUE 这意味着如果有10000个并发client连接,你需要运行10000个线程。就本身而论,这不如其他servers对资源友好。并且,如果client的数量超过线程池的最大数值,请求将被阻塞住直到有工作线程可用。 话虽如此,TThreadPoolServer表现的非常好;我用它支撑10000个并发连接没有任何问题。如果你能提前知道你的client数目并且也不介意多一点线程,TThreadPoolServer对你可能是个好选择。 |
各种线程模型特点总结:(参考如下网址)
https://www.iteye.com/blog/liyonghui160com-2088945
https://www.jianshu.com/p/047f9a5385df
最佳实践:实际工作中,经常使用的组合方式是:TCompactProtocol + TFramedTransport + THsHaServer(thrift-0.10.0)
补充:THsHaServer的执行流程(网上找的图)
thrift文章待看: