由浅入深了解Thrift(三)

五、  Thrift服务器端几种工作模式分析与总结

Thrift为服务器端提供了多种工作模式,本文中将涉及以下5中工作模式:TSimpleServer、TNonblockingServer、THsHaServer、TThreadPoolServer、TThreadedSelectorServer,这5中工作模式的详细工作原理如下:

1.      TSimpleServer模式

TSimpleServer的工作模式只有一个工作线程,循环监听新请求的到来并完成对请求的处理,它只是在简单的演示时候使用,它的工作方式如图5.1所示:

图5.1 TSimpleServer的工作模式

TSimpleServer的工作模式采用最简单的阻塞IO,实现方法简洁明了,便于理解,但是一次只能接收和处理一个socket连接,效率比较低,主要用于演示Thrift的工作过程,在实际开发过程中很少用到它。

2.      TNonblockingServer模式

TNonblockingServer工作模式,该模式也是单线程工作,但是该模式采用NIO的方式,所有的socket都被注册到selector中,在一个线程中通过seletor循环监控所有的socket,每次selector结束时,处理所有的处于就绪状态的socket,对于有数据到来的socket进行数据读取操作,对于有数据发送的socket则进行数据发送,对于监听socket则产生一个新业务socket并将其注册到selector中,如下图5.2所示:

图5.2、TNonblockingServer工作模式

上图5.2中读取数据之后的业务处理就是根据读取到的调用请求,调用具体函数完成处理,只有完成函数处理才能进行后续的操作;

TNonblockingServer模式优点:

相比于TSimpleServer效率提升主要体现在IO多路复用上,TNonblockingServer采用非阻塞IO,同时监控多个socket的状态变化;

TNonblockingServer模式缺点:

TNonblockingServer模式在业务处理上还是采用单线程顺序来完成,在业务处理比较复杂、耗时的时候,例如某些接口函数需要读取数据库执行时间较长,此时该模式效率也不高,因为多个调用请求任务依然是顺序一个接一个执行。

3.      THsHaServer模式(半同步半异步)

THsHaServer类是TNonblockingServer类的子类,在5.2节中的TNonblockingServer模式中,采用一个线程来完成对所有socket的监听和业务处理,造成了效率的低下,THsHaServer模式的引入则是部分解决了这些问题。THsHaServer模式中,引入一个线程池来专门进行业务处理,如下图5.3所示;

图5.3 THsHaServer模式

THsHaServer的优点:

与TNonblockingServer模式相比,THsHaServer在完成数据读取之后,将业务处理过程交由一个线程池来完成,主线程直接返回进行下一次循环操作,效率大大提升;

THsHaServer的缺点:

由图5.3可以看出,主线程需要完成对所有socket的监听以及数据读写的工作,当并发请求数较大时,且发送数据量较多时,监听socket上新连接请求不能被及时接受。

4.      TThreadPoolServer模式

TThreadPoolServer模式采用阻塞socket方式工作,,主线程负责阻塞式监听“监听socket”中是否有新socket到来,业务处理交由一个线程池来处理,如下图5.4所示:

图5.4 线程池模式工作过程

TThreadPoolServer模式优点:

线程池模式中,数据读取和业务处理都交由线程池完成,主线程只负责监听新连接,因此在并发量较大时新连接也能够被及时接受。线程池模式比较适合服务器端能预知最多有多少个客户端并发的情况,这时每个请求都能被业务线程池及时处理,性能也非常高。

TThreadPoolServer模式缺点:

线程池模式的处理能力受限于线程池的工作能力,当并发请求数大于线程池中的线程数时,新请求也只能排队等待。

5.      TThreadedSelectorServer

TThreadedSelectorServer模式是目前Thrift提供的最高级的模式,它内部有如果几个部分构成:

(1)  一个AcceptThread线程对象,专门用于处理监听socket上的新连接;

(2)  若干个SelectorThread对象专门用于处理业务socket的网络I/O操作,所有网络数据的读写均是有这些线程来完成;

(3)  一个负载均衡器SelectorThreadLoadBalancer对象,主要用于AcceptThread线程接收到一个新socket连接请求时,决定将这个新连接请求分配给哪个SelectorThread线程。

(4)  一个ExecutorService类型的工作线程池,在SelectorThread线程中,监听到有业务socket中有调用请求过来,则将请求读取之后,交个ExecutorService线程池中的线程完成此次调用的具体执行;

图5.5 TThreadedSelectorServer模式的工作过程

如上图5.5所示,TThreadedSelectorServer模式中有一个专门的线程AcceptThread用于处理新连接请求,因此能够及时响应大量并发连接请求;另外它将网络I/O操作分散到多个SelectorThread线程中来完成,因此能够快速对网络I/O进行读写操作,能够很好地应对网络I/O较多的情况;TThreadedSelectorServer对于大部分应用场景性能都不会差,因此,如果实在不知道选择哪种工作模式,使用TThreadedSelectorServer就可以。

