大型网站系统与JAVA中间件实践——chapter1-4之各种类型的IO比较

前端线程,连接,IO线程,业务线程

1.BIO

请求方线程——一个socket连接——提供方线程,请求线程:连接数:提供方线程=1:1:1。

2.NIO

BIO每个请求占一个连接——一条路的独木桥(可以把连接看做路)。
NIO的连接可以复用——多排路的高速公路。连接可以复用。
这里可以用半双工全双工来打比方,也可以用电话和对讲机来打比方,BIO就类似于对讲机,要么听,要么讲,NIO类似于电话,可以同时讲和听
为什么连接可以复用?
BIO的一个连接在提供方没准备好数据的时候,是卡住的。但是对NIO来说,这个连接在提供方没准备好数据的时候,还可以继续给请求方发起新的请求使用。
IO线程
NIO需要引入专门的IO线程来处理通信功能(socket相关操作)。IO线程专门和socket打交道,进行数据的收发。
这样IO线程(池)管理socket连接,由IO线程来复用socket。

3.NIO请求方

请求方同步
请求线程发送请求之后,交由IO线程来处理,请求线程进入阻塞状态。在超时之前,远程调用返回执行结果( IO线程返回),阻塞解除,进行后续处理。如果超时了也解除阻塞,返回对应错误码。这里可以用guava的cache维护一个带超时时间的context,同时配合CountDownLatch来实现。
连接(socket)的复用是由IO线程来管理的。
请求方callback
和请求方同步类似,只是主线程不阻塞,继续向下执行。在超时时间之内等响应回来( IO线程返回),进行回调。这里如果回调方法内逻辑很重,可以用单独的线程池来管理回调部分的逻辑,防止业务逻辑影响IO线程。
Future方式
主线程阻塞。和callback类似,在超时时间内等响应回来( IO线程返回),把值传给Future,主线程Future.get阻塞获取结果,可以使用带超时时间的get方法。还可以使用guava的ListenableFuture,IO线程执行其set方法,触发它的listener中的操作。也可以使用FutureTask。

4.线程拆分

IO线程与业务线程拆分
这里的IO线程是专门负责和socket通信打交道的,所以尽量不要用它做过重的业务逻辑,比如dubbo的线程和callback线程,异步http的回调线程。使用自己的管理的线程池首先会更加灵活,同时也会一定程度上提高系统的吞吐量。
业务线程之间的拆分
同时,响应慢的业务过程和响应快的业务过程也要区分开,防止线程池中的线程完全被响应慢的业务方法占满,导致响应快的业务方法无法获取线程。

水平和垂直的概念

水平扩容,垂直扩容。
水平拆分,垂直拆分。
水平指的是同一个东西散开。
垂直指的是不同的东西汇聚。


猜你喜欢

转载自blog.csdn.net/xxcupid/article/details/53096502