精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深度長文:從Bio到Nio到Aio,再到響應式編程

系統 Linux
要問計算機系統里,有哪些概念比較折騰人,nio絕對能算上一個。配合著多是異的網絡編程,nio加上多線程一般能夠完成雙殺。

[[417220]]

本文轉載自微信公眾號「小姐姐味道」,作者小姐姐養的狗 。轉載本文請聯系小姐姐味道公眾號。

要問計算機系統里,有哪些概念比較折騰人,nio絕對能算上一個。配合著多是異的網絡編程,nio加上多線程一般能夠完成雙殺。

Linux有5種常見的IO模型。其中,阻塞IO就是bio,IO復用就是nio,異步IO就是aio,我們本篇文章就聚焦于此。

  • 阻塞式IO (bio)
  • 非阻塞式IO
  • IO復用 (nio)
  • 信號驅動式IO
  • 異步IO(aio)

在網絡編程中,Reactor模型是必須要了解的。現在,大多數與IO相關的組件,都會使用Reactor模型,比如Tomcat、Redis、Nginx等,可見Reactor應用的廣泛性。

Reactor是NIO的基礎。為什么NIO的性能就能夠比傳統的阻塞IO性能高呢?我們首先來看一下傳統阻塞式IO的一些特點。

1.阻塞IO模型

 

如上圖,是典型的BIO模型,每當有一個連接到來,經過協調器的處理,就開啟一個對應的線程進行接管。如果連接有1000條,那就需要1000個線程。線程資源是非常昂貴的,除了占用大量的內存,還會占用非常多的CPU調度時間,所以BIO在連接非常多的情況下,效率會變得非常低。