时间: 2024-10-13 21:57:00

由浅入深了解Thrift(三)的相关文章

由浅入深了解Thrift之服务化

一.问题描述 在上一篇<由浅入深了解Thrift之服务模型和序列化机制>文章中,我们已经了解了thrift的基本架构和网络服务模型的优缺点.如今的互联网圈中,RPC服务化的思想如火如荼.我们又该如何将thrift服务化应用到我们的项目中哪?实现thrift服务化前,我们先想想这几个问题:服务注册.服务发现.服务健康检测.服务“Load Balance”.隐藏client和server端的交互细节.服务调用端的对象池化. 服务的注册.发现和健康检测,我们使用zookeeper可以很好的解决 服务

由浅入深了解Thrift(二)

三.  Thrift的工作原理 1.普通的本地函数调用过程 例如,有如下关于本地函数的调用的java代码,在函数caller中调用函数getStr获取两个字符串的拼接结果: 代码3.1        本地函数调用调用方和被调用方都在一个程序内部,只是cpu在执行调用的时候切换去执行被调用的函数,执行完被调用函数之后,再切换回来执行调用之后的代码,其调用过程如下图3.1所示: 图3.1        站在调用方的角度,在本地函数调用过程中,执行被调用函数期间,调用方会被卡在那里一直等到被调用函数执

由浅入深了解Thrift之结果封装

一.thrift返回结果封装 Thrift文件添加版本号,方便对thrift的版本进行控制 服务与返回的数据类型分开定义 在项目中使用Thrift提供RPC服务时,很多情况下我们都会将返回的结果进行封装和定义需要自己数据结构.为增加thrift文件的易读性,我们将数据结构和服务分开定义到不通的文件中 .通过这种方式,为调用方提供友好的使用体验. thrift_datatype.thrift中定义数据类型: namespace java com.wy.service.thriftdatatype

由浅入深了解Thrift(一)

一.  Thrift简单介绍 1.1.  Thrift是什么?能做什么? Thrift是Facebook于2007年开发的跨语言的rpc服框架,提供多语言的编译功能,并提供多种服务器工作模式:用户通过Thrift的IDL(接口定义语言)来描述接口函数及数据类型,然后通过Thrift的编译环境生成各种语言类型的接口文件,用户可以根据自己的需要采用不同的语言开发客户端代码和服务器端代码. 例如,我想开发一个快速计算的RPC服务,它主要通过接口函数getInt对外提供服务,这个RPC服务的getInt

Vue.js 2.0 由浅入深,第三天 day03

## 一. 组件component ### 1. 什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码 组件是自定义元素(对象) ### 2. 定义组件的方式 方式1:先创建组件构造器,然后由组件构造器创建组件 方式2:直接创建组件 ### 3. 组件的分类 分类:全局组件.局部组件 ### 4. 引用模板 将组件内容放到模板<template>中并引用 ### 5. 动态组件 <component :is="

由浅入深了解EventBus:(三)

原理 EventBus的核心工作机制如下图 在EventBus3.0架构图: EventBus类 在EventBus3.0框架的内部,核心类就是EventBus,订阅者的注册/订阅,解除注册,以及事件的分发全部在这个核心类中实现; 对于EventBus对象的创建,在框架内部是通过单例模式进行创建;我们平时在代码中通过EventBus类中的静态方法getDefault 获取实例对象: public static EventBus getDefault() { if (defaultInstance

python thrift 服务端与客户端使用

一.简介 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的.高效的服务. 二.安装 1.下载地址 http://www.apache.org/dyn/closer.cgi?path=/thrift

RPC-Thrift(一)

一个简单例子 IDL文件如下,详细的IDL语法参考官方文档http://thrift.apache.org/docs/idl. 通过代码生成工具得到两个文件:HelloService.java和ResultCommon.java. namespace java com.mytest.thrift struct ResultCommon{ 1:i32 resultCode, 2:string desc } service HelloService{ ResultCommon sayHello(1:

2017 框架、框架、类库、类库,web前端应该学什么 ?

在当今的快节奏生态中,有人倾向于花时间尝试最新框架,最新的类库,新奇有趣的插件.. 但我们的确应该把脚步放慢一些,并认真了解那些不会有很大变化的事情(理论本质).这样不仅会提升我们的工作质量和我们所创造的价值 -- 还将切实地帮助我们更快理解这些新的工具. ### 如何写出可读性高的代码 我们多数的工作并不是编写新代码,而是维护已有代码.这意味着你最终阅读代码的时间要比编写它所花费的时间要长,所以你需要为之后需要阅读你代码的程序员优化代码,而不是为了解释器. 这里我建议你按以下顺序 - 由浅入深