青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

路漫漫,長修遠,我們不能沒有錢
隨筆 - 173, 文章 - 0, 評論 - 257, 引用 - 0
數據加載中……

兩種高性能I/O設計模式(Reactor/Proactor)的比較

原文出處: Alex Libman   譯文出處:潘孫友



綜述

這篇文章探討并比較兩種用于TCP服務器的高性能設計模式。 除了介紹現有的解決方案,還提出了一種更具伸縮性,只需要維護一份代碼并且跨平臺的解決方案(含代碼示例),以及其在不同平臺上的微調。 此文還比較了java、c#、c++對各自現有以及提到的解決方案的實現性能。

系統I/O 可分為阻塞型, 非阻塞同步型以及非阻塞異步型[12]。 阻塞型I/O意味著控制權只到調用操作結束了才會回到調用者手里。 結果調用者被阻塞了, 這段時間了做不了任何其它事情。 更郁悶的是,在等待IO結果的時間里,調用者所在線程此時無法騰出手來去響應其它的請求,這真是太浪費資源了。拿read()操作來說吧, 調用此函數的代碼會一直僵在此處直至它所讀的socket緩存中有數據到來。

相比之下,非阻塞同步是會立即返回控制權給調用者的。調用者不需要等等,它從調用的函數獲取兩種結果:要么此次調用成功進行了;要么系統返回錯誤標識告訴調用者當前資源不可用,你再等等或者再試度看吧。比如read()操作, 如果當前socket無數據可讀,則立即返回EWOULBLOCK/EAGAIN,告訴調用read()者”數據還沒準備好,你稍后再試”。

在非阻塞異步調用中,稍有不同。調用函數在立即返回時,還告訴調用者,這次請求已經開始了。系統會使用另外的資源或者線程來完成這次調用操作,并在完成的時候知會調用者(比如通過回調函數)。拿Windows的ReadFile()或者POSIX的aio_read()來說,調用它之后,函數立即返回,操作系統在后臺同時開始讀操作。

在以上三種IO形式中,非阻塞異步是性能最高、伸縮性最好的。

這篇文章探討不同的I/O利用機制并提供一種跨平臺的設計模式(解決方案)。 希望此文可以給于TCP高性能服務器開發者一些幫助,選擇最佳的設計方案。下面我們會比較 Java、C#、 C++各自對探討方案的實現以及性能。 我們在文章的后面就不再提及阻塞式的方案了,因為阻塞式I/O實在是缺少可伸縮性,性能也達不到高性能服務器的要求。

兩種IO多路復用方案:Reactor and Proactor

一般情況下,I/O 復用機制需要事件分享器(event demultiplexor [13])。 事件分享器的作用,即將那些讀寫事件源分發給各讀寫事件的處理者,就像送快遞的在樓下喊: 誰的什么東西送了, 快來拿吧。開發人員在開始的時候需要在分享器那里注冊感興趣的事件,并提供相應的處理者(event handlers),或者是回調函數; 事件分享器在適當的時候會將請求的事件分發給這些handler或者回調函數。

涉及到事件分享器的兩種模式稱為:Reactor and Proactor [1]。 Reactor模式是基于同步I/O的,而Proactor模式是和異步I/O相關的。 在Reactor模式中,事件分離者等待某個事件或者可應用或個操作的狀態發生(比如文件描述符可讀寫,或者是socket可讀寫),事件分離者就把這個事件傳給事先注冊的事件處理函數或者回調函數,由后者來做實際的讀寫操作。

而在Proactor模式中,事件處理者(或者代由事件分離者發起)直接發起一個異步讀寫操作(相當于請求),而實際的工作是由操作系統來完成的。發起時,需要提供的參數包括用于存放讀到數據的緩存區,讀的數據大小,或者用于存放外發數據的緩存區,以及這個請求完后的回調函數等信息。事件分離者得知了這個請求,它默默等待這個請求的完成,然后轉發完成事件給相應的事件處理者或者回調。舉例來說,在Windows上事件處理者投遞了一個異步IO操作(稱有overlapped的技術),事件分離者等IOCompletion事件完成[1]。 這種異步模式的典型實現是基于操作系統底層異步API的,所以我們可稱之為“系統級別”的或者“真正意義上”的異步,因為具體的讀寫是由操作系統代勞的。

