简介:使用最通俗概念讲解 同步异步、堵塞和非堵塞
洗衣机洗衣服
洗衣机洗衣服(无论阻塞式IO还是非阻塞式IO,都是同步IO模型)
同步阻塞:你把衣服丢到洗衣机洗,然后看着洗衣机洗完,洗好后再去晾衣服(你就干等,啥都不做,阻塞在那边)
同步非阻塞:你把衣服丢到洗衣机洗,然后会客厅做其他事情,定时去阳台看洗衣机是不是洗完了,洗好后再去晾衣服
(等待期间你可以做其他事情,玩游戏,看视频等等)。但即便如此,依然要时不时地去看一下洗衣机是不是把衣服洗完了,然后才能去晾衣服。
异步阻塞: 你把衣服丢到洗衣机洗,然后看着洗衣机洗完,洗好后再去晾衣服(几乎没这个情况,几乎没这个说法,可以忽略,异步不可能阻塞)
异步非阻塞:你把衣服丢到洗衣机洗,然后会客厅做其他事情,洗衣机洗好后会自动去晾衣服,晾完成后放个音乐告诉你洗好衣服并晾好了,这里你不需要晾衣服。
同步有先后顺序,无论是否阻塞。异步没有先后顺序,各自完成各自的事情。
在讲解Netty之前,需要先说明一下什么是Reactor设计模式
设计模式——Reactor模式(反应器设计模式),是一种基于事件驱动的设计模式,在事件驱动的应用中,将 一个或多个客户的服务请求分离(demultiplex)和调度(dispatch)给应用程序。在事件驱动的应用中,同步 地、有序地处理同时接收的多个服务请求 一般出现在高并发系统中,比如Netty,Redis等
优点 1)响应快,不会因为单个同步而阻塞,虽然Reactor本身依然是同步的; 2)编程相对简单,最大程度 的避免复杂的多线程及同步问题,并且避免了多线程/进程的切换开销; 3)可扩展性,可以方便的通过增加 Reactor实例个数来充分利用CPU资源;
缺点 1)相比传统的简单模型,Reactor增加了一定的复杂性,因而有一定的门槛,并且不易于调试。 2) Reactor模式需要系统底层的的支持,比如Java中的Selector支持,操作系统的select系统调用支持
通俗理解:KTV例子 前台接待,服务人员带领去开机器 Reactor模式基于事件驱动,适合处理海量的I/O事件,属于同步非阻塞IO(NIO)
Reactor单线程模型(比较少用)
内容: 1)作为NIO服务端,接收客户端的TCP连接;作为NIO客户端,向服务端发起TCP连接; 2) 服务端读请求数据并响应;客户端写请求并读取响应
使用场景: 对应小业务则适合,编码简单;对于高负载、大并发的应用场景不适合,一个NIO线程处理 太多请求,则负载过高,并且可能响应变慢,导致大量请求超时,而且万一线程挂了,则不可用了 ,NIO的说明可以参考传统IO与NIO比较
Reactor多线程模型
内容:一个Acceptor线程;一组NIO线程,一般是实用自带的线程池,包含一个任务队列和多个可用的线程 去处理接入连接和处理IO
使用场景:满足大多数场景 ,但是当Acceptor需要做复杂操作的时候,比如认证等耗时操作的时候,在高并发情况下则也会有性能问题,大量的请求被堆积到Acceptor,而无法分发到Worker线程池。
Reactor主从线程模型
内容:
1) Acceptor不在是一个线程,而是一组NIO线程;IO线程也是一组NIO线程,这样就是两个线程池去处理接入连接和处理IO
使用场景:满足目前的大部分场景,也是Netty推荐使用的线程模型
BossGroup
WorkGroup