亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Netty(一)引題

2019-11-14 14:59:24
字體:
來源:轉載
供稿:網友

本文介紹java BIO(同步阻塞IO),偽異步IO,NIO(非阻塞IO),AIO(異步IO)這四種IO的情況,并對不同IO模型作比較。

目錄

1.BIO

2.偽異步IO

3.NIO

4.AIO

5.四種IO比較

6.BIO/偽異步IO/NIO/AIO源碼下載

 

1.BIO

采用BIO通信模型的服務器,通常由一個獨立的Acceptor線程負責監聽客戶端的連接,它接收到客戶端連接請求后為每個客戶端創建一個新的線程進程鏈路連接處理,處理完后,通過輸出流返回應答給客戶端,線程銷毀。

該模型最大的問題性能問題,當客戶端并發訪問增加后,服務端線程增加,當線程數膨脹后,系統的性能下降,隨著并發量增大,系統會發生線程堆棧溢出、創建新線程失敗等問題,最終導致線程宕機或者僵死,不能對外提供服務。而且開線程有很大的開銷,影響服務器性能。

源碼在src/main/java/NIOInduction/BIO下,分為客戶端和服務端,簡單的網絡、線程的處理。

 

2.偽異步IO

為了解決同步阻塞IO面臨的一個鏈接需要一個線程處理情況,現在引入了“池”的概念,加入了線程池。

當有新的客戶端連接的時候,將客戶端的Socket封裝為Task(java的Runnable接口實現了)投遞到后端線程池中進行處理。由于線程池可以設置消息隊列的大小和最大線程數,因此它的資源是可控的,無論多少個客戶端并發訪問,都不會導致資源的耗盡和宕機。

偽異步IO通訊框架采用了線程池的實現,因此避免了為每個請求都創建一個獨立的線程造成的線程資源耗盡問題。但是由于它的底層的通信依然采用的同步阻塞模型,因此無法從根本上解決問題。

java輸出流InputStream:當對socket的輸入流進行讀操作時,它會一直阻塞下去,直到發生以下三種事件。

  • 有數據可讀;
  • 可用數據已經讀取完畢;
  • 發生空指針或者IO異常。

這意味著當對方發數據請求或者應答消息緩慢(網絡傳輸慢)時,讀取寫入流一方的通訊線程將長時間阻塞,如果對方要100s才有消息發生完成,讀取的一方的IO線程也會將同步阻塞100s,在此時間里,其他接入消息只能在消息隊列中排隊。

java輸入流OutputStream:當調用OutputStream的write方法寫輸出流的時候,它將會唄阻塞,直到所有要發送的字節全部寫入完畢,或者發生異常。搞過TCP/ip的都曉得,當消息的接收方處理緩慢的時候,將不能及時從TCP緩沖區讀取數據,這將導致發送方的TCP window size不斷減小,直到為0,雙方處于keep-alive狀態,消息發送方就不能再將TCP緩沖區寫入數據,這時采用同步阻塞的IO,write操作將會無限期阻塞,直到tcp window size大于0或者發生IO異常。

源碼在src/main/java/NIOInduction/PseudoAsynchronousIO下,分為客戶端和服務端??蛻舳撕虰IO的客戶端一樣,服務端加入了線程池ExecutorService,相關構造函數請讀者自行查閱。

 

3.NIO

 NIO庫,是在JDK1.4中引入的,NIO彌補了同步阻塞IO的不足。在所有的數據,NIO都是用緩沖區處理掉的(Buffer),任何時候訪問NIO中的數據,都是通過緩沖區進行操作。緩沖區實際就是一個數組。Java NIO的基礎是多路復用器Selector,簡單來說,selector會不斷的輪詢注冊在其上的Channel(通道,全雙工的),如果某個Channel上有新的TCP連接接入、讀寫事件,這個Channel會處于就緒狀態,會被Selector輪詢出來,然后通過SelectionKey可以獲取就緒的select集合,進行后續的IO操作。

一個多路復用器可以同時輪詢多個Channel,而且由于jdk使用了epoll替代了select實現,所以沒有最大連接句柄的限制。(題外話,這里說的eopll、select是說的linux下的IO復用,和select、epoll一樣,清楚流程概念請直接看源碼)。