舉另外個例子來更好地理解Reactor與Proactor兩種模式的區別。這里我們只關注read操作,因為write操作也是差不多的。下面是Reactor的做法:

  • 某個事件處理者宣稱它對某個socket上的讀事件很感興趣;
  • 事件分離者等著這個事件的發生;
  • 當事件發生了,事件分離器被喚醒,這負責通知先前那個事件處理者;
  • 事件處理者收到消息,于是去那個socket上讀數據了。 如果需要,它再次宣稱對這個socket上的讀事件感興趣,一直重復上面的步驟;

下面再來看看真正意義的異步模式Proactor是如何做的:

  • 事件處理者直接投遞發一個寫操作(當然,操作系統必須支持這個異步操作)。 這個時候,事件處理者根本不關心讀事件,它只管發這么個請求,它魂牽夢縈的是這個寫操作的完成事件。這個處理者很拽,發個命令就不管具體的事情了,只等著別人(系統)幫他搞定的時候給他回個話。
  • 事件分離者等著這個讀事件的完成(比較下與Reactor的不同);
  • 當事件分離者默默等待完成事情到來的同時,操作系統已經在一邊開始干活了,它從目標讀取數據,放入用戶提供的緩存區中,最后通知事件分離者,這個事情我搞完了;
  • 事件分享者通知之前的事件處理者: 你吩咐的事情搞定了;
  • 事件處理者這時會發現想要讀的數據已經乖乖地放在他提供的緩存區中,想怎么處理都行了。如果有需要,事件處理者還像之前一樣發起另外一個寫操作,和上面的幾個步驟一樣。

現行做法

開源C++開發框架 ACE[13](Douglas Schmidt, et al.開發) 提供了大量平臺獨立的底層并發支持類(線程、互斥量等)。 同時在更高一層它也提供了獨立的幾組C++類,用于實現Reactor及Proactor模式。 盡管它們都是平臺獨立的單元,但他們都提供了不同的接口。

ACE Proactor在MS-Windows上無論是性能還在健壯性都更勝一籌,這主要是由于Windows提供了一系列高效的底層異步API。 [45]。

(這段可能過時了點吧) 不幸的是,并不是所有操作系統都為底層異步提供健壯的支持。舉例來說, 許多Unix系統就有麻煩。因此, ACE Reactor可能是Unix系統上更合適的解決方案。 正因為系統底層的支持力度不一,為了在各系統上有更好的性能,開發者不得不維護獨立的好幾份代碼: 為Windows準備的ACE Proactor以及為Unix系列提供的ACE Reactor。

就像我們提到過的,真正的異步模式需要操作系統級別的支持。由于事件處理者及操作系統交互的差異,為Reactor和Proactor設計一種通用統一的外部接口是非常困難的。這也是設計通行開發框架的難點所在。

更好的解決方案

在文章這一段時,我們將嘗試提供一種融合了Proactor和Reactor兩種模式的解決方案。 為了演示這個方案,我們將Reactor稍做調整,模擬成異步的Proactor模型(主要是在事件分離器里完成本該事件處理者做的實際讀寫工作,我們稱這種方法為”模擬異步“)。 下面的示例可以看看read操作是如何完成的:

  • 事件處理者宣稱對讀事件感興趣,并提供了用于存儲結果的緩存區、讀數據長度等參數;
  • 調試者等待(比如通過select());
  • 當有事件到來(即可讀),調試者被喚醒, 調試者去執行非阻塞的讀操作(前面事件處理者已經給了足夠的信息了)。讀完后,它去通知事件處理者。
  • 事件處理者這時被知會讀操作已完成,它擁有完整的原先想要獲取的數據了。

我們看到,通過為分離者(也就上面的調試者)添加一些功能,可以讓Reactor模式轉換為Proactor模式。所有這些被執行的操作,其實是和Reactor模型應用時完全一致的。我們只是把工作打散分配給不同的角色去完成而已。這樣并不會有額外的開銷,也不會有性能上的的損失,我們可以再仔細看看下面的兩個過程,他們實際上完成了一樣的事情:

標準的經典的 Reactor模式:

  • 步驟 1) 等待事件 (Reactor 的工作)
  • 步驟 2) 發”已經可讀”事件發給事先注冊的事件處理者或者回調 ( Reactor 要做的)
  • 步驟 3) 讀數據 (用戶代碼要做的)
  • 步驟 4) 處理數據 (用戶代碼要做的)

模擬的Proactor模式:

  • 步驟 1) 等待事件 (Proactor 的工作)
  • 步驟 2) 讀數據(看,這里變成成了讓 Proactor 做這個事情)
  • 步驟 3) 把數據已經準備好的消息給用戶處理函數,即事件處理者(Proactor 要做的)
  • 步驟 4) 處理數據 (用戶代碼要做的)

