久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

Java面試必問:BIO、NIO、AIO三種I/O模型詳解與實(shí)戰(zhàn)

Java面試必問:BIO、NIO、AIO三種I/O模型詳解與實(shí)戰(zhàn) 1. 從一次面試問答說起這三個IO模型到底在聊什么“AIO、BIO 和 NIO 的區(qū)別是什么”——如果你準(zhǔn)備過頭幾個月的Java后端面試這個問題一定不陌生。它幾乎是JVM網(wǎng)絡(luò)編程里最高頻的送分題但有意思的是真正能把三者講透的候選人并不多。大部分人的回答停在“BIO是阻塞的、NIO是非阻塞的、AIO是異步的”這種口訣層面一追問到“為什么Netty不用AIO”“NIO和AIO各自的底層實(shí)現(xiàn)是什么”就露餡了。我先給個整體定位BIOBlocking I/O、NIONon-blocking I/O、AIOAsynchronous I/O是Java在不同版本和不同應(yīng)用場景下提供給開發(fā)者的三種I/O處理模型。它們解決的問題不一樣設(shè)計哲學(xué)不一樣適配的業(yè)務(wù)場景也不一樣。實(shí)際項(xiàng)目中大部分常規(guī)Web服務(wù)用的是BIO或者說Servlet容器傳統(tǒng)的連接處理方式高性能網(wǎng)關(guān)、RPC框架底層幾乎都是NIO模型而AIO雖然一度被寄予厚望但在Linux平臺上的落地表現(xiàn)并不理想反而在Windows上有過一段相對靠譜的實(shí)現(xiàn)。這篇文章我不只給你對比表格我會把三種模型的核心機(jī)制拆開講把“阻塞、非阻塞、異步”這幾個詞背后的線程模型、系統(tǒng)調(diào)用、底層數(shù)據(jù)結(jié)構(gòu)講清楚再結(jié)合面試場景給你一套可以直接背下來、也能扛住追問的回答框架。無論你是準(zhǔn)備面試的Java開發(fā)還是想搞清楚手頭項(xiàng)目的I/O模型選型這篇文章都適用。2. 先把概念拎清楚阻塞、非阻塞與異步之間不是一回事2.1 “阻塞”和“同步”不是一個維度上的概念我在面試別人時發(fā)現(xiàn)一個高頻誤區(qū)很多人把“同步/異步”和“阻塞/非阻塞”混在一起一上來就說“NIO是異步的”。這個說法是錯的。NIO的全稱是Non-blocking I/O它在本質(zhì)上仍然是同步I/O只是線程不需要一直卡在系統(tǒng)調(diào)用上等待數(shù)據(jù)就緒。要理解AIO和BIO、NIO的區(qū)別第一步就是把這四個詞拆開。阻塞與非阻塞討論的是“發(fā)起I/O請求的線程在數(shù)據(jù)還沒準(zhǔn)備好之前是否會被掛起”。阻塞模式下線程發(fā)起read()調(diào)用后如果內(nèi)核緩沖區(qū)里沒有數(shù)據(jù)這個線程就進(jìn)入等待狀態(tài)直到數(shù)據(jù)到達(dá)才算完非阻塞模式下read()調(diào)用會立刻返回如果沒有數(shù)據(jù)就返回一個標(biāo)志比如-1或者0線程可以去做別的事過一會再來看。同步與異步討論的是“數(shù)據(jù)從內(nèi)核復(fù)制到用戶緩沖區(qū)這一步由誰來完成以及完成之后怎么通知應(yīng)用程序”。同步I/O里真正的數(shù)據(jù)拷貝是發(fā)生在read()/write()系統(tǒng)調(diào)用內(nèi)部的應(yīng)用程序主動等這個調(diào)用返回異步I/O里應(yīng)用程序發(fā)起aio_read()之后立刻返回內(nèi)核把數(shù)據(jù)準(zhǔn)備好并且復(fù)制到用戶緩沖區(qū)之后再通過信號或回調(diào)函數(shù)通知應(yīng)用“數(shù)據(jù)已經(jīng)到位你直接拿來用就行”。所以組合出來是四種模型同步阻塞BIO就是這一類、同步非阻塞NIO、異步阻塞現(xiàn)實(shí)中幾乎沒有這個組合因?yàn)楫惒奖旧砭褪桥浜匣卣{(diào)用的、異步非阻塞AIO。BIO、NIO、AIO這三個簡稱并不是嚴(yán)格按這個四象限劃分的Java里它們更多代表了一套完整的API體系和編程范式但搞清楚底層歸屬之后很多困惑就迎刃而解了。2.2 BIO線程死等數(shù)據(jù)一對一服務(wù)BIO是Java 1.0就有的傳統(tǒng)I/O模型。Socket編程里服務(wù)端用ServerSocket.accept()接受客戶端連接然后為每個連接分配一個線程這個線程從accept()到read()到write()全程阻塞。我來還原一下最經(jīng)典的服務(wù)端代碼長什么樣ServerSocket serverSocket new ServerSocket(8080); while (true) { Socket socket serverSocket.accept(); // 阻塞在這里直到有客戶端連進(jìn)來 new Thread(() - { InputStream in socket.getInputStream(); BufferedReader reader new BufferedReader(new InputStreamReader(in)); String line; while ((line reader.readLine()) ! null) { // 處理請求 System.out.println(line); } }).start(); }這段代碼的問題顯而易見如果客戶端連接后不發(fā)送數(shù)據(jù)或者發(fā)送得很慢讀線程就會一直阻塞在readLine()上線程資源被白白占用。一個線程同時只能服務(wù)一個連接而JVM默認(rèn)的線程棧大小是1MB左右即便一臺服務(wù)器能開的線程數(shù)量有一定彈性當(dāng)連接數(shù)上升到幾千、上萬時線程切換的開銷和內(nèi)存占用就會把進(jìn)程拖垮。這個模型的好處是簡單、可靠、代碼直觀。對于連接數(shù)少、單個連接傳輸數(shù)據(jù)量大的場景比如企業(yè)內(nèi)部管理系統(tǒng)、傳統(tǒng)數(shù)據(jù)庫連接池BIO反而是最合適的。很多老項(xiàng)目的TCP服務(wù)仍然在用BIO不是因?yàn)樗鼈兟浜蠖且驗(yàn)闃I(yè)務(wù)規(guī)模根本不需要上NIO。2.3 NIO一個線程輪詢管理大量連接NIO是Java 1.4引入的一套新I/O API核心組件是Channel通道、Buffer緩沖區(qū)、Selector選擇器。和BIO面向流不同NIO面向緩沖區(qū)數(shù)據(jù)總是從Channel讀入Buffer或者從Buffer寫入Channel。最關(guān)鍵的是Selector。它底層在Linux上對應(yīng)epoll機(jī)制在Windows上對應(yīng)select機(jī)制作用是讓一個線程可以同時監(jiān)控多個Channel上的I/O事件。當(dāng)某個Channel上有數(shù)據(jù)可讀、可以寫、有新的連接到達(dá)時Selector會返回對應(yīng)的事件集合線程只需要遍歷這個集合逐個處理即可。Selector selector Selector.open(); ServerSocketChannel serverChannel ServerSocketChannel.open(); serverChannel.bind(new InetSocketAddress(8080)); serverChannel.configureBlocking(false); serverChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { selector.select(); // 阻塞等待直到至少有一個事件就緒 SetSelectionKey keys selector.selectedKeys(); IteratorSelectionKey it keys.iterator(); while (it.hasNext()) { SelectionKey key it.next(); if (key.isAcceptable()) { SocketChannel channel serverChannel.accept(); channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { // 從channel讀取數(shù)據(jù)到buffer } it.remove(); } }就這樣一個線程就能管理成千上萬個連接。線程不再死等某一個連接的數(shù)據(jù)而是空閑時阻塞在selector.select()上事件到來時統(tǒng)一處理。這個模型最大的價值是省線程連接數(shù)再多線程數(shù)量基本可控系統(tǒng)吞吐量被打通了一個量級?,F(xiàn)代高性能網(wǎng)絡(luò)框架的底層基礎(chǔ)就是NIO。Netty的 boss 線程、worker 線程模型本質(zhì)上就是基于NIO事件循環(huán)做擴(kuò)展的。2.4 AIO內(nèi)核全部干完活回調(diào)通知AIO是Java 7引入的異步I/O模型也叫NIO.2。它的設(shè)計目標(biāo)是更進(jìn)一步應(yīng)用程序發(fā)起一個異步讀操作之后連“監(jiān)控事件是否就緒”這步都不用管了內(nèi)核把數(shù)據(jù)從socket緩沖區(qū)復(fù)制到用戶緩沖區(qū)之后直接通過回調(diào)或者Future通知應(yīng)用程序去處理。AsynchronousServerSocketChannel server AsynchronousServerSocketChannel.open(); server.bind(new InetSocketAddress(8080)); server.accept(null, new CompletionHandlerAsynchronousSocketChannel, Void() { Override public void completed(AsynchronousSocketChannel channel, Void attachment) { server.accept(null, this); // 繼續(xù)接受下一個連接 ByteBuffer buffer ByteBuffer.allocate(1024); channel.read(buffer, null, new CompletionHandlerInteger, Void() { Override public void completed(Integer result, Void attachment) { // 數(shù)據(jù)已經(jīng)在內(nèi)核復(fù)制完成后被放到buffer里這里直接處理 } Override public void failed(Throwable exc, Void attachment) { // 處理異常 } }); } Override public void failed(Throwable exc, Void attachment) { // 處理異常 } });這段代碼有兩個特點(diǎn)一是沒有顯式的select阻塞二是所有I/O的結(jié)果通過CompletionHandler回調(diào)送達(dá)。從編程范式上說AIO是一種事件驅(qū)動的異步回調(diào)模型它比NIO更進(jìn)一步把線程從I/O等待中徹底解放出來。理論上是這樣但現(xiàn)實(shí)中AIO在Linux平臺上的表現(xiàn)讓人一言難盡。Linux內(nèi)核的異步I/O實(shí)現(xiàn)io_uring是現(xiàn)代版本早期的AIO基于epoll模擬成熟度不足Java的AIO實(shí)現(xiàn)底層在Linux上仍然依賴epoll事件通知本質(zhì)上沒有做到真正的內(nèi)核級異步性能相比NIO沒有明顯優(yōu)勢反而因?yàn)榛卣{(diào)編程復(fù)雜度更高、調(diào)試更困難導(dǎo)致它在中后端框架中幾乎沒有被廣泛使用。Netty的作者在官方文檔里也表達(dá)過對AIO的保留態(tài)度這也是Netty在Linux平臺上仍然堅持NIO模型的重要原因。3. 三個模型的機(jī)制拆解從線程模型到底層系統(tǒng)調(diào)用的完整對比3.1 線程模型差異一對一、一對多、還是完全不需要等我來把三種模型的線程模型放到一起看這是面試時最直接的答題線索。BIO是“一連接一線程”。建立一個連接就創(chuàng)建一個線程線程內(nèi)部從頭到尾處理這個連接上的所有讀寫。連接數(shù)等于線程數(shù)線程數(shù)受操作系統(tǒng)資源限制一般幾百到幾千就到頭了。這個模型天然適合短連接、低并發(fā)場景因?yàn)槊總€連接的存活時間很短線程復(fù)用率雖然低但創(chuàng)建銷毀線程的成本分?jǐn)傁聛硪策€能接受。NIO是“一線程多連接”。一個線程運(yùn)行著事件循環(huán)通過Selector同時管理成千上萬個連接。事件到來時才處理沒有事件時線程阻塞在select調(diào)用上不消耗CPU。這個模型的核心思想是把“連接”和“處理線程”解耦連接只是注冊在Selector上的一個事件源處理線程是共享的。AIO是“連接與線程完全無關(guān)”。應(yīng)用程序發(fā)出讀寫請求后立即返回不需要線程去輪詢或等待數(shù)據(jù)就緒后由內(nèi)核觸發(fā)回調(diào)。如果這時候一定要給它分配一個線程概念那么“回調(diào)執(zhí)行線程”是內(nèi)核或框架的線程池提供的業(yè)務(wù)線程本身全程不參與等待。面試官問你“怎么理解線程模型”你直接把這段話梳理清楚回答基本就穩(wěn)了。3.2 底層系統(tǒng)調(diào)用與數(shù)據(jù)結(jié)構(gòu)差異講完線程模型我建議你順帶把底層實(shí)現(xiàn)提一嘴這會明顯拉開和其他候選人的差距。BIO在Linux上走的是傳統(tǒng)的read()/write()系統(tǒng)調(diào)用配合socket的阻塞模式。進(jìn)程調(diào)用read()后如果數(shù)據(jù)沒有準(zhǔn)備好操作系統(tǒng)會把這個進(jìn)程的狀態(tài)設(shè)為睡眠TASK_INTERRUPTIBLE把它掛到socket的等待隊(duì)列上直到數(shù)據(jù)到達(dá)或超時。這個過程中CPU被讓出去了線程占用的內(nèi)存大概1MB但是不消耗CPU資源。NIO在Linux上走的是epoll這一組系統(tǒng)調(diào)用。程序先把需要監(jiān)控的文件描述符通過epoll_ctl注冊到內(nèi)核的事件表里然后調(diào)用epoll_wait阻塞等待。事件表里只要有任何一個fd就緒epoll_wait就會返回可處理的事件列表。這里有個關(guān)鍵區(qū)別epoll返回的是“就緒事件”本身而不需要程序再去遍歷所有連接去挨個檢查狀態(tài)時間復(fù)雜度從O(n)降到了O(就緒事件數(shù))。這也是epoll在大規(guī)模連接場景下遠(yuǎn)勝select/poll的地方。AIO在Windows上走的是IOCPInput/Output Completion Port這是Windows內(nèi)核原生的異步I/O實(shí)現(xiàn)完成端口會在線程池里調(diào)度一個線程來執(zhí)行完成回調(diào)它的設(shè)計是完善的。但在Linux上AIO那套系統(tǒng)調(diào)用aio_read()對socket的支持并不好Java的AIO實(shí)現(xiàn)實(shí)際上往Linux上還是會落到epoll那一套把“可讀”事件當(dāng)作“異步完成”的替代信號。所以本質(zhì)上在Linux上跑Java AIO底層依然是NIO的實(shí)現(xiàn)邏輯只是封裝層面多了一層回調(diào)。這個事實(shí)能解釋為什么AIO在Linux上性能上不去。我把關(guān)鍵差異整理成一張表面試前可以反復(fù)看維度BIONIOAIO全稱Blocking I/ONon-blocking I/OAsynchronous I/O引入版本JDK 1.0JDK 1.4JDK 1.7線程模型一連接一線程一線程多連接Selector異步回調(diào)不需要業(yè)務(wù)線程等待阻塞點(diǎn)read/write/accept全阻塞阻塞于selector.select()無阻塞點(diǎn)數(shù)據(jù)就緒后程序自己去讀程序輪詢就緒事件后自己讀內(nèi)核復(fù)制完成回調(diào)直接拿數(shù)據(jù)底層實(shí)現(xiàn)(Linux)read/write阻塞調(diào)用epoll事件驅(qū)動epoll模擬未真正異步底層實(shí)現(xiàn)(Windows)read/write阻塞調(diào)用selectIOCP原生異步適用場景連接數(shù)少、并發(fā)低高并發(fā)、連接數(shù)多、IO密集型高并發(fā)且對異步編程有明確需求的場景編程復(fù)雜度簡單中等較高代表框架傳統(tǒng)Servlet容器Netty、Mina、Tomcat NIO模式早期某些文件I/O場景3.3 緩沖區(qū)處理差異流式還是塊式BIO的操作單位是字節(jié)流你從InputStream里一個字節(jié)一個字節(jié)讀或者用BufferedReader按行讀數(shù)據(jù)在stream里是連續(xù)流動的沒有邊界的概念。這種設(shè)計對文本協(xié)議比較友好但網(wǎng)絡(luò)傳輸中的數(shù)據(jù)經(jīng)常是分幀的可能出現(xiàn)半包、粘包問題需要業(yè)務(wù)代碼自己去做邊界判斷。NIO和AIO的操作單位是Buffer數(shù)據(jù)在Channel和Buffer之間批量移動。Buffer有很多類型ByteBuffer、CharBuffer、IntBuffer等等其中ByteBuffer用得最多。你在讀數(shù)據(jù)時需要手動控制position當(dāng)前讀寫位置、limit有效數(shù)據(jù)邊界、capacity緩沖區(qū)容量這三個核心指針讀寫切換時要調(diào)用flip()、clear()、compact()等方法。這個設(shè)計比流式處理復(fù)雜但性能上限也更高因?yàn)閿?shù)據(jù)是按塊而不是按字節(jié)移動的減少了系統(tǒng)調(diào)用次數(shù)。舉個小例子從Channel讀數(shù)據(jù)到Buffer的典型操作ByteBuffer buffer ByteBuffer.allocate(1024); int bytesRead socketChannel.read(buffer); // 內(nèi)核把數(shù)據(jù)拷貝到buffer if (bytesRead 0) { buffer.flip(); // 從寫模式切換為讀模式 while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } buffer.clear(); // 清空準(zhǔn)備下次寫入 }flip()這句看著簡單但很多初學(xué)者在這里踩坑。如果不調(diào)用flip()就直接get()讀出來的數(shù)據(jù)可能是空的或者是不完整的數(shù)據(jù)因?yàn)閜osition還停留在寫入的末尾位置讀取操作沒有從有效數(shù)據(jù)起始位置開始。4. 面試場景實(shí)戰(zhàn)如何把回答組織得既有深度又能扛住追問4.1 開場回答概念差異速答面試官問出這個問題的時候他首先想聽的是一個干凈利落的定義性回答。我建議你按這個順序說“這三個是Java提供的三種I/O模型。BIO是同步阻塞I/O傳統(tǒng)的Socket編程一個連接對應(yīng)一個線程線程在讀寫時阻塞并發(fā)能力受限于線程數(shù)量。NIO是同步非阻塞I/O核心是Channel、Buffer、Selector這三件套一個線程通過Selector管理多個連接數(shù)據(jù)準(zhǔn)備好后線程再去讀適合高連接數(shù)場景。AIO是異步非阻塞I/O也叫NIO.2應(yīng)用發(fā)起讀寫后立刻返回內(nèi)核完成數(shù)據(jù)復(fù)制后通過回調(diào)通知應(yīng)用進(jìn)一步省掉了線程對I/O事件的等待。在Linux平臺上實(shí)際落地效果不如NIO所以Netty等主流框架默認(rèn)不用AIO?!边@段話大概40秒把三種模型的定義、核心機(jī)制、實(shí)際落地差異全說到了。說完之后面試官大概率會順著往下追問這時候就到了展示深度的時候。4.2 被追問“為什么不推薦AIO”時怎么答這是最容易踩坑的問題。如果你只是簡單說“AIO性能不如NIO”面試官會覺得你沒認(rèn)真研究過。正確姿勢是把原因拆成兩層第一層是Linux內(nèi)核的異步I/O機(jī)制不夠成熟。早期的Linux AIO系統(tǒng)調(diào)用aio_read()對文件描述符支持有限對socket支持更差后續(xù)雖然有io_uring這種現(xiàn)代異步框架但Java的運(yùn)行時和第三方框架并沒有第一時間跟進(jìn)適配。Java的AIO在Linux上的實(shí)現(xiàn)是繞道epoll模擬出來的既然底層還是epoll那一套那它和NIO的性能差距很難拉開還多了一層回調(diào)封裝的開銷和復(fù)雜度。第二層是編程模型的復(fù)雜性。AIO把控制權(quán)完全交給回調(diào)代碼的執(zhí)行流程變得不連貫異常處理也被分散到failed方法里一旦業(yè)務(wù)邏輯復(fù)雜調(diào)試和排錯的成本很高。NIO雖然也復(fù)雜但它的代碼邏輯至少在同一個線程內(nèi)是順序可讀的出事之后可以通過日志定位到某一次事件處理的循環(huán)里。權(quán)衡下來工程團(tuán)隊(duì)更愿意選擇NIO而不是AIO。4.3 被追問“Netty為什么不用AIO”時怎么答這個問題是上一問的延伸但更貼合實(shí)際框架選型。Netty的定位是高性能網(wǎng)絡(luò)應(yīng)用框架它要在所有主流操作系統(tǒng)上提供一致的性能表現(xiàn)。在Windows上AIO有IOCP支撐性能確實(shí)好但在Linux上AIO名不副實(shí)。如果Netty全盤采用AIO就意味著不同平臺要走兩套底層而且Linux作為服務(wù)器端的主力系統(tǒng)反而表現(xiàn)最弱這不符合Netty的跨平臺高性能目標(biāo)。另外還要提一個設(shè)計點(diǎn)Netty的線程模型是從Reactor模式演化來的事件循環(huán)和NIO的Selector機(jī)制天然契合。NIO的事件驅(qū)動模型可以很好地配合Netty的pipeline機(jī)制在框架層面把編解碼、業(yè)務(wù)處理鏈路串聯(lián)起來。AIO的回調(diào)模型雖然也能實(shí)現(xiàn)pipeline但會把執(zhí)行線程的調(diào)度權(quán)交給操作系統(tǒng)線程池框架對線程模型的控制力度減弱反而不利于精細(xì)調(diào)優(yōu)。4.4 被追問“BIO、NIO、AIO分別適合什么場景”時怎么答這個問題考的是工程判斷力不是背定義。我給的參考回答B(yǎng)IO適合連接數(shù)不多、單連接持續(xù)傳輸?shù)膱鼍?。典型例子是傳統(tǒng)的JDBC連接池連接數(shù)可能只有幾十到幾百每個連接的使用頻率高線程阻塞等待數(shù)據(jù)庫響應(yīng)也不是多大的問題。再比如企業(yè)內(nèi)部的管理后臺、設(shè)備控制網(wǎng)關(guān)這些系統(tǒng)并發(fā)量低用BIO代碼簡單、穩(wěn)定可靠線上問題也好排查。NIO適合連接數(shù)大、單連接請求頻率不高或者請求量和連接數(shù)不完全匹配的場景。典型例子是網(wǎng)關(guān)服務(wù)、IM長連接服務(wù)、消息推送服務(wù)。幾萬個設(shè)備維持一個TCP長連接隨時可能有消息進(jìn)來如果用BIO線程數(shù)根本撐不住NIO的一個事件循環(huán)線程就能扛住幾萬個連接的調(diào)度。AIO適合對異步編程有明確需求且使用Windows平臺的場景或者某些高吞吐的文件I/O場景。比如基于NIO.2的異步文件讀寫在本地文件復(fù)制、日志寫入這類場景下AIO的表現(xiàn)比NIO直接輪詢要好因?yàn)槲募蘒/O的完成時間不確定用回調(diào)通知更加自然。但網(wǎng)絡(luò)編程領(lǐng)域AIO在主流服務(wù)器上確實(shí)沒有站穩(wěn)腳跟。4.5 面試官常挖的坑accept()和read()的阻塞細(xì)節(jié)有時候面試官會把問題引到具體方法層面比如“accept()是阻塞的嗎那為什么NIO里accept不阻塞”這個問題很多人在回答時語義含糊。我來理清楚BIO的ServerSocket.accept()是阻塞的調(diào)用線程會一直等待直到有客戶端發(fā)起連接。NIO的ServerSocketChannel.accept()默認(rèn)是非阻塞的但在實(shí)際代碼中我們通常先把channel注冊到Selector上然后調(diào)用selector.select()阻塞等待OP_ACCEPT事件。也就是說NIO里的線程并不是被accept()方法阻塞而是被select()方法阻塞這個區(qū)別很重要。它意味著線程等待的不再是某一個連接事件而是一批注冊好的事件源中任意一個發(fā)生變化事件粒度從“連接”細(xì)化為“連接、讀、寫、連接關(guān)閉”等具體操作。至于NIO的read操作SocketChannel.read()在非阻塞模式下也會立即返回如果數(shù)據(jù)沒準(zhǔn)備好就返回0讀到末尾返回-1。處理時要注意區(qū)分這兩種返回值0表示暫時沒有數(shù)據(jù)-1表示對端關(guān)閉了連接邏輯處理完全不同。5. 實(shí)操經(jīng)驗(yàn)手寫一個簡易NIO長連接服務(wù)踩過的坑5.1 從0到1的完整實(shí)現(xiàn)思路光說不練假把式面試之前我強(qiáng)烈建議你親手寫一個NIO服務(wù)端Demo哪怕只是用來加深理解也值。我來分享一個我去年寫過的簡易長連接服務(wù)包含了服務(wù)端接收連接、處理客戶端數(shù)據(jù)的完整邏輯。先搭骨架一個ServerSocketChannel監(jiān)聽端口配置為非阻塞模式注冊到Selector上監(jiān)聽OP_ACCEPT事件循環(huán)里調(diào)用selector.select()等待事件處理可接受事件時把新的SocketChannel注冊為OP_READ處理可讀事件時從Channel讀數(shù)據(jù)到ByteBuffer。我給出一個可以運(yùn)行的版本去掉異常處理簡化了代碼但核心流程完整public class NioServer { public static void main(String[] args) throws IOException { Selector selector Selector.open(); ServerSocketChannel server ServerSocketChannel.open(); server.bind(new InetSocketAddress(9000)); server.configureBlocking(false); server.register(selector, SelectionKey.OP_ACCEPT); System.out.println(server start on 9000); while (true) { selector.select(); // 阻塞直到有事件 IteratorSelectionKey keys selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key keys.next(); keys.remove(); if (key.isAcceptable()) { SocketChannel channel server.accept(); channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_READ); System.out.println(new connection: channel.getRemoteAddress()); } else if (key.isReadable()) { SocketChannel channel (SocketChannel) key.channel(); ByteBuffer buffer ByteBuffer.allocate(1024); int len channel.read(buffer); if (len 0) { buffer.flip(); byte[] bytes new byte[buffer.remaining()]; buffer.get(bytes); System.out.println(receive: new String(bytes)); // 簡單回顯 ByteBuffer writeBuf ByteBuffer.wrap((ack: new String(bytes)).getBytes()); channel.write(writeBuf); } else if (len -1) { // 對端關(guān)閉取消key并關(guān)閉channel key.cancel(); channel.close(); } } } } } }5.2 我在寫這個Demo時踩過的三個大坑第一個坑沒有調(diào)用keys.remove()或者selectedKeys的清理。selector.selectedKeys()返回的是本次事件的就緒集合處理完一個事件后必須從集合中移除對應(yīng)的SelectionKey否則下次select()時這個key還會存在于集合里造成重復(fù)處理同一個事件輕則重復(fù)讀數(shù)據(jù)重則NullPointerException。這是NIO新手最容易犯的問題。第二個坑對OP_READ事件處理中read()返回0的情況處理不當(dāng)。只要channel配置為非阻塞模式read()返回0是正?,F(xiàn)象表示當(dāng)前沒有數(shù)據(jù)可讀。我在早期版本里把返回0也當(dāng)作異常去關(guān)閉連接結(jié)果客戶端一空閑就被服務(wù)端斷開。正確的邏輯是len 0就處理數(shù)據(jù)len -1才關(guān)閉連接len 0不做任何事。第三個坑客戶端數(shù)據(jù)半包的處理。上面這個Demo在數(shù)據(jù)量很小時沒問題但當(dāng)客戶端一次性發(fā)送超過1024字節(jié)的數(shù)據(jù)時一次read()可能只讀走前1024字節(jié)剩下數(shù)據(jù)會在下次select()時繼續(xù)觸發(fā)OP_READ。如果業(yè)務(wù)協(xié)議是完整的消息你就需要自己維護(hù)一個累積緩沖區(qū)把不完整的消息暫存起來等完整幀到達(dá)后再解析。這就是Netty里ByteToMessageDecoder要解決的粘包拆包問題實(shí)際項(xiàng)目中你不會想自己造的。5.3 用telnet驗(yàn)證服務(wù)的正確姿勢寫完之后怎么驗(yàn)證最簡單的辦法是用telnet工具連上去手動輸入數(shù)據(jù)telnet 127.0.0.1 9000連上之后隨便輸入一行字符串按下回車服務(wù)端控制臺會打印“receive: 你輸入的內(nèi)容”并返回“ack: 你輸入的內(nèi)容”。多開幾個telnet窗口你會發(fā)現(xiàn)一個服務(wù)端線程就能同時處理所有連接的數(shù)據(jù)。這就是NIO“一個線程管理多連接”最直觀的體驗(yàn)。如果你所在環(huán)境沒有telnet也可以用Python一行命令臨時模擬TCP客戶端python3 -c import socket;ssocket.socket();s.connect((127.0.0.1,9000));s.send(bhello);print(s.recv(1024))5.4 如果換成AIO實(shí)現(xiàn)同一個服務(wù)要怎么寫我把同樣的回顯服務(wù)用AIO重寫了一遍你感受一下編程風(fēng)格的差異public class AIOServer { public static void main(String[] args) throws IOException, InterruptedException { AsynchronousServerSocketChannel server AsynchronousServerSocketChannel.open(); server.bind(new InetSocketAddress(9001)); System.out.println(aio server start on 9001); server.accept(null, new CompletionHandlerAsynchronousSocketChannel, Void() { Override public void completed(AsynchronousSocketChannel channel, Void attachment) { // 立刻為下一個連接注冊accept回調(diào) server.accept(null, this); ByteBuffer buffer ByteBuffer.allocate(1024); channel.read(buffer, null, new CompletionHandlerInteger, Void() { Override public void completed(Integer result, Void attachment) { if (result 0) { buffer.flip(); byte[] bytes new byte[buffer.remaining()]; buffer.get(bytes); String msg new String(bytes); System.out.println(receive: msg); channel.write(ByteBuffer.wrap((ack: msg).getBytes())); buffer.clear(); channel.read(buffer, null, this); // 繼續(xù)讀取下一條消息 } } Override public void failed(Throwable exc, Void attachment) { exc.printStackTrace(); } }); } Override public void failed(Throwable exc, Void attachment) { exc.printStackTrace(); } }); Thread.currentThread().join(); // 主線程等待避免進(jìn)程退出 } }AIO代碼的嵌套層級比NIO深accept成功回調(diào)里套read成功回調(diào)read回調(diào)里套下一次read回調(diào)。邏輯上不復(fù)雜但一旦業(yè)務(wù)步驟變多這個回調(diào)地獄會非常難看。這也是工程上更愿意用NIO而不用AIO的另一個現(xiàn)實(shí)原因代碼的可讀性和可維護(hù)性也是選型的重要考量。6. 常見問題與面試官話術(shù)應(yīng)對實(shí)錄6.1 “NIO既然是Non-blocking為什么selector.select()還會阻塞”這是我在面試中最喜歡追問的一個問題。很多背題型的候選人在這里會卡殼。答案是NIO的非阻塞指的是“單個Channel上的I/O操作不阻塞”但Selector的select()方法本身是阻塞的否則線程會進(jìn)入忙輪詢狀態(tài)CPU占用會飆升。線程阻塞在select()上等待的是事件通知這個等待是高效的線程讓出CPU由內(nèi)核在事件發(fā)生時喚醒它。從整體上看NIO的網(wǎng)絡(luò)I/O線程大部分時間都處于阻塞等待事件的狀態(tài)這和BIO的線程阻塞有本質(zhì)區(qū)別——BIO阻塞時只等一個連接NIO阻塞時等的是所有注冊連接的任意事件。6.2 “為什么說AIO是異步的但Java的AIO在Linux上又不算真正的異步”這個問題的核心在于區(qū)分“API層面的異步”和“操作系統(tǒng)層面的異步”。Java的AIO API提供的是CompletionHandler回調(diào)讓你發(fā)完請求就不用管了從程序員視角確實(shí)是異步編程。但Linux平臺上的底層實(shí)現(xiàn)并沒有走真正的異步I/O系統(tǒng)調(diào)用而是用epoll事件機(jī)制模擬出來的。真正的異步I/O應(yīng)該由內(nèi)核完成數(shù)據(jù)從內(nèi)核態(tài)到用戶態(tài)的拷貝然后通知應(yīng)用直接使用而Java的AIO在Linux上是內(nèi)核通知“數(shù)據(jù)可讀”應(yīng)用還得自己調(diào)用read()去把數(shù)據(jù)拷貝出來。所以API是異步的底層仍然是同步I/O的流程。6.3 “Tomcat的BIO和NIO模式差別在哪里”Tomcat從8.5/9.0版本開始已經(jīng)徹底移除了BIO模式默認(rèn)是NIO模式。老版本Tomcat的BIO模式里每個HttpServletRequest對應(yīng)一個線程處理線程從socket讀請求行、讀請求頭、讀請求體全程阻塞。連接數(shù)一多線程池打滿后面請求只能排隊(duì)。換到NIO模式后Tomcat的Acceptor線程只負(fù)責(zé)接收連接注冊到Poller線程監(jiān)控事件Poller發(fā)現(xiàn)可讀事件后把任務(wù)丟給工作線程池處理工作線程在處理業(yè)務(wù)時才占用等待網(wǎng)絡(luò)數(shù)據(jù)的工作不再占用線程。這解釋了為什么同樣一臺機(jī)器Tomcat從BIO切到NIO后能支撐的連接數(shù)能提升一個數(shù)量級。6.4 “RPC框架的I/O模型選擇有標(biāo)準(zhǔn)答案嗎”理論上RPC框架在網(wǎng)絡(luò)傳輸層都可以用BIO。但實(shí)際的高性能RPC框架比如Dubbo、gRPC這些幾乎都基于NIO實(shí)現(xiàn)原因在于RPC的調(diào)用方通常是海量并發(fā)請求TCP連接的復(fù)用率極高BIO的“一連接一線程”模式會讓線程數(shù)失控。Dubbo默認(rèn)使用的就是Netty底層是NIO事件循環(huán)。這里有一個反直覺的點(diǎn)NIO雖然適合高連接數(shù)但單個連接上的吞吐量并不一定比BIO高因?yàn)镹IO要對每個事件做額外調(diào)度和狀態(tài)管理。所以如果你的系統(tǒng)就是單連接、持續(xù)大數(shù)據(jù)傳輸比如文件傳輸服務(wù)BIO或者專門的傳輸協(xié)議反而可能更高效。6.5 會不會被問到“IO多路復(fù)用和NIO的關(guān)系”大概率會被追問。IO多路復(fù)用是操作系統(tǒng)提供的一種能力讓一個線程同時監(jiān)控多個文件描述符的可讀、可寫狀態(tài)select、poll、epoll都是具體的實(shí)現(xiàn)機(jī)制。NIO在Java層的Selector就是IO多路復(fù)用的封裝。更嚴(yán)格地說Java NIO的Selector在Linux上就是epoll的包裝在Mac上則是kqueue的包裝。所以NIO能夠做到“一個線程管成千上萬連接”本質(zhì)上是IO多路復(fù)用機(jī)制在Java層的體現(xiàn)。而BIO完全沒有使用多路復(fù)用因?yàn)樗恍枰瑫r監(jiān)控多個連接——一個線程只盯著一個連接的讀事件。AIO在Windows上走IOCP它的邏輯更加接近“異步通知”而不是“多路復(fù)用”但在Linux上的Java實(shí)現(xiàn)又繞回了epoll所以準(zhǔn)確地說AIO的Linux實(shí)現(xiàn)也是多路復(fù)用的變體。7. 給準(zhǔn)備面試的人的最終建議7.1 不要只背結(jié)論要把機(jī)制畫出來我見過很多候選人能把概念表背得滾瓜爛熟但一讓畫圖就露餡。面試前你可以試著在一張紙上畫出三種模型的線程與連接關(guān)系圖BIO是每個線程拉著一根線連接一個socketNIO是一個線程面前放著一個SelectorSelector連著很多socketAIO是socket直接連著回調(diào)函數(shù)的代碼塊。如果你能自己畫出來說明你是真懂了而不是背了一堆結(jié)論。另外要留意我在面試時經(jīng)常讓人現(xiàn)場模擬“假設(shè)有個客戶端連接上來之后每10秒才發(fā)一條消息服務(wù)端線程怎么看”的場景。BIO里那個線程這10秒就是在阻塞等數(shù)據(jù)白白占用資源NIO里線程在等其它事件這個連接只是注冊列表里的一項(xiàng)AIO里壓根沒有線程在等。能把這段場景敘述清楚面試官基本就認(rèn)可你對三者的理解了。7.2 結(jié)合JDK版本演進(jìn)講亮點(diǎn)更大有個很討巧的加分技巧把三種模型放進(jìn)JDK版本的時間線里講。JDK 1.0時代剛有網(wǎng)絡(luò)編程BIO是唯一選擇。JDK 1.4引入NIO這一版就是為高性能網(wǎng)絡(luò)框架準(zhǔn)備的但早期的NIO API用起來很繁瑣所以Netty這種封裝框架才有生存空間。JDK 7引入AIO本意是提供真正的異步I/O文件I/O場景也好、網(wǎng)絡(luò)I/O場景也好都有更高級的API可用。但后來Linux平臺上的網(wǎng)絡(luò)AIO沒有被大規(guī)模采用反而NIO經(jīng)過Netty等框架的深度封裝成了事實(shí)上的標(biāo)準(zhǔn)。JDK 9又開始推進(jìn)異步的、基于流的API設(shè)計這是更高層面的演進(jìn)方向。把時間線講出來說明你在系統(tǒng)性理解這個問題而不只是背了三個名詞。7.3 最后提醒寫代碼永遠(yuǎn)比背定義管用這篇文章信息量不小但我最想給你留的一句忠告是就算你把所有知識點(diǎn)都背下來了如果不親手寫一遍NIO服務(wù)端、不讓幾個客戶端同時連上來實(shí)測一把你對這三者的理解始終是空心的?;ò胄r把上面那個Demo跑起來把telnet打開親眼看一兩個線程扛住幾十個連接比你在網(wǎng)上看十篇對比文章都值。面試的時候如果還能把我上面寫的那些底層原理結(jié)合你跑過的現(xiàn)象來敘述你已經(jīng)超過絕大多數(shù)候選人了。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
蜜色网色哟哟| 亚洲国产成人精品999| a片亚洲一本通视频| 欧美 色 亚洲| 亚洲综合中文字幕有码| 亚洲人成色9999精品久久| 亚洲天堂少妇| 91精品伊人久久久大香线蕉91| 亚洲城人男人的天堂| 精品对白久久不卡| 激情丁香五月婷婷| 大肥女高潮bbwbbwhd视频| 国产亚洲禁久一区二区| 精品免费成人久久| 亚洲人妻av| 中文字幕精品亚洲熟女| 一本一道vs波多野结衣| 青青草色插素人| 涩综合导航| 日本加靬比网站发布页| 亚洲操人| 欧洲一区二区三区四区在线观看| 欧美久久伊人| 精品无码一区二区三区| www激情| 91久久免费视频互動交流| 婷婷五月天影院| 精品人妻一区二区三区鲁大师| 99综合免费视频| 色区97| 五月丁香六月综合缴清无码| 91美女色视频亚洲| 亚洲中文字幕熟女少妇一区二区| 天天摸天天操视频| 综合五月天| 天天夜夜rb| 久久骚| av麻豆啪啪| 97人肏| 日韩999| 色综合婷婷| 操逼视频亚洲| 久久久久成人亚洲国产| 青草精品视频-日本久久久久网站| 国产精品乱码久久久久久| 亚洲成人色情五月天丁香花| 中文字幕精品探花视频| 亚洲熟女综合一区二区| 亚洲在线a| 97在线免费观看视频| 乱人乱色一区二区三区免费 | 国产亚洲日本| 日逼五月天| 天天天天天天天天综合| 啊啊啊啊好疼视频| 少妇蹲下买菜露大唇0| 熟女网站最新| 精品无码产区一区二| 日本精品免费一区二区三区四区| 2017天天透天天通天天擦| 亚洲区限制级| 美女啊啊啊啊啊啊| 日日操免费视频| 狠狠操,使劲操| 97亚洲综合影院| 小说区 图片区色 综合区| 免费?级毛片无码?∨蜜芽试看| 久久超碰国产一区二区三区| 日本高清一区二区在线| 久热69九色熟妇97| 精品然女一区二区| 天天在线91| 97超碰欧美精品| 日韩无限资源| 国产一级137片内射麻豆| 成人一道本免费视频| caoni国产亚洲av| 亚洲一本大道中文字幕无码在线| 亚洲天堂另类小说男人| 欧美亚洲清纯| 欧美狠狠| 无码日韩网站| 美女91在线观看| 免费a级毛片av无码久久精品中文字幕| 日韩高清黄片| 精品久久久亚洲AV成人网站| 78p欧美| 91 国产丝袜在线播放-百度| 久久久精品网| 久久免费精品视频免一| 少妇特黄一区二区三区| 亚洲欧美日韩中文播放| 亚洲天堂7777| 午夜福利久久久噜久噜久久综合| 中文字日本乱码| 日韩亚洲97| 久久性爱视频免费看| 亚洲日韩成人性爱视频| 夜夜狠狠躁日日躁色视频| 91久久国产精品| 青娱乐福利99| 欧美在线大香蕉| 97伊人| 国产三级多多影院2022国产AA一级毛片无码| 国产激情av女片自拍| 欧美色色色| yy少妇精品久久| 91亚洲欧洲| 欧美很很操视频| 色大师网站www永久网站视频| 91欧美综合| 日韩性爱电影一区| 99热日| 99re免费视频精品全部| 欧美毛片在线网| 久久久国产av美女私房| 婷婷中文字幕| 欧亚 另类 久| 乳欲人妻办公室奶水| 富二代亚洲精品99| 97免费在线| 九热视频| 欲香欲色| 精品久久青青草| 久久在肏| 五月丁香六月婷| 亚洲猛交| 国产操逼逼网| 国产久久日韩网站导航| 91精品国产一区三一| 日韩性爱一级片| 天堂蜜桃无码视频一区二区| 嗯嗯不要视频| 按摩中文字幕| 四虎国产精品永久入口| 日韩精品一二三四| Av手机版天堂网| wwe 天天干.com| 变态综合色| 五月天精品| 中文字幕一二三| 精品久久視頻在线| 欧美视频一| 四虎884a| 亚洲夜夜欢无码一区二区| 国产成人啪一区二区| 欧美日韩性爱无码| 国产 日韩 另类 视频一区爱| 欧美亚洲厕所精品偷拍91| 日韩中文字幕国产| 亚洲久久久| 青青爽| 欧美呦呦性爱| 9精品久久久久| 日韩成人精品中文字幕| 日韩黄片视频试看| 性91| 嗯嗯啊啊视频一区二区三区| 五月天综合网| 黑人精品一区二区在线播放| 综合91网| 天天看综合网| www.激情| 久久久久久亚洲Av无码| 99蜜月精品久久| 91色情黑丝搞鸡在线观看一区二区三区三州| 午夜噜噜噜| 免费综合亚洲中文| 密乳视频在线| 天天躁夜夜躁狠狠躁AV| 五月婷婷丁香六月| 色哟哟综合| 久久人人爽av亚洲精品天堂桃色| 色丁香五月婷婷| 岛国1区2区3区在线观看| 一区二区三区男女操逼黄色小电影| 熟女五十路一区二区三| 爱逼综合| 精品免费成人久久| 偷拍在线观看视频| 五月丁香网站| 免费一级视频特黄色大片| 日日干天天干夜夜爽| 亚洲双插| 欧美日韩另类字幕中文| 黄色污污污污污污网站| 色综合色综合网| 91被操| 欧洲精品一二三在线| 国产日韩欧美三级片| 91久久久亚洲| 欧洲亚洲人妻无码高清久久三区四区| 中国小夫妻勾搭露脸淫荡对白| 日韩一级片| 日韩色欲久久一二三四区| 国产一级高清免费观看| 99热这里都是精品| 久久久天堂| 情色五月天久久久| 亚洲情色婷婷五月天| 中文字幕精品资源在线| 手机在线中文字幕国产 | 婷婷综合网| 中文字幕国产| 日韩欧洲操屄视频| 青娱乐淫乱1314| 99热婷婷一区二区三| 色偷偷超碰亚洲| 十八禁黄色成人网站观看| 欧美男女午夜啪啪| 四虎永久在线精品免费网址| 婷婷色五月激情| 久草国产在线视频| 91一区二区三区蜜桃| 日韩91网站| 青青草依人大香蕉| 欧美97免费| chaopen97久久| 青青青草伊人精品| 蜜桃狠狠色伊人亚洲综合| 亚州色阁| 十八禁电影伊人网| 青青草好吊| 黄色片G G G| 极品后入免费视频| 日本在线999| 亚洲黄色电影| 欧美福利视频啊啊啊啊| 日韩成人精品| 能在线播放的国产三级| 九九无码视频| 欧美三级一级| 日韩二级| 国内成人圈中文字幕无码视频| 亚洲十八禁止| 自拍啪啪视频| 97在线免费视频观看| 97在线播放| 日本二三四区| 中字幕人妻一区二区三区| 日本一区二区三区午夜观看| 国产精品原创巨作?v网站| 狠狠操夜夜| 91站街按摩店老熟女熟女| 女人被添高潮免费视频| 97精品国产97久久久久久免费| 无码一区二区三区四区五区六区七区八区九区十区视频 | 久久亚洲国产成人| 都市久久精品激情亚洲| 桃花色涩综合影院| 日本中文字幕在线视频| 九九天堂| 天天拍天| 97干在线视频| 色欲无码人妻日韩欧美精品| 久久久人体| 超碰97最新人妻| 啊啊在线| 一级@啪啪视频| 干婷婷综合网| 久久av色| 久久99九九九九6666免费观看软件| 91一区二匹| 欧美日韩一区二区三区四区蜜桃| 中文字幕 码 自拍 视频 区| 2000亚洲男人天堂| 78精品| 9/A片 | 亚洲人妻久久| 色在线综合| 五月婷婷五月天| 97色视频在线| 加勒比综合| 强奸乱伦大香蕉网| 日韩欧美成人大香蕉| 国产精品九九| 粉嫩av久久一区二区三区| 五月天婷婷色| 人妻夜爽夜夜爽| 国产精品黑人一区二区三区| 五月婷婷综合网| 大屁股国产在线视频| 秋霞Av理论一级在线| 亚洲成av人片色午夜乱码| 2025亚洲男人天堂| 国产综合久久久麻桃个| 强奸乱亚洲| 五月开心久久AV官网| 放黄片放3级黄片没穿衣服| 无码天天操| 超碰 另类 欧美 | 成人一级性爱| 精品无码久久久久| 少妇高潮流水av免费| 中文字幕精品一区二区精品| 国产后入清纯| 成人三级片无码| 亚洲aw毛茸茸在线| 国产成年女黄特黄| 国产亚卅97| 正在播放:深夜激情大战,自带黑丝袜全力输出骚穴 | 最新加勒比丝袜在线| 欧美日韩97在线| 1人人看人人摸人人操| 久久免费中文字幕在线观看| 91欧美色| 亚洲精品视频二区| 欧洲黄色网| 综合网欧美在线| 五月天日日操夜夜操| 黄色性爱网网| 欧美日韩不卡传媒| 人妻天堂综合网| 一二三区精品视频| 欧美亚洲日韩人妻在线观看| 日韩色香| 99精品伊人| WWW操逼| 欧美A√综合网 | AAA久久| 欧美偷拍| 色婷婷在线视频精品导航| 精品无码秘 人妻一区二区 | 啊啊啊啊啊好多水| 色偷偷色偷偷欧美日韩| 免费综合亚洲中文| 福利大香蕉| 国产自偷自拍一区| 蜜臀久久99精品久久久| 麻豆黄四叶草网站| 乱论91| 综合亚洲网| 后X久久| 国产成人精品必看| 日韩电影中文字幕| 亚洲中文人妻色| www.久久制服糖| 狠狠操狠狠燥| 欧亚乱色熟女一区二区| 97在线免费看视频| 国产中出内射一区二区| 清清草影| 超碰97爽| 俺去俺来也在线www| 日本免费二区三区| 91亚洲不卡一区| 精品人体无圣光凹凸| 四虎免费在线播放| 美女91在线观看| 牛牛aV| 国产路线专区| 玖玖超碰熟| 久久秀这里有精品| 深夜国产一区二区三区在线看 | 中文字幕乱码人妻二区三区| 精品十八在线观看| 欧洲精品人妻| 五月天开心网| AA特级绝黄| 肏逼视频日本| 天天色欧美| 五月天欧美色图| 91蜜臀在线久久久久| 91社区拍啪人妻| 精品性爱| 亚洲欧美综合网 | 在线日韩日本亚洲国产| 精品无码少妇| 亚洲脚交| 男人的天堂日韩| 欧美爆操91| 色色五月婷| 国产精品网址| 内射老妇BBWX0C0CK| 日韩本不卡视频在线观看| 91偷拍欧美亚洲| 亚洲宅男天堂| 丝袜 亚洲 偷拍| 日本精品高清一二区一本到| 午夜视频好爽啊| 亚洲天堂区| 久久肏大逼| 日韩综合无码色欲vv| J?P?NESEHD熟女熟妇伦| 另类图片天天影视| 国产白丝AV| 国产又大又粗又长视频| 久操在97| 日日夜夜草草草| 人人操天天爽| 欧美亚洲第1页| 色哟哟AV| av在线资源| 天美欧美国产| 一区二区视频你懂的| 人妻天天夜夜爽一区二区| 国语对白在线播放视频| 强奸乱伦αv片| 国产极品美女高潮无套在线观看 | 大逼色网站| 成人草草视频| 亚洲偷91色| 欧洲精品区| 日韩精品国模| 欧美亚洲色的图| 最新精品久久蜜桃 | 男女猛烈无遮掩视频免费软件| 婷婷超| 99久久久无码国产精品性啊聊| 亚洲色图亚洲| 人人贴人人摸| 首页中文字幕中文字幕免费| 人妻精品视频一区二区| 91操人| 国产欧美伊人| 亚洲永久AV无码精品秋霞| 蜜臀久久99精品| 久久综合久色欧美综合狠狠| 97视频620| 久久精品免视看国产成人﹣蜜臀av一区. 久久精品免视看国产成人,蜜臀av一区 | 中文无线日韩一区| 97色操| 夜夜爽夜夜爽| 啪啪啪东京| 久久一区二区三区入口| 久久精品人体AV| 日逼五月天| 欧美日日夜夜| 抽插亚洲无码| 一级片视频啪啪| 日本欧美一区二区三区免费| 激情五月综合网| 啊好大好舒服| 久久久久久久久国产| 亚洲骚逼少妇| 大香蕉www.超碰| 中文字幕在线观看二区三区| 九九99精品视频在线观看| 精品国产少妇高潮视频| 日韩特一级久久| 久久精品一区二区| 九九探花视频在线观看| 精品免费一区二区三区在线亚洲人成| 啊啊啊久久久视频| 三级日韩一区二区三区| 岛国成人av在线播放网址| 亚洲 日韩 欧美 国产综合体| 岛国人妻少妇av在线观看| 色香网| 激情五月综合开心五月| 99热91| 亚洲AO在线| 天堂网亚洲区手机版| 国产视频一区二区三区在线免费观看 | 久久久久亚洲Aⅴ无码| 欧美综合在线91| 啪啪性爱免费视频| 大香蕉在线视频15| 国产老太乱伦一区| 国产精品交换一区二区| 蜜臀久久99'精品久久久| 翔田千里无码中出中文字幕| 最新日产中文在线麻豆| 一区二区三区成人| 中文精品一区二去| 夜夜高潮夜夜爽高清视频一 | 国产欧美后入| 网站A V在线| 婷婷丁香九月| 狠狠夜色午夜久久综合在线| 国产精品午夜福利亚洲综合网| 久操高青| 操逼免费视频无码国产| 超碰98综合网| 久草福利在线资源站| 色偷偷人人玩人人舔人人操人人摸人人爽| 欧美黑人精品在线播放| 东京热大香焦| 99热啪啪| 亚洲综合第一页| 熟妇熟女一区二三区| 东北少妇高潮zzzz| 97爱b| 国产精品无码av在线 | 超碰色97| 久久人妻四季| 啪啪视频亚洲第一| 五十路熟女,国产欧美精品区一区二区三区| 中文字幕一区二区三区高清| 土豪酒店各种姿势玩弄极品幼稚| 无码抄逼网| 久久久久久性爱免费视频| 久久9亚洲| 99这里只有精品国产| 岛国不卡超碰护士AV在线播放| 强奸乱伦动态污图免费 | 国产操偷| 五十路一区无码| 欧美大香蕉97| 亚洲中文字幕av| 日韩一二三区| 加勒比AV天堂| 国产11页| 美国一区二区免费视频| 国产色图乱伦| 啪啪视频亚洲第一| 国产日本顶级一区二区三区| 香港成人一级视频在线青青草| 老司机深夜影院18未满| 黄片免费日韩| 欧美 日韩第一性色| 国产一区96在线| 亚洲91在线播放影院| 亚洲无码一区成人免费午夜 | 亚洲巨爆乳一区二区三区四季网| 91 国产丝袜在线播放-百度| 久久久久精| 国产亚洲禁久一区二区| 在线人成亚洲视频免费观看| 人妻夜爽夜夜爽| 69精品人人人人| 六月激情婷婷| 欧美性爱三区二区| 狠狠久久手机视频精品| 97神马久久| 老司机午夜福利视频一区二区| 99免费视频| 日韩精品黄片免费观看| ,成人免费啪啪视频| 人妻丝袜一区二区三区在线| 97久久国产精品| 久久色一区| 男人的天堂啪啪啪啪啪蜜桃不卡| 色成人Www精品永久观看| 欧美日韩在线视频网站| 91丨人妻丨国产丨丝袜| 久草看看看| 劲爆欧美人妖三区91| 欧美黄色图片| 国产天美欧美| 插入综合网| 99久久9| 日本中文字幕在线视频| h无码动漫在线观看| 99亚洲精品| 无码精品久久久久久亚洲| 97超碰超| 99999亚洲| 久久精品操| 欧美综合亚洲| 啊啊在线| 国产精品另类一区大香蕉| 翔田千里一区二区三区奶水| 26UUU欧美日本| 岛国爱情动作片在国产AV无码专区亚洲AV漫画| 欧洲精品二区| 欧美 亚洲 在线| 激情小说激情视频| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区 | 使劲用力艹少妇视频一区二区| 少妇被玩视频二三区| 中文字幕一区二区三区蜜臀| 久久久工口| 国产13区| 天天综合网1| 美女黄码视频午夜| 男女香蕉一区二区| 极品美女嘿咻| 天久久久噜噜噜久久国产精品爽爽| 大逼色网站| 午夜精品久久99蜜桃的功能章节| 九九九九久久久久| 日本一区二区三区免费观看| 热久久国产| 亚洲第2页| 一区二区三区机械有限公司| 懂色综合久久久| 九月AV| 久久大精品乱码视频人妻熟女| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师 | 夜夜躁狠狠躁日日躁av| 国产又黄又粗又猛大片| 中文字幕一区二区日韩网| 夜夜影视四色| 91校园春色长篇| 欧美永久激情一区二区| 欧美极品少妇| 国产精品操| 国产最新小视频在线播放下载| 偷拍自拍在线视频观看| 五月婷视频| 人妻无码后入| 成人日本片久久久蜜桃| 久久专区| 日本色色的视频| 亚洲 图片 综合91| 亚洲限制级| 东京太热男人的天堂久久久| 飘花国产午夜精品不卡| 另类天堂| 精品视频久久区| 五月婷色| 99re95| 午夜传煤十二区精品| 亚洲中字幕日本一区二区三区| 美中日韩无码| 伊人久久大香蕉线AV五月天| 日天天九九天堂666| 老外又粗又长一晚做五次| av国产无码| 东北老女人的激情视频| 青青五月天| 青青伊人这里只有精品| 97干色天堂| 青娱乐黄色录像| 人人人人插| 久久精彩视频9| 欧美天天在线| 亚洲乱色熟女一区| 国产超碰国产97| 亚洲自拍青操视频| 国产乱色国产精品免费视| 欧洲天天在线| 91熟女网| 婷婷五月av| 久草毛片| 国产网站在线播放| 狠综合网| 亚洲高清无毛一区二区| 综合干干干av久久久综合网| 亚洲se91| 婷婷综合五月| 欧洲亚洲人妻无码久久三区四区| 看日韩操逼| 欧美激情久久久久| 男人天堂黄片| 素人无码中文字幕| 天天激情干| 日日AV加勒比| 逼操网站| 一区二三区四区视频大全套| 亚洲欧洲综合av在线| 超碰97玖玖爱| 色黄污美女啪啪啪免费网站| 国精综合一二三区影视| 性爱综合一区二区| 国产精品suv一区| 性暴力欧美猛交在线直播| 日日夜夜国产综合| 高清国产成人无码| 日欧毛片久久| 强奸乱伦资源| 99精品无码| 99蜜月精品久久| 免费毛片在线播放| 欧美九九九| 91碰碰| 亚洲学生妹高清av| 爱欲AV| 日本狂喷奶水在线播放212| 超碰人妻中文在线| 操我无码| 国产美女自拍视频| 欧美内射少妇| 在线看片国产精品每日更新| 东京男人天堂| 久操黄色视频| 国内偷自视频区视频综合| 夜夜操中文字幕| 免费毛片在线播放| 亚洲另类春色| 久久久久亚洲一区女同性恋中文字幕| 色综合av男人天堂| 亚洲 欧美综合| 99re这里只有精品3| 这里只有精品视频在线观看麻豆 | 熟女精品va中文字幕| 亚洲加勒比色图| 超碰97起碰| 超碰人人操97碰| 91精品91久久久久77777| 色999人与兽| 亚洲成人日韩小说| 九九热三级片| 青青草乱入乱欲视频在线观看| 亚洲最大无码中文字幕网站| 久久久久久9| 久草男人天堂| 性欧美另类高清| 岛国网址国产 | 天天色图| 中出人妻中文字幕91在线| 丰满欧美少妇| 女人喷水视频在线观看| 伊人影院日本| 青青草原成人| 精品国产99| 激情久久久| 岛国视频一二三区| 性夜影院爽黄A爽免费动漫| 九九九九九九九| 第四色色综合91| 国产久久久久久久久一区二区| 日韩强奸av| 97精品全部| 亚州欧美一区| 麻豆九九九| 色综九九九一区| 日日黄色三级网站| 中文啪啪视频| 超碰在线国产| 亚洲国产成人精品久久久国产成人一区二区三. | 人妻性爱一区二区| 五十路三区在线| 蜜桃午夜视频一区二区| 久久伊人青青草| 亚洲熟妇图片| 男人的天堂亚洲| 国产亚州精品美女久久久免费| 国产极品粉嫩馒头一线天av| 91性感在线| 婷婷性网| 亚洲精品乱码久久久久久蜜桃麻豆| 人人澡综合涩| 91精品成人| 久久色一区| 最新AVzaixian| 男人兔费天堂| 人妻丝袜无 码视频专区| 九九无码视频| 亚洲成?V人片在线观看福利| 777AV电影| WWW啪啪的com| 欧美一区二区福利在线| 日韩性爱免费观看视频| 日韩熟女无码| 1000部熟女视频在线观看| 久久精品熟女亚洲AV麻豆软件| 日韩猛交| 神马久久久久久久| 精品99999| 女沟厕偷窥piss小便| 亚洲欧美另类小说| 亚洲色图欧美激情| 日韩成年人性爱视频| 东北毛片| 国产精品日韩在线一区| 日韩综合成人免费视频| 日韩亚洲中文有码视频| 综合欧美日韩在线观看| 7777欧美成是人在线观看| 中文字幕免费看大片| 欧美 亚洲 偷拍自拍| 一起草av| 国产黄a三级三级三级av在线看 | 亚洲色图亚洲| 欧美综合国产精品久久丁香| 天天插夜夜操| 国产一级黄色片在线观看| 性爱av网站| 67914亚洲精品| 日少妇亚洲版| 91男人天堂网| 久久久偷拍| 国产精品人妻无码久久久老鸭窝| 免费国产电影一区二区| 中国乱伦一区二区| 99在线精品观看99| 日韩中字av一区| 国产美女精品| 国产日韩美女小穴视频网站不卡| 欧美性夜| 日韩福利综合一区| 91香蕉视频在线观看免费| 综合影视国产无码| 亚洲少妇喷视频看| 精品人妻一区二区三区-国产精品 一个人在线看的黄色电影网站 | 欧美78| 久99在线免费观看视频| 91青青草| 啪啪资源网| 婷婷五月天成人网| 啊啊啊啊在线观看网址| 天天爽夜夜欢视| 婷婷探花久久精品一区| 熟妇乱伦一区二区| 福利视频一区二区微拍| 99综合免费视频| 欧美三级一级| 天美传媒精品久久视频| 国产呦精品系列在线观看| 欧美黑人精品在线播放| 色综合色综合网| 久久人爽| 激情一区二区| 色爱三区| 天天爽爽爽爽| 久久超碰av在线| 色哟哟AⅤ| 国产女人成人精品视频| 九九热五区| 9久久久久久| 91强热人妻| 天堂资源欧美| 国产精品久久久久久久久久久久久久| 日本黄大片在线观看视频| A久久| 熟女熟妇伦久久影院毛片一区二区 | 日韩欧美久久婷婷网站| 久久超碰国产一区二区三区| 2024人人操人人摸| n1038 一二三区| 美女91在线| 精品亚洲国产成人AV制服丝袜 | 欧美黑人168页欧美黑人167| 最近2018中文字幕在线高清第一页| 黄色毛片A片| oumeizonghese,www| 欧洲视频在线| 狠狠色婷婷777| 超碰天天操| 最新国内自拍av免费| 自拍偷拍2025在线观看| 加勒比伊人综合| 久久av无码| 久久精品免费| 男人天堂电影院| 久久丁香五月天| 999色欧美中文字幕| 无码黑人精品一区二区三区三| 黑丝日韩av丝袜av| 操久久久久| 秋霞视频一区二区 | 亚洲天堂五月天国产| 日本超碰在线国产一区| 91熟女网| 天天日天天舔天天喷天天射| 阿姨一区二区免费视频-高清正片西瓜视频下载app-T450AV | 99精品在线| 99热这里都是精品| 婷婷在线视频| JuliaAnn丝袜熟女系列| 人人色人人操在线| 欧美亚洲今日在线| 操操AV电影| 久久97| 精品97精品97| 欧美十八禁视频| 欧美性,亚州色| 精品亚洲一区在线观看| 97自拍一区| 国产人伦a片信息免费片| 狠狠图片青青草| 蜜臀AV秘一区翔田千里| 久热久操| 亚洲精品亚洲人成在线麻豆| yazhouzaixian| 90后性网国产欧美| 久久免费少妇| 夂久色| 欧美岛国精品在线观看| 亚洲三级网址久久最新| 中文字幕乱码人妻二区三区| 任你干在线视频| 大屁股xxxxx| 97爱综合| 高清肉丝中文无码| 亚洲高清无码AAA久久久精品| 久啪视频| 亚洲 欧美 中文 日韩超碰 | 欧美精品成人亚洲| 免费一级性爱久久| 久久久青草青青国产亚洲免观精品高清完整版_97久久综合区小说区图片区,国精品 | 超碰天天去日穴| 亚洲情色电影网| 国产精品免费日韩| 女上位精品在线| 久久久蜜桃一区二区三区| 麻豆国产97在线| 亚洲系列欧美| 丁香五月社区| 免费自拍三级综合| 黑人精品欧美一区二区蜜桃| 99中出在线| 日韩亚洲中文有码视频| 96一区二区三区| 精品国产99| 日韩精品免费高清视频在线| 96一区二区| 超碰碰激情97+久| 激情四射五月天| 日韩欧美操逼xxx| 日韩欧美麻豆 | 欧美亚洲丝袜美女电影| 国产区性爱在线视频秋霞豆 | 又黑又大又粗| 一本一道波多野毛片中文在线| 加勒比aⅴ| 99热在线不卡| 艹我哪美一区无码| 91丝袜在线观看| 亚洲日本大香蕉1| 久久久111| 久久婷婷影院| 中文字幕成人理论在线| 免费岛国一级片| 亚洲深夜福利| 亚洲少妇免费视频\| 你操综合| 成人夜夜爽| 女人喷水视频在线观看| 人人看人人插| 免费精品无码一级毛片牛牛影视| 人妻熟女一区二区| 黑丝日韩av丝袜av| 中亚av| 超碰人人妻| 久久免费精彩视频| 亚洲无码?第一页| www亚洲免费| 香蕉视频欧美一卡二卡| 伊人少妇久久久| 亚洲综合情色| 另类亚洲图色| 日韩av熟女一区二区三区成人| 久久女人一区二区三区| 亚洲操逼无码| 精品人妻美妇91job| 欧洲综合无码| 国产中文大片资源中文字幕 | 日韩啪啪啪啪啪| 五月婷婷久久综合| 亚洲中文字幕精品久久久久久直播| 伊人久久在线视频观看| 超碰无码加勒比| 天天看天天日| 色吧 综合| 99精品国产户外露出| 天堂成人网| www.yw尤物| 天堂中文资源在线bt| 亚洲精品天堂久久A∨51成人漫| 中文字幕,人妻,日韩| 日本操逼aaaaa| 日本精品中文字幕视频| 蜜臀在线视频| 亚洲欧美色图小说| 久久男人精品| 中文字幕一区二区三区字幕| 色五天伊人| 久艾草在线精品视频在线观看| 日韩在线欧美精品一区二区| 国产精品毛片?v一区二区三区| 日韩av性爱在线播放| 搞中出久久| 午夜福利视频在线一区| 色爱三区| 五月天伊人| 东京热男人的天堂精品| 久久中文字幕人妻熟av女蜜柚| 2019久久久久久久久福利| 精品久久大胆人体| 乱伦系列一区二区| 婷婷五月天av| 日本在线播放不卡一区| 国产成人网站在线观看| 久久黄黄| 无码heyzo高清一区| 亚洲限制级| 玖色av| 国产精品乱码久久久| 免费成人自拍视频在线| 日本三级A片网站com| 亚洲高清无码在线桃色| 亚洲午夜免费狠狠干| 亚洲国产综合久久天堂| 熟妇国产免费一区| 夜夜爽夜夜高潮夜夜爽| 日韩无码一级黄色av片| 99精品视频在线观看免费| 免费黄色片子| 中文字幕加勒比海高清无码免费视频 | 91五月天| 一区二区蜜臀| 曰本道人妻久久久在线不卡色视频| 亚洲欧洲自拍| 老熟女乱伦片| 男人a天堂手机在线版| 99热久| 超碰97网址| 欧美宗合网| 欧美精品99久久久**| 五月天大香蕉| 天美传媒AV国产在线| 欧美日韩资源| 少妇高潮特黄A片| 天美av在线观看| 夜夜夜夜爽| 91天天| 五月丁香综合| 手机av亚洲丝袜美腿日韩第一页二页| 亚洲天堂资源在线| 天天做日日做天天欢。| 99热在线播放| 超碰97在线色男人??| 日韩免费在线观看不卡| 国产精品老师| 青青三级视频| 无码精品久久| 国产精品交换一区二区| 一区二区三区在线日韩影院观看| 强奸乱伦AV一天堂网| 色色五月丁香| 中文精品少妇天堂| 国产精品女久久久久av爽| 97精品国产97久久久| 密臀在线视频| 日本国产欧美高清在线| 亚洲棕合电彰| 超碰97精品| 久久99操天天日| 美女上床网站| 国产人妻天天干精品| 日本99一区二区| 91精品老女人| 最新AVzaixian| 色欧洲| 色婷婷视频| 欧美的精品的视频| 午夜婷婷| 久久99干一本高清| 国产欧美日韩在线不卡第一页| 精品无码久久久久久国产浪潮| 久操婷婷| 亚洲一区二区AV| 国产精品麻豆成人AV艾秋| 插B在线观看| 强奸xx国产| 久久久亚洲精品中文字幕人妻| 亚洲午夜福利在线影院| 丝袜狂射91| 亚洲成A∨人影院在线欢看| 夜夜操一区二区| 91成人精品在线播放| 国产精品大屁股999| 丰满高潮18xxxx| 欧美特黄视频网站| 99热欧美| 老鸭窝成人免费毛片视频| 久久一二三四五六七八九区区区| 天天综合~91| 亚洲 图片 综合91| 欧美一级黄色免费专区| 性老妇一区二区三区| 日韩操啪| 日日噜噜夜夜久久亚洲一区二区 | 欧美亚洲日本视频久久久 | 国产成人五月天丁香花| 你想操日本小逼吗| 嫩草 我啊~嗯~在线| 自拍偷拍2025在线观看| 国产AV中文| 一区二区精品更新提醒| 久久av无码| 久久一区二区加油站| 欧美日韩91| 日韩精品-原创伙伴| 亚州乱码中文字幕综合久久久| 伊人久久在线视频观看| 色欧洲97| 国产欧美日韩在线观看麻豆传媒公司| 国产1024在线播放| 青青草乱入乱欲视频在线观看| 最新日产中文在线麻豆| 亚洲日韩美女丝袜美腿人妻视频| 九九成人| 一区二区三区高清天码| 91亚.色| 香蕉一区二区三区在线视频| 久久这里只精品免费福利| 国产白领连续中出在线观看| 97国产人人| 日日黄色三级网站| 国产成人www免费人成看片| 欧美激情在线观看视频| 国产馆极品诱惑| 97亚洲欧美| 欲射影视| 91粉嫩萝控精品福利网站_精品影音先锋国 | 婷婷色一区| 国产乱伦性爱区| 亚洲美女高潮喷水视频| 天天天天操| 午夜精品久久久久久久久久蜜桃| 91久久国外网| 91狠狠综合久久| 2023天天操夜夜操| 亚洲交换| 日韩钢筋无码高清啾啾啾| 99热这里| 综合自拍| 亚洲?V无码专区在线电影| 国产精品久久久久9999小说| 中文字幕精品久久久久人妻红杏ⅰ| 国产无马av| 乱伦1色页| 人人操 欧美| 天堂男人网| 欧美成人国产精品| 操操操操操操| 久久超碰久| 欧美三级中文字幕hd| 在线亚洲 欧美 日本专区| 日韩小电影| 亚洲成人色情五月天丁香花| 综合婷婷| 亚洲国产无码精品首页久久久| 欧美黄色大片在线观看 | 97超碰欧美| 日韩无码第3页| 十八禁一区二区无码观看| 久久一区,青青青青草视频在线播放| 亚洲另类在线观看| 乱抡国产91| 精品久久久av无码免费| 久热热| 女优大全 - 91n| 97久久久久久久久久| 欧美色综合图片| 国产精品熟妇一区二区三| 国产专区路线| 九九无码| 亚洲日韩精品在线播放| 国产成人99久久亚洲综合| 成人怡红院| 国产精品自拍视频| 中文字幕制服诱惑| 2017天天插| 人人透人人操| 国产 日韩 另类 视频一区爱| 中日韩熟女| 免费的黄片有限公司| 亚洲高清欧美总合| 色天天野狼综合社区| 97超碰总站| 男人的天堂三级| 九九国产热| 天天干天天日天天射黄色大片| 久久精品亚洲东京热色播| 丝袜综合色图| 日韩美女高潮喷水视频| 2021久久国产综合精品青草| 亚洲男人的天堂一区二区| 中文字幕天天天天天| 久久久不能久久久久| 91av天美性媒精品视频| 欧美午夜色妇色鬼| 欧美一二在线| 热久久国产精品视频大陆精品| 日本一区二区三区欧美日韩中文字幕|