NIO服務端序列圖

1.打開ServerSocketChannel,用于監聽客戶端的連接,它是所有客戶端連接的父管道。

 ServerSocketChannel accptorSvr = ServerSocketChannel.open(); 

2.綁定監聽端口,設置連接為非阻塞模式。

acceptorSvr.socket().bind(  new InetSocketAddress(InetAddress.getByName("IP"),port));acceptorSvr.configureBlocking(false);

3.創建Reactor線程,創建多路復用器并啟動線程。

Selector selectot = Selector.open();new Thread(new RectorTask()).start();

4.將SelectSocketChannel注冊到Reactor線程的多路復用器selector上,監聽accept事件。

SelectionKey key = acceptorSvr.register(selector,SelectionKey.OP_ACCEPT,ioHandler);

5.多路復用器在線程run方法中無線循環里輪詢準備就緒的key。

int num = selector.select();Set selectkeys = selector.selectedKeys();Iterator it = selectkeys.iterator();while(it.hasNext){      SelectionKey key = (SelectionKey)it.next;      /*     deal with  IO event    */    }

 6.多路復用監聽到有新的用戶接入,處理新的接入請求,完成TCP三次握手,建立物理連接。

SocketChannel sc = ssc.accept();

7.設置客戶端鏈路為非阻塞模式

sc.configureBlocking(false);sc.socket().setReuseAddress(true);...

8.將新接入的客戶端連接注冊到Reactor線程的多路復用器上,監聽讀操作,用來讀取客戶端發送的網絡消息。

SelectionKey key = sc.register(selector,SelectionKey.OP_READ,ioHangler);

9.異步讀取客戶端請求消息到緩沖區

int readNumber = channel.read(receivedBuffer);

10.對bytebuffer進行編解碼,如果有半包消息指針reset,繼續讀取后續的報文,將解碼成功的消息封裝成task,投遞到業務線程池中,進行業務邏輯處理。

Object message = null;        while (buffer.hasRemain()){            byteBuffer.mark();            Object message = decode(byteBuffer);            if(message==null){                byteBuffer.reset();                break;            }            messageList.add(message);        }        if(!byteBuffer.hasRemain()){            byteBuffer.clear();        }        else byteBuffer.compact();        if(messageList!=null & !messageList.isEmpty()) {            for(Object messageF:messageList)                handleTask(messageE);        }

11.將pojo對象encode成bytebuffer,調用SocketChannel的異步write接口,將消息異步發送到客戶端。

socketChannel.wite(buffer);

注意:如果發送區TCP緩沖區滿了,會導致寫半包,此時,需要注冊寫操作位,循環寫,直到整個包消息寫入TCP緩沖區。

 

NIO客戶端序列圖(大多數和服務端類似)

1.打開SocketChannel,綁定客戶端本地地址(可選,默認系統會隨機分配一個可用的本地地址)

 SocketChannel clientChannel = SocketChannel.open(); 

2.設置SocketChannel為非阻塞模式,同時設置連接的TCP參數。

SocketChannel.configureBlocking(false);
socket.setReuseAddress(true);
socket.setReceiveBufferSize(BUFFER_SIZE);
socket.setSendBufferSize(BUFFER_SIZE);

3.異步連接服務器。

boolean connected = clientChannel.connect(new InetSocketAdress("ip",port));

4.判斷是否連接成功,如果成功,則直接注冊讀狀態位到多路復用器中,如果沒成功(異步連接,返回false,說明客戶端已經已經發送sync包,服務端沒有返回ack包,物理連接還沒建立——關于ack、sync包,請讀者自行查閱TCP/IP中的TCP的三次握手,四次分手的過程)

if(connect)
  clientChannel.register(selector,SelectionKey.OP_READ,ioHandler);
else
  clientChannel.register(selector,SelectionKey.OP_CONNECT,ioHandler);

5.向Reactor線程的多路復用器注冊OP_CONNECT狀態位,監聽服務器的TCP ACK應答。

clientChannel.register(selector,SelectionKey.OP_CONNECT,ioHandler);

 6.創建Reactor線程,創建多路復用器并啟動線程。