在沒有底層異步I/O API支持的操作系統,這種方法可以幫我們隱藏掉socket接口的差異(無論是性能還是其它), 提供一個完全可用的統一“異步接口”。這樣我們就可以開發真正平臺獨立的通用接口了。

TProactor

我們提出的TProactor方案已經由TerabitP/L [6]公司實現了。 它有兩種實現: C++的和Java的。C++版本使用了ACE平臺獨立的底層元件,最終在所有操作系統上提供了統一的異步接口。

TProactor中最重要的組件要數Engine和WaitStrategy了。 Engine用于維護異步操作的生命周期;而WaitStrategy用于管理并發策略。 WaitStrategy和Engine一般是成對出現的, 兩者間提供了良好的匹配接口。

Engines和等待策略被設計成高度可組合的(完整的實現列表請參照附錄1)。TProactor是高度可配置的方案,通過使用異步內核API和同步Unix API(select(), poll(), /dev/poll (Solaris 5.8+), port_get(Solaris 5.10),RealTime (RT) signals (Linux 2.4+), epoll (Linux 2.6), k-queue (FreeBSD) ),它內部實現了三種引擎(POSIX AIO, SUN AIO and Emulated AIO)并隱藏了六類等待策略。TProactor實現了和標準的 ACE Proactor一樣的接口。這樣一來,為不同平臺提供通用統一的只有一份代碼的跨平臺解決方案成為可能。

Engines和WaitStrategies可以像樂高積木一樣自由地組合,開發者可以在運行時通過配置參數來選擇合適的內部機制(引擎和等待策略)。可以根據需求設定配置,比如連接數,系統伸縮性,以及運行的操作系統等。如果系統支持相應的異步底層API,開發人員可以選擇真正的異步策略,否則用戶也可以選擇使用模擬出來的異步模式。所有這一切策略上的實現細節都不太需要關注,我們看到的是一個可用的異步模型。

舉例來說,對于運行在Sun Solaris上的HTTP服務器,如果需要支持大量的連接數,/dev/poll或者port_get()之類的引擎是比較合適的選擇;如果需要高吞吐量,那使用基本select()的引擎會更好。由于不同選擇策略內在算法的問題,像這樣的彈性選擇是標準ACE Reactor/Proactor模式所無法提供的(見附錄2)。

在性能方面,我們的測試顯示,模擬異步模式并未造成任何開銷,沒有變慢,反倒是性能有所提升。根據我們的測試結果,TProactor相較標簽的ACE Reactor在Unix/Linux系統上有大約10-35%性能提升,而在Windows上差不多(測試了吞吐量及響應時間)。