下面的代碼是使用ServerSocket實現的一個簡單socket服務器,監聽在8888端口。

  1. public class BIO { 
  2.     static boolean stop = false
  3.     public static void main(String[] args) throws Exception { 
  4.         int connectionNum = 0; 
  5.         int port = 8888; 
  6.         ExecutorService service = Executors.newCachedThreadPool(); 
  7.         ServerSocket serverSocket = new ServerSocket(port); 
  8.         while (!stop) { 
  9.             if (10 == connectionNum) { 
  10.                 stop = true
  11.             } 
  12.             Socket socket = serverSocket.accept(); 
  13.             service.execute(() -> { 
  14.                 try { 
  15.                     Scanner scanner = new Scanner(socket.getInputStream()); 
  16.                     PrintStream printStream = new PrintStream(socket.getOutputStream()); 
  17.                     while (!stop) { 
  18.                         String s = scanner.next().trim(); 
  19.                         printStream.println("PONG:" + s); 
  20.                     } 
  21.                 } catch (Exception ex) { 
  22.                     ex.printStackTrace(); 
  23.                 } 
  24.             }); 
  25.             connectionNum++; 
  26.         } 
  27.         service.shutdown(); 
  28.         serverSocket.close(); 
  29.     } 

啟動之后,使用nc命令進行連接測試,結果如下。

  1. $ nc -v localhost 8888 
  2. Connection to localhost port 8888 [tcp/ddi-tcp-1] succeeded! 
  3. hello 
  4. PONG:hello 
  5. nice 
  6. PONG:nice 

可以看到,BIO的讀寫操作是阻塞的,線程的整個生命周期和連接的生命周期是一樣的,而且不能夠被復用。

就單個阻塞IO來說,它的效率并不比NIO慢。但是當服務的連接增多,考慮到整個服務器的資源調度和資源利用率等因素,NIO就有了顯著的效果,NIO非常適合高并發場景。

2.非阻塞IO模型

其實,在處理IO動作時,有大部分時間是在等待。比如,socket連接要花費很長時間進行連接操作,在完成連接的這段時間內,它并沒有占用額外的系統資源,但它只能阻塞等待在線程中。這種情況下,系統資源并不能被合理的利用。

Java的NIO,在Linux上底層是使用epoll實現的。epoll是一個高性能的多路復用I/O工具,改進了select和poll等工具的一些功能。在網絡編程中,對epoll概念的一些理解,幾乎是面試中必問的問題。

epoll的數據結構是直接在內核上進行支持的。通過epoll_create和epoll_ctl等函數的操作,可以構造描述符(fd)相關的事件組合(event)。

這里有兩個比較重要的概念:

  • fd 每條連接、每個文件,都對應著一個描述符,比如端口號。內核在定位到這些連接的時候,就是通過fd進行尋址的
  • event 當fd對應的資源,有狀態或者數據變動,就會更新epoll_item結構。在沒有事件變更的時候,epoll就阻塞等待,也不會占用系統資源;一旦有新的事件到來,epoll就會被激活,將事件通知到應用方

關于epoll還會有一個面試題:相對于select,epoll有哪些改進?這里直接給出答案:

  • epoll不再需要像select一樣對fd集合進行輪詢,也不需要在調用時將fd集合在用戶態和內核態進行交換
  • 應用程序獲得就緒fd的事件復雜度,epoll時O(1),select是O(n)
  • select最大支持約1024個fd,epoll支持65535個
  • select使用輪詢模式檢測就緒事件,epoll采用通知方式,更加高效

我們還是以Java中的NIO代碼為例,來看一下NIO的具體概念。

  1. public class NIO { 
  2.     static boolean stop = false
  3.     public static void main(String[] args) throws Exception { 
  4.         int connectionNum = 0; 
  5.         int port = 8888; 
  6.         ExecutorService service = Executors.newCachedThreadPool(); 
  7.         ServerSocketChannel ssc = ServerSocketChannel.open(); 
  8.         ssc.configureBlocking(false); 
  9.         ssc.socket().bind(new InetSocketAddress("localhost", port)); 
  10.         Selector selector = Selector.open(); 
  11.         ssc.register(selector, ssc.validOps()); 
  12.         while (!stop) { 
  13.             if (10 == connectionNum) { 
  14.                 stop = true
  15.             } 
  16.             int num = selector.select(); 
  17.             if (num == 0) { 
  18.                 continue
  19.             } 
  20.             Iterator<SelectionKey> events = selector.selectedKeys().iterator(); 
  21.             while (events.hasNext()) { 
  22.                 SelectionKey event = events.next(); 
  23.  
  24.                 if (event.isAcceptable()) { 
  25.                     SocketChannel sc = ssc.accept(); 
  26.                     sc.configureBlocking(false); 
  27.                     sc.register(selector, SelectionKey.OP_READ); 
  28.                     connectionNum++; 
  29.                 } else if (event.isReadable()) { 
  30.                     try { 
  31.                         SocketChannel sc = (SocketChannel) event.channel(); 
  32.                         ByteBuffer buf = ByteBuffer.allocate(1024); 
  33.                         int size = sc.read(buf); 
  34.                         if(-1==size){ 
  35.                             sc.close(); 
  36.                         } 
  37.                         String result = new String(buf.array()).trim(); 
  38.                         ByteBuffer wrap = ByteBuffer.wrap(("PONG:" + result).getBytes()); 
  39.                         sc.write(wrap); 
  40.                     } catch (Exception ex) { 
  41.                         ex.printStackTrace(); 
  42.                     } 
  43.                 } else if (event.isWritable()) { 
  44.                     SocketChannel sc = (SocketChannel) event.channel(); 
  45.                 } 
  46.  
  47.                 events.remove(); 
  48.             } 
  49.         } 
  50.         service.shutdown(); 
  51.         ssc.close(); 
  52.     } 

上面這段代碼比較長,是使用NIO實現的和BIO相同的功能。從它的API設計上,我們就能夠看到epoll的一些影子。

首先,我們創建了一個服務端ssc,并開啟一個新的事件選擇器,監聽它的OP_ACCEPT事件。

  1. ServerSocketChannel ssc = ServerSocketChannel.open(); 
  2. Selector selector = Selector.open(); 
  3. ssc.register(selector, ssc.validOps()); 

共有4種事件類型。分別是新連接事件(OP_ACCEPT)、連接就緒事件(OP_CONNECT)、讀就緒事件(OP_READ)、寫就緒事件(OP_WRITE)。任何網絡和文件操作,都可以抽象成這四個事件。

接下來,在while循環里,使用select函數,阻塞在主線程里。所謂阻塞,就是操作系統不再分配CPU事件片到當前線程中,所以select函數是幾乎不占用任何系統資源的。

  1. int num = selector.select(); 

一旦有新的事件到達,比如有新的連接到來,主線程就能夠被調度到,程序就能夠向下執行。這時候,就能夠根據訂閱的事件通知,持續獲取訂閱的事件。

由于注冊到selector的連接和事件可能會有多個,所以這些事件也會有多個。我們使用安全的迭代器循環進行處理,在處理完畢之后,將它刪除。

如果事件不刪除的話,或者漏掉了某個事件的處理,會怎么樣呢?后果還是比較嚴重的,由于事件總是存在,我們的程序會陷入無休無止的循環之中。

  1. Iterator<SelectionKey> events = selector.selectedKeys().iterator(); 
  2.     while (events.hasNext()) { 
  3.         SelectionKey event = events.next(); 
  4.         ... 
  5.         events.remove(); 
  6.     } 

有新的連接到達時,我們訂閱了更多的事件。對于我們的數據讀取來說,對應的事件就是OP_READ。和BIO編程面向流的方式不同,NIO操作的對象是抽象的概念Channel,通過緩沖區進行數據交換。

  1. SocketChannel sc = ssc.accept(); 
  2. sc.configureBlocking(false); 
  3. sc.register(selector, SelectionKey.OP_READ); 

值得注意的是:服務端和客戶端的實現方式,可以是不同的。比如,服務端是NIO,客戶端可以是BIO,它們并沒有什么強制要求。

另外一個面試時候經常問到的事件就是OP_WRITE。我們上面提到過,這個事件是表示寫就緒的,當底層的緩沖區有空閑,這個事件就會一直發生,浪費占用CPU資源。所以,我們一般是不注冊OP_WRITE的。

這里還有一個細節,在讀取數據的時候,并沒有像BIO的方式一樣使用循環來獲取數據。如下面的代碼,我們創建了一個1024字節的緩沖區,用于數據的讀取。如果連接中的數據,大于1024字節怎么辦?

  1. SocketChannel sc = (SocketChannel) event.channel(); 
  2. ByteBuffer buf = ByteBuffer.allocate(1024); 
  3. int size = sc.read(buf); 

這涉及到兩種事件的通知機制。

  • 水平觸發 (level-triggered) 稱作LT模式。只要緩沖區有數據,事件就會一直發生
  • 邊緣觸發 (edge-triggered) 稱作ET模式。緩沖區有數據,僅會觸發一次。事件想要再次觸發,必須先將fd中的數據讀完才行

可以看到,Java的NIO采用的就是水平觸發的方式。LT模式頻繁環喚醒線程,效率相比較ET模式低,所以Netty使用JNI的方式,實現了ET模式,效率上更高一些。

3.Reactor模式

了解了BIO和NIO的一些使用方式,Reactor模式就呼之欲出了。

NIO是基于事件機制的,有一個叫做Selector的選擇器,阻塞獲取關注的事件列表。獲取到事件列表后,可以通過分發器,進行真正的數據操作。

上圖是Doug Lea在講解NIO時候的一張圖,指明了最簡單的Reactor模型的基本元素。你可以對比這上面的NIO代碼分析一下,里面有四個主要元素:

  • Acceptor 處理client的連接,并綁定具體的事件處理器
  • Event 具體發生的事件
  • Handler 執行具體事件的處理者。比如處理讀寫事件
  • Reactor 將具體的事件分配給Handler

我們可以對上面的模型進行近一步細化,下面這張圖同樣是Doug Lea的ppt中的。它把Reactor部分分為mainReactor和subReactor兩部分。mainReactor負責監聽處理新的連接,然后將后續的事件處理交給subReactor,subReactor對事件處理的方式,也由阻塞模式變成了多線程處理,引入了任務隊列的模式。

熟悉Netty的同學可以看到,這個模型就是Netty設計的基礎。在Netty中,Boss線程對應著對連接的處理和分派,相當于mainReactor;Work線程 對應著subReactor,使用多線程負責讀寫事件的分發和處理。

這種模式將每個組件的職責分的更細,耦合度也更低,能有效的解決C10k問題。

4.AIO

關于NIO的概念,誤解還是比較多的。面試官可能會問你:為什么我在使用NIO的時候,使用Channel進行讀寫,socket的操作依然是阻塞的?NIO主要體現在哪里?

  1. //這行代碼是阻塞的 
  2. int size = sc.read(buf); 

答案就是,NIO只負責對發生在fd描述符上的事件進行通知。事件的獲取和通知部分是非阻塞的,但收到通知之后的操作,卻是阻塞的。即使使用多線程去處理這些事件,它依然是阻塞的。

AIO更近一步,將這些對事件的操作也變成非阻塞的。下面是一段典型的AIO代碼,它通過注冊CompletionHandler 回調函數進行事件處理。這里的事件是隱藏的,比如read函數,它不僅僅代表Channel可讀了,而且會把數據自動的讀取到ByteBuffer中。等完成了讀取,就會通過回調函數通知你,進行后續的操作。

  1. public class AIO { 
  2.     public static void main(String[] args) throws Exception { 
  3.         int port = 8888; 
  4.         AsynchronousServerSocketChannel ssc = AsynchronousServerSocketChannel.open(); 
  5.         ssc.bind(new InetSocketAddress("localhost", port)); 
  6.         ssc.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() { 
  7.             void job(final AsynchronousSocketChannel sc) { 
  8.                 ByteBuffer buffer = ByteBuffer.allocate(1024); 
  9.                 sc.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() { 
  10.                     @Override 
  11.                     public void completed(Integer result, ByteBuffer attachment) { 
  12.                         String str = new String(attachment.array()).trim(); 
  13.                         ByteBuffer wrap = ByteBuffer.wrap(("PONG:" + str).getBytes()); 
  14.                         sc.write(wrap, null, new CompletionHandler<Integer, Object>() { 
  15.                             @Override 
  16.                             public void completed(Integer result, Object attachment) { 
  17.                                 job(sc); 
  18.                             } 
  19.                             @Override 
  20.                             public void failed(Throwable exc, Object attachment) { 
  21.                                 System.out.println("error"); 
  22.                             } 
  23.                         }); 
  24.                     } 
  25.                     @Override 
  26.                     public void failed(Throwable exc, ByteBuffer attachment) { 
  27.                         System.out.println("error"); 
  28.                     } 
  29.                 }); 
  30.             } 
  31.             @Override 
  32.             public void completed(AsynchronousSocketChannel sc, Object attachment) { 
  33.                 ssc.accept(null, this); 
  34.                 job(sc); 
  35.             } 
  36.             @Override 
  37.             public void failed(Throwable exc, Object attachment) { 
  38.                 exc.printStackTrace(); 
  39.                 System.out.println("error"); 
  40.             } 
  41.         }); 
  42.         Thread.sleep(Integer.MAX_VALUE); 
  43.     } 

AIO是Java1.7加入的,理論上性能是會提升的,但它現在發展的不太好。那部分對數據進行自動讀取的操作,總得有地方實現,不在框架里,就得在內核里。Netty的NIO模型加上多線程處理,在這方面已經做的很好,編程模式也非常簡單。所以,市面上對AIO的實踐并不多,在采用技術選型的時候,一定要謹慎。

5.響應式編程

你可能聽說過Spring5的webflux,webflux是可以替代spring mvc的一套解決方案,可以編寫響應式的應用,兩者之間的關系可以看下圖。它的底層使用的是netty,所以操作是異步非阻塞的。類似的組件還有vert.x、akka、rxjava等。

webflux是運行在project reactor之上的一個封裝,其根本特性是由后者提供的。至于再底層的非阻塞模型,就是由Netty保證的了。

非阻塞的特性我們可以理解,響應式又是什么概念呢?

響應式編程是一種面向數據流和變化傳播的編程范式。這意味著可以在編程語言中很方便地表達靜態或動態的數據流,而相關的計算模型會自動將變化的值通過數據流進行傳播。

這段話很晦澀,在編程方面,它表達的意思是:把生產者消費者模式,使用簡單的API表示出來,并自動處理背壓(backpressure)問題。

背壓,指的是生產者與消費者之間的流量控制。通過將操作全面異步化,來減少無效的等待和資源消耗。

Java的lambda表達式可以承擔簡單這個職責,Java9更是引入了響應式流(Reactive Stream),方便了我們的操作。比如,下面是Spring Cloud GateWay的Fluent API寫法,響應式編程的API都是類似的。

  1. public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) { 
  2.         return builder.routes() 
  3.                 .route(r -> r.path("/market/**"
  4.                         .filters(f -> f.filter(new RequestTimeFilter()) 
  5.                                 .addResponseHeader("X-Response-Default-Foo""Default-Bar")) 
  6.                         .uri("http://localhost:8080/market/list"
  7.                         .order(0) 
  8.                         .id("customer_filter_router"
  9.                 ) 
  10.                 .build(); 
  11.     } 

從傳統的開發模式過渡到reactor的開發模式,是有一定成本的,不過它確實能夠提高我們應用程序的性能。具體用不用,就要看在編程難度和性能之間的取舍了。

小結

從上面的描述,我們了解到,BIO的線程模型是一個連接對應一個線程的,非常的浪費資源;NIO通過對關鍵事件的監聽,通過主動通知的方式完成非阻塞操作,但它對事件本身的處理依然是非阻塞的;AIO完全是異步非阻塞的,但現實中使用很少。

使用Netty的多Acceptor模式和多線程模式,我們能夠方便的完成類似AIO這樣的操作。Netty的事件觸發機制使用了高效的ET模式,使得支持的連接更多,性能更高。

使用Netty,能夠構建響應式編程的基礎,加上類似lambda表達式這樣的書寫風格,能夠完成類似WebFlux這樣的響應式框架。響應式編程是一個趨勢,現在有越來越多的框架和底層的數據庫支持響應式編程,我們的應用響應也會更加迅速。

 

作者簡介:小姐姐味道 (xjjdog),一個不允許程序員走彎路的公眾號。聚焦基礎架構和Linux。十年架構,日百億流量,與你探討高并發世界,給你不一樣的味道。

 

責任編輯:武曉燕 來源: 小姐姐味道
相關推薦

2023-04-06 09:42:00

LispHTMLQwit

2022-06-16 13:08:30

Combine響應式編程訂閱

2022-04-16 16:52:24

Netty網絡服務器客戶端程序

2020-04-16 15:20:43

PHP前端BIO

2023-12-20 14:44:33

軟件開發DevOpsNoOps

2016-11-28 16:23:23

戴爾

2021-06-11 17:26:06

代碼Java網絡編程

2020-10-10 19:37:27

BIO 、NIO 、A

2011-05-25 14:59:35

if elseswitch case

2023-07-11 08:40:02

IO模型后臺

2020-05-17 13:59:37

物聯網工業物聯網工業4.0

2019-10-18 08:22:43

BIONIOAIO

2025-08-29 08:28:13

2022-09-01 08:00:00

響應式編程集成

2020-08-13 17:18:20

Kubernetes邊緣容器

2019-04-11 15:45:08

ReactMixin前端

2013-04-08 17:13:14

2017-09-12 15:26:44

2021-01-25 05:38:04

設計原理VueSubject

2023-06-26 07:39:10

點贊
收藏

51CTO技術棧公眾號

亚洲乱码av中文一区二区| 亚洲国产视频直播| 成人亚洲激情网| 久久国产精品波多野结衣| 欧美人与动xxxxz0oz| 欧美在线免费观看亚洲| 四虎精品欧美一区二区免费| 污污视频在线观看网站| 青青草97国产精品免费观看无弹窗版 | 国产精品宾馆| 欧美午夜精品理论片a级按摩| 69精品丰满人妻无码视频a片| 日本成人一区| 国产在线精品一区二区夜色| 57pao国产精品一区| 最新一区二区三区| 九九综合九九| 精品久久国产老人久久综合| 手机看片福利盒子久久| av成人福利| 亚洲天堂2014| 亚洲v欧美v另类v综合v日韩v| 天天干天天操av| 国产精品亚洲一区二区三区在线| 国产成人在线精品| 日韩 欧美 中文| 欧美精品一卡| 久久精品91久久久久久再现| 人妻少妇无码精品视频区| 国产精品网址| 日韩欧美国产一区二区三区| 日日干夜夜操s8| av有声小说一区二区三区| 亚洲成av人综合在线观看| 中文字幕在线乱| eeuss影院www在线观看| 久久久无码精品亚洲日韩按摩| 国产欧美日韩一区二区三区| 亚洲精品视频专区| 国产精品一区在线观看乱码 | 成人午夜三级| 欧美成人激情免费网| 一本之道在线视频| 999精品嫩草久久久久久99| 欧美亚洲综合色| 欧美伦理片在线看| 国产私拍福利精品视频二区| 色悠久久久久综合欧美99| 91精品国产高清自在线看超| 亚洲第一综合网站| www在线免费观看| 国产亚洲综合在线| 日韩理论片在线观看| 美州a亚洲一视本频v色道| 久久欧美一区二区| 日本精品视频一区| 香蕉视频免费在线播放| 国产精品国产a级| 日韩西西人体444www| 国产精品视频xxxx| 性色av一区二区三区四区| 三级成人在线视频| 国产精品第10页| 伊人成年综合网| 日本欧美一区二区| 成人激情黄色网| 国产人妖一区二区三区| 国产成人自拍高清视频在线免费播放| 99在线影院| 无码精品视频一区二区三区 | 国产精品一区二区av| 香蕉久久国产av一区二区| 久久午夜色播影院免费高清 | 欧美日韩四区| 97精品伊人久久久大香线蕉 | 日韩三级中文字幕| 一边摸一边做爽的视频17国产 | 日韩精品在线免费播放| 国产一二三四五区| 香蕉av一区二区| 欧美激情中文网| 成年人视频在线免费看| 人人爽香蕉精品| 91久久国产自产拍夜夜嗨| 人妻无码中文字幕| 91麻豆精品一区二区三区| 日韩尤物视频| 大香伊人久久| 91成人免费电影| 中文字幕av一区二区三区人妻少妇| 国产精品久久久久久久久久白浆 | 久草精品电影| 在线观看二区| 亚洲一区二区三区四区中文字幕| 欧美污视频网站| 电影91久久久| 亚洲色图15p| 麻豆成人在线视频| 免费久久99精品国产| 99久久精品无码一区二区毛片 | 中文欧美字幕免费| 999一区二区三区| 日韩在线观看不卡| 亚洲第一免费网站| 美女网站视频色| 国产亚洲在线观看| 亚洲在线第一页| 国产黄色片在线播放| 亚洲黄一区二区三区| 99视频在线视频| 美国十次av导航亚洲入口| 久久国产一区二区三区| 香蕉污视频在线观看| 国产91丝袜在线播放0| 亚洲视频欧美在线| 黄色成人免费网| 精品国产99国产精品| 四虎影视一区二区| 久久综合九色| 久久av一区二区三区亚洲| bt在线麻豆视频| 欧美日韩亚州综合| 亚洲码无人客一区二区三区| 亚洲黄网站黄| 99国产超薄肉色丝袜交足的后果| 91激情在线| 色欧美片视频在线观看| 欧美做受喷浆在线观看| 激情综合中文娱乐网| 亚洲free嫩bbb| 久草免费在线观看| 欧美日韩国产精品自在自线| 亚洲韩国日本中文字幕| 美女又爽又黄视频毛茸茸| 极品尤物久久久av免费看| 91在线观看免费高清| 在线观看国产原创自拍视频| 欧美性大战xxxxx久久久| ass精品国模裸体欣赏pics| 亚洲国产电影| 国产在线精品一区二区中文| 91超碰在线| 精品第一国产综合精品aⅴ| 久热这里有精品| 国产精品综合二区| 性做爰过程免费播放| 国产精品66| 北条麻妃一区二区三区中文字幕| 一级欧美一级日韩| 日韩理论片一区二区| 一级黄色片在线免费观看| 91日韩欧美| 亚洲va国产va天堂va久久| 1024在线播放| 欧美xingq一区二区| 精品无码一区二区三区电影桃花 | 成人福利在线观看视频| 欧美一区午夜精品| 免费无遮挡无码永久在线观看视频 | 色乱码一区二区三区88| 极品蜜桃臀肥臀-x88av| 久久99精品国产麻豆婷婷洗澡| 一区二区三区四区五区视频| 91成人精品观看| 欧美精品久久一区二区| 亚洲av成人无码久久精品老人 | 日韩欧美大尺度| 美女爆乳18禁www久久久久久| 全国精品久久少妇| 中文字幕在线乱| 免费成人蒂法| 国产精品国产亚洲伊人久久 | 一区二区视频免费在线观看| 国产国语老龄妇女a片| 亚洲一区欧美二区| 亚洲精品久久久久久一区二区| 亚洲福利影视| 久久久人成影片一区二区三区观看| 欧洲天堂在线观看| 欧美二区三区的天堂| 国产亚洲欧美精品久久久久久| 91小视频在线| 国产女同无遮挡互慰高潮91| 狠狠干综合网| 日韩高清三级| 亚洲性视频在线| 国产成人中文字幕| 麻豆福利在线观看| 亚洲欧美中文字幕| av综合在线观看| 色天使色偷偷av一区二区| 久久国产波多野结衣| 99久久精品99国产精品| 亚洲xxx在线观看| 中文亚洲免费| 伊人再见免费在线观看高清版| 妖精一区二区三区精品视频| 91在线高清视频| 超薄肉色丝袜脚交一区二区| 97精品久久久中文字幕免费| 男人和女人做事情在线视频网站免费观看| 精品国产3级a| 91福利免费视频| 日韩欧美一区二区三区| 国产盗摄x88av| 日本一区二区动态图| 日本久久久久久久久久| 麻豆freexxxx性91精品| 日本在线观看a| 在线观看一区视频| 国产一二三四区在线观看| 成人羞羞网站入口免费| 麻豆av一区二区三区久久| 日韩高清在线观看一区二区| 国产精品女主播视频| 午夜影视一区二区三区| 欧美国产日韩一区| a天堂中文在线官网在线| 中文字幕国产精品久久| 久久天堂电影| 亚洲精品视频网上网址在线观看| www.97av.com| 欧美电影影音先锋| 一卡二卡三卡在线观看| 91黄色免费版| 4444kk亚洲人成电影在线| 户外露出一区二区三区| 欧美一级大片在线观看| ririsao久久精品一区| 欧美麻豆久久久久久中文| 麻豆网站在线看| 自拍偷拍亚洲欧美| 国产福利电影在线| 亚洲人成亚洲人成在线观看| 婷婷综合激情网| 精品福利av导航| 天堂中文在线观看视频| 精品国产免费视频| 亚洲第一第二区| 精品久久久久一区二区国产| 精品国产亚洲AV| 日韩精品影音先锋| 亚洲av综合色区无码一二三区 | 国产成人精品一区二区三区| 成人软件在线观看| 国产精品白嫩初高中害羞小美女| 欧美国产日韩电影| 国产一区视频在线播放| 国产一区二区三区| 亚洲精品欧美日韩专区| 中文在线综合| 国产在线视频欧美一区二区三区| 牛牛视频精品一区二区不卡| 欧美日韩一区综合| 欧美色图激情小说| 国产手机视频在线观看| 狠狠入ady亚洲精品| 黄色一级视频在线播放| 免费日韩一区二区| 动漫av免费观看| 麻豆精品久久精品色综合| 99精品999| 成人国产精品免费观看视频| 国产精品久久无码| 国产亚洲欧美色| 网站永久看片免费| 亚洲综合在线观看视频| 亚洲黄色三级视频| 欧美午夜一区二区三区| 国产精品嫩草影院桃色| 精品久久久久久无| 国产在线中文字幕| 欧美成年人视频网站| 超碰资源在线| 国产精品久久久久不卡| 精品国产伦一区二区三区观看说明 | 日韩国产一级片| 日本伊人精品一区二区三区观看方式| 小明看看成人免费视频| 岛国一区二区三区| 一道本在线观看| 亚洲综合色网站| 日韩欧美国产另类| 欧美一区二区福利视频| 你懂的在线播放| 欧美成人精品激情在线观看| 美女日韩欧美| 成人在线观看视频网站| 免费欧美激情| 亚洲五码在线观看视频| 视频一区二区欧美| 男人添女人荫蒂国产| 国产亚洲精品中文字幕| 欧美国产日韩综合| 欧美性生交片4| 国产成人无码www免费视频播放| 一本色道久久88亚洲综合88| 丁香花在线电影| 国产日韩精品一区二区| 亚洲国产网址| 成人在线视频一区二区三区| 人人精品人人爱| 特级西西人体wwwww| 亚洲天堂2016| 中文字幕91爱爱| 亚洲乱码一区av黑人高潮| 七七久久电影网| 成人在线视频福利| 自拍欧美一区| 久久精品视频16| 国产高清久久久久| 九九这里只有精品视频| 色哟哟一区二区| 天天躁日日躁狠狠躁伊人| 久久久精品久久久久| 成人国产精选| 欧洲精品亚洲精品| 亚洲一区二区免费看| 伊人影院在线观看视频| 亚洲欧美一区二区三区国产精品 | 免费毛片b在线观看| 91久久国产综合久久蜜月精品| 99久久久久| 蜜臀一区二区三区精品免费视频| 久久久精品一品道一区| 日韩av电影网| 精品国产91九色蝌蚪| 欧美男男video| ts人妖另类在线| 亚洲一级淫片| 亚洲三级在线视频| 国产女人aaa级久久久级| 国产一区免费看| 一区二区在线视频| 国产精品高清乱码在线观看 | 女人色偷偷aa久久天堂| 国产xxxxhd| 一区二区三区小说| 国产免费黄色片| 欧美区二区三区| 999国产精品一区| 成人午夜视频在线观看免费| 成人性生交大片免费看中文| 国产无套粉嫩白浆内谢| 成人性视频免费网站| 亚洲国产日韩欧美| 日韩精品福利网| 貂蝉被到爽流白浆在线观看| 精品视频免费看| 黄色免费在线看| 亚洲mm色国产网站| 国产综合网站| 伦理片一区二区| 欧美性xxxx极品高清hd直播| 久草在现在线| 国产又爽又黄的激情精品视频| 国产高清一区| 最新国产精品自拍| 第一福利永久视频精品| 欧美男男同志| 国产日韩精品视频| 欧美片第1页综合| 艳妇乳肉亭妇荡乳av| 日本韩国欧美一区| 日本中文字幕电影在线免费观看 | 8090成年在线看片午夜| 一本久久青青| 午夜啪啪小视频| 亚洲国产精品自拍| 久草在线网址| 亚洲www在线| 免费亚洲一区| 日本不卡一二区| 亚洲激情视频在线观看| yy6080久久伦理一区二区| 三级在线免费观看| 久久青草欧美一区二区三区| 在线观看xxxx| 久久免费少妇高潮久久精品99| 久久av电影| 中文字幕在线视频一区二区| 精品人伦一区二区三区蜜桃网站 | 久久久久亚洲精品成人网小说| 综合亚洲色图| 红桃视频一区二区三区免费| 五月激情六月综合| 久操视频在线观看| 农村寡妇一区二区三区| 国产一区二区三区精品欧美日韩一区二区三区 | 国内精品久久久久影院一蜜桃| 日韩美女黄色片| 日韩在线欧美在线国产在线| 精品久久国产一区| 老司机午夜av| 亚洲国产成人av好男人在线观看| 岛国在线视频免费看| 国产区欧美区日韩区| 久久狠狠亚洲综合| 特级毛片www| 欧美日韩国产第一页|