Selector selectot = Selector.open();new Thread(new RectorTask()).start();

7.多路復用器在線程run方法中無線循環里輪詢準備就緒的key。

int num = selector.select();Set selectkeys = selector.selectedKeys();Iterator it = selectkeys.iterator();while(it.hasNext){      SelectionKey key = (SelectionKey)it.next;      /*     deal with  IO event    */    }

8.接收connect事件進行處理

if(key.isConnectable())
  //handlerConnect();

9.判斷連接結果,如果連接成功,注冊讀事件到多路復用器

if(channel.finishConnect())
  registerRead();

10.注冊讀事件到多路復用器

clientChannel.register(selector,SelectionKey.OP_READ,ioHandler);

11.異步讀取客戶端請求消息到緩沖區

int readNumber = channel.read(receivedBuffer);

12.對bytebuffer進行編解碼,如果有半包消息指針reset,繼續讀取后續的報文,將解碼成功的消息封裝成task,投遞到業務線程池中,進行業務邏輯處理。

Object message = null;        while (buffer.hasRemain()){            byteBuffer.mark();            Object message = decode(byteBuffer);            if(message==null){                byteBuffer.reset();                break;            }            messageList.add(message);        }        if(!byteBuffer.hasRemain()){            byteBuffer.clear();        }        else byteBuffer.compact();        if(messageList!=null & !messageList.isEmpty()) {            for(Object messageF:messageList)                handleTask(messageE);        }

13.將pojo對象encode成bytebuffer,調用SocketChannel的異步write接口,將消息異步發送到客戶端。

socketChannel.wite(buffer);

 

注:以上的客戶端和服務端過程,了解就行,上層的代碼不一定這樣寫的,具體參考能運行的代碼。

源碼在src/main/java/NIOInduction/NIO下,分為客戶端和服務端。

4.AIO

 NIO2.0中引入了新的異步通道的概念,并提供了異步文件通道h額異步套接字通道的實現。

異步通道提供2種方式獲取操作結果:

  • 通過java.util.concurrent.Futurn類來表示異步操作的結果;
  • 在執行異步操作的時候傳入一個java.nio.channels.

CompletionHandler接口的實現類作為操作完成的回溯。

NIO2.0的異步套接字通道,對應UNIX網絡編程中的事件驅動IO(AIO),它不需要通過多路復用器(Selector)對注冊的通道進行輪詢操作。

源碼在src/main/java/NIOInduction/AIO下,分為客戶端和服務端。

 

5.四種IO比較

6.BIO/偽異步IO/NIO/AIO源碼下載

