開發(fā)速度快,文檔全播急,性能高
Reactor模型
- 翻譯:反應器模式脓钾,分發(fā)者模式,通知者模式
原理:
1)通過一個或多個輸入同時請求服務處理器(基于事件驅(qū)動)桩警;
2)服務處理器接收到請求可训,同步分發(fā)到相應的處理線程;
3)使用IO復用監(jiān)聽事件,分發(fā)事件到線程(進程)握截,這點就是網(wǎng)絡高并發(fā)的關鍵飞崖。
組成
1)Reactor:一個單獨的線程
2)Handlers:事件處理器,可能是開啟單獨的線程谨胞,也可能開啟個進程處理事件
單Reactor單線程模型
1)簡單的nio群聊就是這種模式固歪。
2)缺點:不能支持高并發(fā)。不能發(fā)揮cpu性能胯努,有一個handler在讀寫時會阻塞整個系統(tǒng)牢裳。
單Reactor多線程模型
1)Handler加入了線程池,去處理耗時的業(yè)務邏輯叶沛。
2)需要注意的是:線程池處理完蒲讯,需要將結果返回給handler,再返回給客戶端灰署。
3)優(yōu)點:充分發(fā)揮多核cpu的優(yōu)勢判帮;
4)缺點:多線程數(shù)據(jù)共享和訪問比較復雜,Reactor處理所有事件的監(jiān)聽和響應溉箕,是單線程運行晦墙,高并發(fā)場景容易出現(xiàn)性能瓶頸
主從Reactor多線程模型
- 圖解
1)reactor主線程MainReactor對象通過select監(jiān)聽事件,收到事件后轉發(fā)給acceptor
2) acceptor處理連接事件后约巷,將連接分配給subReactor
3) subReactor將連接加入到連接隊列進行監(jiān)聽并創(chuàng)建handler進行各種事件處理
4)當有新事件發(fā)生數(shù)時偎痛,subReactor就會調(diào)用對應的handler處理
5)handler通過read讀取數(shù)據(jù)旱捧,分發(fā)給后面的worker線程處理
6)worker線程池分配獨立的線程進行業(yè)務處理独郎,并返回結果
7)handler收到返回結果后,通過send將結果返回客戶端
8)Reactor主線程可以對應多個Reactor子線程 - 優(yōu)點:父線程和子線程職責明確枚赡,父線程只負責接收連接氓癌,子線程負責業(yè)務處理。父子線程交互也簡單贫橙,父線程只需要把連接傳給子線程贪婉,子線程無需返回數(shù)據(jù)
- 缺點:編程復雜度高
-
實例:nginx主從Reactor多線程模型,memcached主從多線程卢肃,netty主從多線程模型
Netty模型
image.png
- Netty抽象出兩組線程池疲迂,BossGroup專門負責接收客戶端的連接,WorkerGroup專門負責網(wǎng)絡讀寫
- BossGroup和WorkerGroup類型都是NioEventLoopGroup
- NioEventLoopGroup相當于一個事件循環(huán)組莫湘,這個組中含有多個事件循環(huán)尤蒿,每一個事件循環(huán)是NioEventLoop
- NioEventLoop表示一個不斷循環(huán)的執(zhí)行處理任務的線程,每個NioEventLoop都有一個selector幅垮,用于監(jiān)聽綁定在其上的socket的網(wǎng)絡通訊
- NioEventLoopGroup可以有多個線程腰池,即可以含有多個NioEventLoop
- 每個Boss NioEventLoop 循環(huán)執(zhí)行的步驟有3步
1)輪詢accept事件
2)處理accept事件,與client建立連接,生成NioSocketChannel示弓,并將其注冊到某個worker NIOEventLoop上的selector
3)處理任務隊列的任務讳侨,即runAllTasks - 每個worker NIOEventLoop循環(huán)執(zhí)行的步驟
1)輪詢read,write事件
2)處理IO事件奏属,即read,write跨跨,在對應NioSocketchannel處理
3)處理任務隊列中的任務,即runAllTasks - 每個Worker NIOEventLoop處理業(yè)務時拍皮,會使用pipeline(管道)歹叮,pipeline中包含了channel,即通過pipeline可以獲取到對應通道铆帽,管道中維護了很多的處理器
實戰(zhàn)
https://github.com/lanqqiao/net-demo.git
- 最簡單Netty服務
服務:NettyServer
服務handler:NettyServerHandler extends ChannelInboundHandlerAdapter
客戶端:NettyClient
客戶端handler:NettyClientHandler extends ChannelInboundHandlerAdapter
- hander任務異步實現(xiàn)
ctx.channel().eventLoop().execute(new Runnable() {});
ctx.channel().eventLoop().schedule(new Runnable() {}, 5, TimeUnit.SECONDS);
- ChannelFuture 監(jiān)聽機制
ChannelFuture cf = bootstrap.bind(6668).sync();
cf.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (cf.isSuccess()) {
System.out.println("監(jiān)聽端口6668成功");
}
}
});
- http服務
主要是使用netty已經(jīng)存在的handler咆耿,比如http編解碼器:HttpServerCodec
- ChannelInitializer初始化里面加內(nèi)置http處理器
pipeline.addLast(new HttpServerCodec());
- handler實現(xiàn)時繼承內(nèi)置channelInboundHandler
extends SimpleChannelInboundHandler<HttpObject>