性能比較 (JAVA / C++ / C#).

除了C++,我們也在Java中實現了TProactor。 JDK1.4中, Java僅提供了同步方法, 像C中的select() [78]。 Java TProactor基于Java的非阻塞功能(java.nio包),類似于C++的TProactor使用了select()引擎。

圖1、2顯示了以 bits/sec為單位的傳輸速度以及相應的連接數。這些圖比較了以下三種方式實現的echo服務器:標準ACE Reactor實現(基于RedHat Linux9.0)、TProactor C++/Java實現(Microsoft Windows平臺及RedHat v9.0), 以及C#實現。測試的時候,三種服務器使用相同的客戶端瘋狂地連接,不間斷地發送固定大小的數據包。

這幾組測試是在相同的硬件上做的,在不同硬件上做的相對結果對比也是類似。



圖 1. Windows XP/P4 2.6GHz HyperThreading/512 MB RAM.




圖 2. Linux RedHat 2.4.20-smp/P4 2.6GHz HyperThreading/512 MB RAM.


用戶代碼示例

下面是TProactor Java實現的echo服務器代碼框架。總的來說,開發者只需要實現兩個接口:一是OpRead,提供存放讀結果的緩存;二是OpWrite,提供存儲待寫數據的緩存區。同時,開發者需要通過回調onReadComplated()和onWriteCompleted()實現協議相關的業務代碼。這些回調會在合適的時候被調用。


 1 class EchoServerProtocol implements AsynchHandler
 2 {
 3  
 4   AsynchChannel achannel = null;
 5  
 6   EchoServerProtocol( Demultiplexor m,  SelectableChannel channel ) 
 7   throws Exception
 8   {
 9     this.achannel = new AsynchChannel( m, this, channel );
10   }
11  
12   public void start() throws Exception
13   {
14     
15 // called after construction
16     System.out.println( Thread.currentThread().getName() + 
17     ": EchoServer protocol started" );
18     achannel.read( buffer);
19   }
20  
21   public void onReadCompleted( OpRead opRead ) throws Exception
22   {
23     if ( opRead.getError() != null )
24     {
25       
26 // handle error, do clean-up if needed
27       System.out.println( "EchoServer::readCompleted: " + 
28       opRead.getError().toString());
29       achannel.close();
30       return;
31     }
32  
33     if ( opRead.getBytesCompleted () <= 0)
34     {
35       System.out.println("EchoServer::readCompleted: Peer closed "
36        + opRead.getBytesCompleted();
37       achannel.close();
38       return;
39     }
40  
41     ByteBuffer buffer = opRead.getBuffer();
42  
43     achannel.write(buffer);
44   }
45  
46   public void onWriteCompleted(OpWrite opWrite) 
47   throws Exception
48   {
49     
50 // logically similar to onReadCompleted
51     
52   }
53 }


IO多路復用模型有兩種Proactor與Reactor,兩者的區別主要在于IO是同步還是異步。

Proactor比Reactor更高效。

下面是兩種模式的請求處理過程:

處理過程

Proactor

  1. client創建要進行的操作,并注冊操作完成時的回調處理函數
  2. 操作(opration)交由操作系統底層進行處理
  3. 處理完成后底層將操作結果和回調函數傳給Proactor調度器
  4. Proactor調度器進行分發事件,調用具體的回調處理函數。

Reactor

  1. 對事件進行注冊處理函數。
  2. client的請求觸發底層的事件。
  3. Reactor調度器檢查事件發生,執行注冊的處理函數。

區別和聯系

區別

在實現中,Proactor是發出異步IO請求,交由操作系統完成IO請求,然后回調自己。

而Reactor是查詢操作系統,發生事件的時候,自己再對操作系統同步IO請求,完成后再回調注冊的處理函數。

因此二者的區別在于IO請求是OS來做,還是應用層來做,即異步與同步IO。

異步IO在windows上比較成熟,支持完善和高效,而在Linux等Unix系列操作系統上支持的不是很好,所以大多以Reactor模式為主。

聯系

涉及到高效IO框架都使用了IO多路復用與基于事件的方式,來將請求的處理過程“交叉化”,并行化,異步化,同時盡量的使用底層OS提供的支持功能來達到高效。





結束語


TProactor為多個平臺提供了一個通用、彈性、可配置的高性能通訊組件,所有那些在附錄2中提到的問題都被很好地隱藏在內部實現中了。

從上面的圖中我們可以看出C++仍舊是編寫高性能服務器最佳選擇,雖然Java已緊隨其后。然而因為Java本身實現上的問題,其在Windows上表現不佳(這已經應該成為歷史了吧)。

需要注意的是,以上針對Java的測試,都是以裸數據的形式測試的,未涉及到數據的處理(影響性能)。

縱觀AIO在Linux上的快速發展[9], 我們可以預計Linux內核API將會提供大量更加強健的異步API, 如此一來以后基于此而實現的新的Engine/等待策略將能輕松地解決能用性方面的問題,并且這也能讓標準ACE Proactor接口受益。

附錄 I

TProactor中實現的Engines 和 等待策略

引擎類型等待策略操作系統
POSIX_AIO (true async)
aio_read()/aio_write()
aio_suspend()
Waiting for RT signal
Callback function
POSIX complained UNIX (not robust)
POSIX (not robust)
SGI IRIX, LINUX (not robust)
SUN_AIO (true async)
aio_read()/aio_write()
aio_wait() SUN (not robust)
Emulated Async
Non-blockingread()/write()
select()
poll()
/dev/poll
Linux RT signals
Kqueue
generic POSIX
Mostly all POSIX implementations
SUN
Linux
FreeBSD

附錄 II

所有同步等待策略可劃分為兩組:

  • edge-triggered (e.g. Linux實時信號) – signal readiness only when socket became ready (changes state);
  • level-triggered (e.g. select()poll(), /dev/poll) – readiness at any time.

讓我們看看這兩組的一些普遍的邏輯問題:

  • edge-triggered group: after executing I/O operation, the demultiplexing loop can lose the state of socket readiness. Example: the “read” handler did not read whole chunk of data, so the socket remains still ready for read. But the demultiplexor loop will not receive next notification.
  • level-triggered group: when demultiplexor loop detects readiness, it starts the write/read user defined handler. But before the start, it should remove socket descriptior from theset of monitored descriptors. Otherwise, the same event can be dispatched twice.
  • Obviously, solving these problems adds extra complexities to development. All these problems were resolved internally within TProactor and the developer should not worry about those details, while in the synch approach one needs to apply extra effort to resolve them.

資源

[1] Douglas C. Schmidt, Stephen D. Huston “C++ Network Programming.” 2002, Addison-Wesley ISBN 0-201-60464-7

[2] W. Richard Stevens “UNIX Network Programming” vol. 1 and 2, 1999, Prentice Hill, ISBN 0-13- 490012-X

[3] Douglas C. Schmidt, Michael Stal, Hans Rohnert, Frank Buschmann “Pattern-Oriented Software Architecture: Patterns for Concurrent and Networked Objects, Volume 2″ Wiley & Sons, NY 2000

[4] INFO: Socket Overlapped I/O Versus Blocking/Non-blocking Mode. Q181611. Microsoft Knowledge Base Articles.

[5] Microsoft MSDN. I/O Completion Ports.
http://msdn.microsoft.com/library/default.asp?url=/library/en- us/fileio/fs/i_o_completion_ports.asp

[6] TProactor (ACE compatible Proactor).
www.terabit.com.au

[7] JavaDoc java.nio.channels
http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/package-summary.html

[8] JavaDoc Java.nio.channels.spi Class SelectorProvider
http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/spi/SelectorProvider.html

[9] Linux AIO development
http://lse.sourceforge.net/io/aio.html, and
http://archive.linuxsymposium.org/ols2003/Proceedings/All-Reprints/Reprint-Pulavarty-OLS2003.pdf

更多

Ian Barile “I/O Multiplexing & Scalable Socket Servers”, 2004 February, DDJ

Further reading on event handling
- http://www.cs.wustl.edu/~schmidt/ACE-papers.html

The Adaptive Communication Environment
http://www.cs.wustl.edu/~schmidt/ACE.html

Terabit Solutions
http://terabit.com.au/solutions.php

關于作者

Alex Libman has been programming for 15 years. During the past 5 years his main area of interest is pattern-oriented multiplatform networked programming using C++ and Java. He is big fan and contributor of ACE.

Vlad Gilbourd works as a computer consultant, but wishes to spend more time listening jazz :) As a hobby,he started and runs www.corporatenews.com.au website.


參考材料



posted on 2015-07-09 11:00 Khan 閱讀(862) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美大色视频| 亚洲日本成人在线观看| 欧美激情亚洲激情| 国产日韩久久| 99视频一区二区| 亚洲精品欧美极品| 久久精品欧洲| 午夜一级久久| 欧美久久久久久久久| 欧美ab在线视频| 红杏aⅴ成人免费视频| 亚洲一本视频| 午夜亚洲伦理| 国产精品久久夜| 日韩一级视频免费观看在线| 日韩视频在线你懂得| 久久综合给合| 欧美1级日本1级| 精品动漫3d一区二区三区| 性亚洲最疯狂xxxx高清| 欧美一区二区女人| 国产精品一区毛片| 亚洲欧美国产三级| 午夜精品久久| 国产精品无码永久免费888| 中文日韩电影网站| 午夜精品久久久久久| 国产精品久久久久7777婷婷| 一本色道久久综合亚洲精品高清| 亚洲私人影吧| 国产精品私人影院| 欧美一级淫片aaaaaaa视频| 久久成人免费| 一区免费观看视频| 欧美成人福利视频| 夜夜嗨一区二区| 亚洲自拍偷拍色片视频| 国产精品视频999| 久久国产免费| 欧美激情一二三区| 亚洲一区二区三区四区五区午夜 | 午夜精品久久久久久久99樱桃 | 国产九区一区在线| 亚洲欧美久久久久一区二区三区| 欧美一级二区| 黄色影院成人| 欧美a级片一区| 99精品久久免费看蜜臀剧情介绍| 午夜伦理片一区| 精品动漫3d一区二区三区| 另类专区欧美制服同性| 亚洲人成在线观看网站高清| 中文亚洲欧美| 国产一区二区三区视频在线观看 | 亚洲性图久久| 国产色产综合产在线视频| 久久久国产精品一区| 亚洲日本va午夜在线影院| 亚洲女人小视频在线观看| 国产亚洲精品bt天堂精选| 麻豆成人在线播放| 在线亚洲欧美| 欧美v日韩v国产v| 亚洲主播在线观看| 在线不卡中文字幕播放| 欧美日韩国产探花| 久久精视频免费在线久久完整在线看| 亚洲激情av在线| 欧美一区二视频| 99精品热视频| 黄色成人av在线| 国产精品精品视频| 美女视频网站黄色亚洲| 亚洲色在线视频| 亚洲第一区在线| 欧美一区二区免费| 一本到12不卡视频在线dvd| 黑人中文字幕一区二区三区| 欧美日韩日本国产亚洲在线| 久久手机免费观看| 在线亚洲成人| 亚洲精品日韩久久| 男女激情视频一区| 久久精品99国产精品酒店日本| 亚洲美女精品成人在线视频| 激情综合色综合久久综合| 欧美日韩一区二| 男女精品视频| 久久精品一本久久99精品| 亚洲一区二区三区在线| 最新高清无码专区| 欧美夫妇交换俱乐部在线观看| 香蕉久久夜色精品国产| 亚洲视频在线视频| 99国产精品视频免费观看| 亚洲二区精品| 伊人成人网在线看| 国产日韩综合| 国产日韩欧美一区二区三区在线观看| 欧美日韩在线一区二区三区| 欧美黄色视屏| 欧美日本精品一区二区三区| 欧美破处大片在线视频| 欧美国产欧美亚洲国产日韩mv天天看完整 | 一区二区高清视频| 日韩午夜高潮| 亚洲免费观看视频| 亚洲精品一区在线观看香蕉| 亚洲黑丝一区二区| 亚洲国产三级在线| 亚洲黄色高清| 日韩视频一区二区| 夜夜嗨av一区二区三区四季av | 国产综合一区二区| 国产一区二区三区av电影 | 欧美一区二区精品久久911| 亚洲在线观看| 欧美一二三区精品| 欧美影视一区| 久久久久亚洲综合| 久色成人在线| 亚洲国产cao| 99伊人成综合| 午夜一区不卡| 久久久水蜜桃| 欧美激情影院| 国产精品乱码人人做人人爱| 国产亚洲视频在线| 亚洲国产精品激情在线观看| 亚洲免费大片| 亚洲欧美国产精品专区久久| 久久久91精品| 亚洲国产成人精品久久久国产成人一区| 亚洲韩国青草视频| 一区二区三区日韩精品视频| 欧美在线观看一区| 欧美激情综合色| 国产精品欧美风情| 樱桃国产成人精品视频| 99精品视频一区| 欧美在线黄色| 欧美激情一二三区| 亚洲一区二区成人| 另类成人小视频在线| 欧美午夜精品久久久久久超碰| 国产性做久久久久久| 亚洲精品日韩一| 久久xxxx| 亚洲人成小说网站色在线| 香蕉尹人综合在线观看| 欧美风情在线观看| 国产精品一区二区三区成人| 亚洲国产欧美不卡在线观看| 欧美亚洲综合另类| 亚洲国产天堂久久国产91| 午夜在线电影亚洲一区| 欧美激情精品久久久久久大尺度 | 亚洲看片免费| 久久精品视频在线| 妖精视频成人观看www| 久久久噜噜噜久久| 国产精品久久久久毛片软件| 亚洲黄色免费网站| 久久精品视频99| 国产精品99久久99久久久二8| 久久亚洲精品一区二区| 国产欧美不卡| 亚洲一区二区免费在线| 欧美国产视频一区二区| 午夜精品网站| 国产精品美女久久久久aⅴ国产馆| 91久久久久| 免费看亚洲片| 久久精品国产久精国产思思| 国产精品日韩欧美大师| 中文成人激情娱乐网| 亚洲高清资源| 美国三级日本三级久久99| 国内精品一区二区三区| 午夜激情久久久| 99视频精品免费观看| 欧美乱人伦中文字幕在线| 91久久黄色| 欧美激情精品久久久| 久久久久久9999| 伊人精品视频| 美女日韩在线中文字幕| 久久成人精品无人区| 国产综合一区二区| 久久久精品性| 欧美一区2区视频在线观看| 国产精品一二一区| 欧美一区二区三区视频在线观看| 亚洲新中文字幕| 国产精品区一区二区三区| 午夜精品视频网站| 午夜精品福利一区二区蜜股av| 国产精品综合网站| 欧美中文字幕不卡| 欧美一区高清|