GitHub地址:https://github.com/orange1438/Netty_Course

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲自拍高清视频网站| 黑人巨大精品欧美一区免费视频| 国产在线不卡精品| 久久久久久久久久久久久久久久久久av| 成人情趣片在线观看免费| 欧美综合国产精品久久丁香| 欧美日韩亚洲视频一区| 国产精品久久久久久久天堂| 国产美女精品免费电影| 国产欧美久久一区二区| 欧美成人激情视频免费观看| 日韩在线观看免费网站| 亚洲精品视频久久| 国产成人精品视频| 日韩va亚洲va欧洲va国产| 亚洲伊人第一页| 久热精品视频在线| 国产精品视频自拍| 岛国视频午夜一区免费在线观看| 亚洲国产欧美日韩精品| 国产99久久精品一区二区 夜夜躁日日躁| 亚洲毛茸茸少妇高潮呻吟| 欧美老女人bb| 久久久电影免费观看完整版| 欧美午夜视频一区二区| 欧美激情中文字幕在线| 国产精品爽爽ⅴa在线观看| 亚洲精品中文字| 欧美最猛性xxxxx(亚洲精品)| 久久久久久国产精品三级玉女聊斋| 亚洲精品720p| 欧美一级黄色网| 人九九综合九九宗合| 精品久久久久久久久国产字幕| 亚洲人在线视频| 精品视频www| 黑人巨大精品欧美一区二区免费| 欧美激情视频一区二区三区不卡| 亚洲欧美三级在线| 日韩欧美成人免费视频| 精品一区精品二区| 精品亚洲国产视频| 欧美在线视频在线播放完整版免费观看| 国产在线精品成人一区二区三区| 欧美精品免费看| 日韩中文字幕av| 欧美三级欧美成人高清www| 欧美久久久精品| 国产精品视频久久久| 91中文精品字幕在线视频| 在线日韩中文字幕| 欧美一区亚洲一区| 亚洲精品电影在线观看| 欧美大尺度激情区在线播放| 国产一区二区三区视频免费| 免费99精品国产自在在线| 久久久国产精品x99av| 色综合伊人色综合网| www.欧美精品| 久久久亚洲影院| 欧美午夜激情在线| 国产成人免费av| 在线日韩欧美视频| 国产精品夫妻激情| 91亚洲精品久久久久久久久久久久| 亚洲性线免费观看视频成熟| 成人激情春色网| 伊人久久精品视频| 北条麻妃一区二区在线观看| 91超碰中文字幕久久精品| 粉嫩老牛aⅴ一区二区三区| 国内精品小视频在线观看| 亚洲一级黄色片| 国产精品视频99| 亚洲区bt下载| 国产精品久久久久久久久影视| 精品一区二区三区三区| 欧美激情精品久久久久久蜜臀| 中文字幕日韩免费视频| 亚洲aaaaaa| 日韩精品视频在线播放| 亚洲视频综合网| 亚洲国产欧美精品| 欧美亚洲视频一区二区| 成人免费直播live| 亚洲人成电影在线观看天堂色| 4438全国成人免费| 欧美野外wwwxxx| 国产精品丝袜一区二区三区| 欧美精品做受xxx性少妇| 国产欧美日韩中文字幕| 欧美精品videosex极品1| 高清欧美性猛交xxxx黑人猛交| 欧美激情一级欧美精品| 亚洲片在线资源| 激情亚洲一区二区三区四区| www欧美xxxx| 在线观看欧美日韩| 久久久久女教师免费一区| 免费av在线一区| www.日韩欧美| 欧美成人三级视频网站| 日韩欧美成人精品| 庆余年2免费日韩剧观看大牛| 欧美成人久久久| 精品中文字幕在线| 久久亚洲一区二区三区四区五区高| 7777精品久久久久久| 日本免费一区二区三区视频观看| 欧美另类在线播放| 亚洲视频电影图片偷拍一区| 黄色一区二区在线| 久久天天躁日日躁| 欧美激情喷水视频| 国产精品日韩在线| 欧美日韩中文字幕日韩欧美| 伊人精品在线观看| 亚洲一级片在线看| 国产91久久婷婷一区二区| 日韩高清人体午夜| 国产欧美亚洲视频| 国产精品久久国产精品99gif| 乱亲女秽乱长久久久| 欧美中文字幕精品| 亚洲成人教育av| 亚洲aaaaaa| 精品国产福利在线| 在线午夜精品自拍| 欧美午夜片欧美片在线观看| 国产精品对白刺激| 欧美日韩国产麻豆| 欧美精品videos另类日本| 亚洲欧美综合图区| 色综合久久久久久中文网| 国产精品极品美女粉嫩高清在线| 亚洲高清久久久久久| 久久天天躁夜夜躁狠狠躁2022| 韩日欧美一区二区| 欧美国产激情18| 成人免费福利视频| 中文欧美日本在线资源| 久热99视频在线观看| 亚洲精品视频在线观看视频| 中文字幕国产日韩| 国产不卡av在线免费观看| 久久久久久久999精品视频| 97人洗澡人人免费公开视频碰碰碰| 亚洲美女在线看| 欧洲亚洲免费在线| 久久九九国产精品怡红院| 国模精品一区二区三区色天香| 欧美激情在线有限公司| 亚洲激情免费观看| 亚洲xxx视频| 岛国av午夜精品| 亚洲精品资源美女情侣酒店| 欧美日韩国产精品一区二区不卡中文| 久久手机免费视频| 日本免费一区二区三区视频观看| 国产成人精品一区二区在线| 精品久久久久久久久久久久久| 57pao成人永久免费视频| 高清一区二区三区日本久| 九九综合九九综合|