java mina多线程_mina2中的线程池

Mina框架在处理网络IO时采用线程池模型,包括Acceptor/Connector线程、Processor线程和过滤器中的ExecutorFilter线程池。Acceptor和Connector线程分别在服务器端和客户端各有一个,负责监听和连接。Processor线程负责具体IO操作和业务逻辑,数量默认为CPU数量+1。线程池主要在ExecutorFilter中引入,用于避免阻塞Processor线程,保证服务器处理能力。默认的OrderedThreadPoolExecutor保证了请求处理顺序,但也可通过配置实现无序并行处理以提高吞吐量。Mina线程池的使用包括IoAcceptor、IoConnector、IoProcessor和ExecutorFilter的线程池,其中IoProcessor线程池大小默认为CPU核数+1,可以通过配置调整。
摘要由CSDN通过智能技术生成

一、Mina中的线程池模型

前面介绍了Mina总体的层次结构,那么在Mina里面是怎么使用Java NIO和进行线程调度的呢?这是提高IO处理性能的关键所在。Mina的线程调度原理主要如下图所示:

99416ed6fd0e83d515152fb745c167aa.png

bab46c1f4bcc511d94b2b5ec1c1de06c.png

Acceptor与Connector线程

在服务器端,bind一个端口后,会创建一个Acceptor线程来负责监听工作。这个线程的工作只有一个,调用Java NIO接口在该端口上select connect事件,获取新建的连接后,封装成IoSession,交由后面的Processor线程处理。在客户端,也有一个类似的,叫Connector的线程与之相对应。这两类线程的数量只有1个,外界无法控制这两类线程的数量。

TCP实现的代码可以参考org.apache.mina.core.polling.AbstractPollingIoAcceptor的内部类Acceptor和org.apache.mina.core.polling.AbstractPollingIoConnector的内部类Connector。

Processor线程

Processor线程主要负责具体的IO读写操作和执行后面的IoFilterChain和IoHandler逻辑。Processor线程的数量N默认是CPU数量+1,可以通过配置参数来控制其数量。前面进来的IoSession会被分配到这N个Processor线程中。默认的SimpleIoProcessorPool的策略是session id绝对值对N取模来分配。

每个Porcessor线程中都维护着一个selector,对它维护的IoSession集合进行select,然后对select的结果进行遍历,逐一处理。像前面提到的,读取数据,以事件的形式通知后面IoFilterChain;以及对写请求队列的flush操作,都是在这类线程中来做的。

通过将session均分到多个Processor线程里进行处理,可以充分利用多核的处理能力,减轻select操作的压力。默认的Processor的线程数量设置可以满足大部分情况下的需求,但进一步的优化则需要根据实际环境进行测试。

线程模型

线程模型原理

从单一的Processor线程内部来看,IO请求的处理流程是单线程顺序处理的。前面也提到过,当Process线程select了一批就绪的IO请求后,会在线程内部逐一对这些IO请求进行处理。处理的流程包括IoFilter和IoHandler里的逻辑。当前面的IO请求处理完毕后,才会取下一个IO请求进行处理。也就是说,如果IoFilter或IoHandler中有比较耗时的操作的话(如:读取数据库等),Processor线程将会被阻塞住,后续的请求将得不到处理。这样的情况在高并发的服务器下显然是不能容忍的。于是,Mina通过在处理流程中引入线程池来解决这个问题。

那么线程池应该加在什么地方呢?正如前面所提到过的:IoFilterChain是Mina的扩展点。没错,Mina里是通过IoFilter的形式来为处理流程添加线程池的。Mina的线程模型主要有一下这几种形式:

4721f900227bdd0a01c3169c8c5cf21e.png

第一种模型是单线程模型,也是Mina默认线程模型。也就是Processor包办了从底层IO到上层的IoHandler逻辑的所有执行工作。这种模型比较适合于处理逻辑简单,能快速返回的情况。

第二种模型则是在IoFilterChain中加入了Thread Pool Filter。此时的处理流程变为Processor线程读取完数据后,执行IoFilterChain的逻辑。当执行到Thread Pool Filter的时候,该Filter会将后续的处理流程封装到一个Runnable对象中,并交由Filter自身的线程池来执行,而Processor线程则能立即返回来处理下一个IO请求。这样如果后面的IoFilter或IoHandler中有阻塞操作,只会引起Filter线程池里的线程阻塞,而不会阻塞住Processor线程,从而提高了服务器的处理能力。Mina提供了Thread Pool Filter的一个实现:ExecutorFilter。

当然,也没有限制说chain中只能添加一个ExecutorFilter,开发者也可以在chain中加入多个ExecutorFilter来构成第三种情况,但一般情况下可能没有这个必要。

请求的处理顺序

在处理流程中加入线程池,可以较好的提高服务器的吞吐量,但也带来了新的问题:请求的处理顺序问题。在单线程的模型下,可以保证IO请求是挨个顺序地处理的。加入线程池之后,同一个IoSession的多个IO请求可能被ExecutorFilter并行的处理,这对于一些对请求处理顺序有要求的程序来说是不希望看到的。比如:数据库服务器处理同一个会话里的prepare,execute,commit请求希望是能按顺序逐一执行的。

Mina里默认的实现是有保证同一个IoSession中IO请求的顺序的。具体的实现是,ExecutorFilter默认采用了Mina提供的OrderedThreadPoolExecutor作为内置线程池。后者并不会立即执行加入进来的Runnable对象,而是会先从Runnable对象里获取关联的IoSession(这里有个down cast成IoEvent的操作),并将Runnable对象加入到session的任务列表中。OrderedThreadPoolExecutor会按session里任务列表的顺序来处理请求,从而保证了请求的执行顺序。

对于没有顺序要请求的情况,可以为ExecutorFilter指定一个Executor来替换掉默认的OrderedThreadPoolExecutor,让同一个session的多个请求能被并行地处理,来进一步提高吞吐量。

read  in  data:

IO读入(IoProcessor)---日志记录、解码、threadPool(IoFilter)---业务逻辑处理(IoHandler)

write  out  data:

业务逻辑处理(IoHandler)---日志记录、编码、threadPool(IoFilter)---IO写出(IoProcessor)

由以上可以看出,IO读入和IO写出的过程是相反的。

二、mina框架中的线程池

Mina中的线程池使用主要有四个地方:

1、IoAcceptor线程池。(一个端口一个线程)不可配置

2、IoConnector线程池。(一个端口一个线程)不可配置</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值