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

宜人貸蜂巢API網關技術解密之Netty使用實踐

企業動態
本文先簡要地介紹API網關的項目框架,其次對比BIO和NIO的特點,引入Netty作為項目的基礎框架,然后介紹Netty線程池的原理,最后深入Netty線程池的初始化、ServerBootstrap的初始化與啟動及channel與線程池的綁定過程,讓讀者了解Netty在承載高并發訪問的設計路思。

宜人貸蜂巢團隊,由Michael創立于2013年,通過使用互聯網科技手段助力金融生態和諧健康發展。自成立起一直致力于多維度數據閉環平臺建設。目前團隊規模超過百人,涵蓋征信、電商、金融、社交、五險一金和保險等用戶授信數據的抓取解析業務,輔以先進的數據分析、挖掘和機器學習等技術對用戶信用級別、欺詐風險進行預測評定,全面對外輸出金融反欺詐、社交圖譜、自動化模型定制等服務或產品。

目前宜人貸蜂巢基于用戶授權數據實時抓取解析技術,并結合***大數據技術,快速迭代和自主的創新,已形成了強大而領先的聚合和輸出能力。

為了適應完成宜人貸蜂巢強大的服務輸出能力,蜂巢設計開發了自己的API網關系統,集中實現了鑒權、加解密、路由、限流等功能,使各業務抓取團隊關注其核心抓取和分析工作,而API網關系統更專注于安全、流量、路由等問題,從而更好的保障蜂巢服務系統的質量。今天帶著大家解密API網關的Netty線程池技術實踐細節。

API網關作為宜人貸蜂巢數據開放平臺的統一入口,所有的客戶端及消費端通過統一的API來使用各類抓取服務。從面向對象設計的角度看,它與外觀模式類似,包裝各類不同的實現細節,對外表現出統一的調用形式。

本文首先,簡要地介紹API網關的項目框架,其次對比BIO和NIO的特點,再引入Netty作為項目的基礎框架,然后介紹Netty線程池的原理,***深入Netty線程池的初始化、ServerBootstrap的初始化與啟動及channel與線程池的綁定過程,讓讀者了解Netty在承載高并發訪問的設計思路。

一、項目框架

API網關項目框架

圖1 - API網關項目框架

圖中描繪了API網關系統的處理流程,以及與服務注冊發現、日志分析、報警系統、各類爬蟲的關系。其中API網關系統接收請求,對請求進行編解碼、鑒權、限流、加解密,再基于Eureka服務注冊發現模塊,將請求發送到有效的服務節點上;網關及抓取系統的日志,會被收集到elk平臺中,做業務分析及報警處理。

二、BIO vs NIO

API網關承載數倍于爬蟲的流量,提升服務器的并發處理能力、縮短系統的響應時間,通信模型的選擇是至關重要的,是選擇BIO,還是NIO?

1. Streamvs Buffer & 阻塞 vs 非阻塞

BIO是面向流的,io的讀寫,每次只能處理一個或者多個bytes,如果數據沒有讀寫完成,線程將一直等待于此,而不能暫時跳過io或者等待io讀寫完成異步通知,線程滯留在io讀寫上,不能充分利用機器有限的線程資源,造成server的吞吐量較低,見圖2。而NIO與此不同,面向Buffer,線程不需要滯留在io讀寫上,采用操作系統的epoll模式,在io數據準備好了,才由線程來處理,見圖3。

 BIO 從流中讀取數據

圖2 – BIO 從流中讀取數據

圖3 – NIO 從Buffer中讀取數據

2. Selectors

NIO的selector使一個線程可以監控多個channel的讀寫,多個channel注冊到一個selector上,這個selector可以監測到各個channel的數據準備情況,從而使用有限的線程資源處理更多的連接,見圖4。所以可以這樣說,NIO極大的提升了服務器接受并發請求的能力,而服務器性能還是要取決于業務處理時間和業務線程池模型。

NIO 單一線程管理多個連接

圖4 – NIO 單一線程管理多個連接

而BIO采用的是request-per-thread模式,用一個線程負責接收TCP連接請求,并建立鏈路,然后將請求dispatch給負責業務邏輯處理的線程,見圖5。一旦訪問量過多,就會造成機器的線程資源緊張,造成請求延遲,甚至服務宕機。

圖5 – BIO 一連接一線程

對比JDK NIO與諸多NIO框架后,鑒于Netty優雅的設計、易用的API、優越的性能、安全性支持、API網關使用Netty作為通信模型,實現了基礎框架的搭建。

三、線程池

考慮到API網關的高并發訪問需求,線程池設計,見圖6。

圖6 – API網關線程池設計

Netty的線程池理念有點像ForkJoinPool,不是一個線程大池子并發等待一條任務隊列,而是每條線程都有一個任務隊列。而且Netty的線程,并不只是簡單的阻塞地拉取任務,而是在每個循環中做三件事情:

  • 先SelectKeys()處理NIO的事件
  • 然后獲取本線程的定時任務,放到本線程的任務隊列里
  • ***執行其他線程提交給本線程的任務

每個循環里處理NIO事件與其他任務的時間消耗比例,還能通過ioRatio變量來控制,默認是各占50%。可見,Netty的線程根本沒有阻塞等待任務的清閑日子,所以也不使用有鎖的BlockingQueue來做任務隊列了,而是使用無鎖的MpscLinkedQueue(Mpsc 是Multiple Producer, Single Consumer的縮寫)。

四、NioEventLoopGroup初始化

下面分析下Netty線程池NioEventLoopGroup的設計與實現細節,NioEventLoopGroup的類層次關系見圖7:

NioEvenrLoopGroup類層次關系

圖7 –NioEvenrLoopGroup類層次關系

其創建過程——方法調用,見下圖:

NioEvenrLoopGroup創建調用關系

圖8 –NioEvenrLoopGroup創建調用關系

NioEvenrLoopGroup的創建,具體執行過程是執行類MultithreadEventExecutorGroup的構造方法:

  1. /**  
  2.  * Create a new instance.  
  3.  *  
  4.  * @param nThreads          the number of threads that will be used by this instance.  
  5.  * @param executor          the Executor to use, or {@code null} if the default should be used.  
  6.  * @param chooserFactory    the {@link EventExecutorChooserFactory} to use.  
  7.  * @param args              arguments which will passed to each {@link #newChild(Executor, Object...)} call  
  8.  */  
  9. protected MultithreadEventExecutorGroup(int nThreads, Executor executor,  
  10.                                         EventExecutorChooserFactory chooserFactory, Object... args) {  
  11.     if (nThreads <= 0) {  
  12.         throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));  
  13.     }  
  14.     if (executor == null) {  
  15.         executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());  
  16.     }  
  17.     children = new EventExecutor[nThreads];  
  18.     for (int i = 0; i < nThreads; i ++) {  
  19.         boolean success = false;  
  20.         try {  
  21.             children[i] = newChild(executor, args);  
  22.             success = true;  
  23.         } catch (Exception e) {   
  24.             throw new IllegalStateException("failed to create a child event loop", e);  
  25.         } finally {  
  26.             if (!success) {  
  27.                 for (int j = 0; j < i; j ++) {  
  28.                     children[j].shutdownGracefully();  
  29.                 }  
  30.                 for (int j = 0; j < i; j ++) { 
  31.                      EventExecutor e = children[j]; 
  32.                      try { 
  33.                          while (!e.isTerminated()) {  
  34.                             e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);  
  35.                         }  
  36.                     } catch (InterruptedException interrupted) {  
  37.                         // Let the caller handle the interruption.  
  38.                         Thread.currentThread().interrupt();  
  39.                         break;  
  40.                     }  
  41.                 }  
  42.             }  
  43.         }  
  44.     }  
  45.     chooser = chooserFactory.newChooser(children);  
  46.     final FutureListener<Object> terminationListener = new FutureListener<Object>() {  
  47.         @Override  
  48.         public void operationComplete(Future<Object> future) throws Exception {  
  49.             if (terminatedChildren.incrementAndGet() == children.length) {  
  50.                 terminationFuture.setSuccess(null);  
  51.             }  
  52.         }  
  53.     };  
  54.     for (EventExecutor e: children) {  
  55.         e.terminationFuture().addListener(terminationListener);  
  56.     }  
  57.     Set<EventExecutor> childrenSet = new LinkedHashSet<EventExecutor>(children.length);  
  58.     Collections.addAll(childrenSet, children);  
  59.     readonlyChildren = Collections.unmodifiableSet(childrenSet);  

其中,創建細節見下:

  • 線程池中的線程數nThreads必須大于0;
  • 如果executor為null,創建默認executor,executor用于創建線程(newChild方法使用executor對象);
  • 依次創建線程池中的每一個線程即NioEventLoop,如果其中有一個創建失敗,將關閉之前創建的所有線程;
  • chooser為線程池選擇器,用來選擇下一個EventExecutor,可以理解為,用來選擇一個線程來執行task。

chooser的創建細節,見下:

DefaultEventExecutorChooserFactory根據線程數創建具體的EventExecutorChooser,線程數如果等于2^n,可使用按位與替代取模運算,節省cpu的計算資源,見源碼:

  1. @SuppressWarnings("unchecked")  
  2. @Override  
  3. public EventExecutorChooser newChooser(EventExecutor[] executors) {  
  4.     if (isPowerOfTwo(executors.length)) {  
  5.         return new PowerOfTowEventExecutorChooser(executors);  
  6.     } else {  
  7.         return new GenericEventExecutorChooser(executors);  
  8.     }  
  9. }   
  10.     private static final class PowerOfTowEventExecutorChooser implements EventExecutorChooser {  
  11.         private final AtomicInteger idx = new AtomicInteger();  
  12.         private final EventExecutor[] executors;   
  13.  
  14.         PowerOfTowEventExecutorChooser(EventExecutor[] executors) {  
  15.             this.executors = executors;  
  16.         }   
  17.  
  18.         @Override  
  19.         public EventExecutor next() {  
  20.             return executors[idx.getAndIncrement() & executors.length - 1];  
  21.         }  
  22.     }   
  23.  
  24.     private static final class GenericEventExecutorChooser implements EventExecutorChooser {  
  25.         private final AtomicInteger idx = new AtomicInteger();  
  26.         private final EventExecutor[] executors;   
  27.  
  28.         GenericEventExecutorChooser(EventExecutor[] executors) {  
  29.             this.executors = executors;  
  30.         }   
  31.  
  32.         @Override  
  33.         public EventExecutor next() {  
  34.             return executors[Math.abs(idx.getAndIncrement() % executors.length)];  
  35.         }  
  36.     } 

newChild(executor, args)的創建細節,見下:

MultithreadEventExecutorGroup的newChild方法是一個抽象方法,故使用NioEventLoopGroup的newChild方法,即調用NioEventLoop的構造函數:

  1. @Override  
  2.     protected EventLoop newChild(Executor executor, Object... args) throws Exception {  
  3.         return new NioEventLoop(this, executor, (SelectorProvider) args[0], 
  4.             ((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);  
  5.     } 

在這里先看下NioEventLoop的類層次關系:

NioEventLoop的繼承關系比較復雜,在AbstractScheduledEventExecutor 中,Netty 實現了 NioEventLoop 的 schedule 功能,即我們可以通過調用一個 NioEventLoop 實例的 schedule 方法來運行一些定時任務。而在 SingleThreadEventLoop 中,又實現了任務隊列的功能,通過它,我們可以調用一個NioEventLoop 實例的 execute 方法來向任務隊列中添加一個 task, 并由 NioEventLoop 進行調度執行。

通常來說,NioEventLoop 肩負著兩種任務,***個是作為 IO 線程,執行與 Channel 相關的 IO 操作,包括調用 select 等待就緒的 IO 事件、讀寫數據與數據的處理等;而第二個任務是作為任務隊列,執行 taskQueue 中的任務,例如用戶調用 eventLoop.schedule 提交的定時任務也是這個線程執行的。

具體的構造過程,見下:

創建任務隊列tailTasks(內部為有界的LinkedBlockingQueue):

創建線程的任務隊列taskQueue(內部為有界的LinkedBlockingQueue),以及任務過多防止系統宕機的拒絕策略rejectedHandler。

其中tailTasks和taskQueue均是任務隊列,而優先級不同,taskQueue的優先級高于tailTasks,定時任務的優先級高于taskQueue。

五、ServerBootstrap初始化及啟動

了解了Netty線程池NioEvenrLoopGroup的創建過程后,下面看下API網關服務ServerBootstrap的是如何使用線程池引入服務中,為高并發訪問服務的。

API網關ServerBootstrap初始化及啟動代碼,見下:

  1. serverBootstrap = new ServerBootstrap();  
  2. bossGroup = new NioEventLoopGroup(config.getBossGroupThreads());  
  3. workerGroup = new NioEventLoopGroup(config.getWorkerGroupThreads());   
  4.  
  5. serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)  
  6.         .option(ChannelOption.TCP_NODELAY, config.isTcpNoDelay())  
  7.         .option(ChannelOption.SO_BACKLOG, config.getBacklogSize())  
  8.         .option(ChannelOption.SO_KEEPALIVE, config.isSoKeepAlive())  
  9.         // Memory pooled  
  10.         .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)  
  11.         .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)  
  12.         .childHandler(channelInitializer);    
  13.  
  14. ChannelFuture future = serverBootstrap.bind(config.getPort()).sync();  
  15. log.info("API-gateway started on port: {}", config.getPort());  
  16. future.channel().closeFuture().sync(); 

API網關系統使用netty自帶的線程池,共有三組線程池,分別為bossGroup、workerGroup和executorGroup(使用在channelInitializer中,本文暫不作介紹)。其中,bossGroup用于接收客戶端的TCP連接,workerGroup用于處理I/O、執行系統task和定時任務,executorGroup用于處理網關業務加解密、限流、路由,及將請求轉發給后端的抓取服務等業務操作。

六、Channel與線程池的綁定

ServerBootstrap初始化后,通過調用bind(port)方法啟動Server,bind的調用鏈如下:

  1. AbstractBootstrap.bind ->AbstractBootstrap.doBind -> AbstractBootstrap.initAndRegister 

其中,ChannelFuture regFuture = config().group().register(channel);中的group()方法返回bossGroup,而channel在serverBootstrap的初始化過程指定channel為NioServerSocketChannel.class,至此將NioServerSocketChannel與bossGroup綁定到一起,bossGroup負責客戶端連接的建立。那么NioSocketChannel是如何與workerGroup綁定到一起的?

調用鏈AbstractBootstrap.initAndRegister -> AbstractBootstrap. init-> ServerBootstrap.init ->ServerBootstrapAcceptor.ServerBootstrapAcceptor ->ServerBootstrapAcceptor.channelRead:

  1. public void channelRead(ChannelHandlerContext ctx, Object msg) {  
  2.     final Channel child = (Channel) msg;  
  3.     child.pipeline().addLast(childHandler);  
  4.     for (Entry<ChannelOption<?>, Object> e: childOptions) {  
  5.         try {  
  6.             if (!child.config().setOption((ChannelOption<Object>) e.getKey(), e.getValue())) {  
  7.                 logger.warn("Unknown channel option: " + e);  
  8.             }  
  9.         } catch (Throwable t) {  
  10.             logger.warn("Failed to set a channel option: " + child, t); 
  11.         }  
  12.     }  
  13.     for (Entry<AttributeKey<?>, Object> e: childAttrs) {  
  14.         child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());  
  15.     } 
  16.  
  17.     try {  
  18.         childGroup.register(child).addListener(new ChannelFutureListener() {  
  19.             @Override  
  20.             public void operationComplete(ChannelFuture future) throws Exception {  
  21.                 if (!future.isSuccess()) { 
  22.                      forceClose(child, future.cause());  
  23.                 }  
  24.             }  
  25.         });  
  26.     } catch (Throwable t) {  
  27.         forceClose(child, t);  
  28.     }  

其中,childGroup.register(child)就是將NioSocketChannel與workderGroup綁定到一起,那又是什么觸發了ServerBootstrapAcceptor的channelRead方法?

其實當一個 client 連接到 server 時,Java 底層的 NIO ServerSocketChannel 會有一個SelectionKey.OP_ACCEPT 就緒事件,接著就會調用到 NioServerSocketChannel.doReadMessages方法。

  1. @Override  
  2. protected int doReadMessages(List<Object> buf) throws Exception {  
  3.     SocketChannel ch = javaChannel().accept();  
  4.     try {  
  5.         if (ch != null) {  
  6.             buf.add(new NioSocketChannel(this, ch));  
  7.             return 1;  
  8.         }  
  9.     } catch (Throwable t) {          … 
  10.  
  11.     }  
  12.     return 0;  

javaChannel().accept() 會獲取到客戶端新連接的SocketChannel,實例化為一個 NioSocketChannel, 并且傳入 NioServerSocketChannel 對象(即 this),由此可知, 我們創建的這個NioSocketChannel 的父 Channel 就是 NioServerSocketChannel 實例 。

接下來就經由 Netty 的 ChannelPipeline 機制,將讀取事件逐級發送到各個 handler 中,于是就會觸發前面我們提到的 ServerBootstrapAcceptor.channelRead 方法啦。

至此,分析了Netty線程池的初始化、ServerBootstrap的啟動及channel與線程池的綁定過程,能夠看出Netty中線程池的優雅設計,使用不同的線程池負責連接的建立、IO讀寫等,為API網關項目的高并發訪問提供了技術基礎。

七、總結

至此,對API網關技術的Netty實踐分享就到這里,各位如果對中間的各個環節有什么疑問和建議,歡迎大家指正,我們一起討論,共同學習提高。

參考:

  • http://tutorials.jenkov.com/java-nio/nio-vs-io.html
  • http://netty.io/wiki/user-guide-for-4.x.html
  • http://netty.io/
  • http://www.tuicool.com/articles/mUFnqeM
  • https://segmentfault.com/a/1190000007403873
  • https://segmentfault.com/a/1190000007283053

 【本文是51CTO專欄機構宜信技術學院的原創文章,微信公眾號“宜信技術學院( id: CE_TECH)”】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2019-04-18 22:40:42

蜂巢機器人金融機器人

2017-03-28 19:46:36

外設

2024-09-03 13:59:37

2017-06-19 11:05:44

互聯網

2023-08-09 20:43:32

2023-06-26 18:13:56

開源API

2022-08-22 08:40:42

API網關開發

2017-03-13 14:09:19

RESTful API實踐

2015-11-02 14:17:59

IoT蜂巢式

2017-04-19 14:20:09

宜人貸

2020-04-22 09:00:00

REST API參數化前端

2023-06-26 10:51:56

開源API

2017-04-25 10:57:16

宜人貸

2023-09-07 10:56:36

2019-06-13 13:51:10

白山API大數據

2014-04-18 10:58:44

AndroidAPI實踐

2014-08-05 15:10:05

Larbin搜索引擎

2014-08-13 11:04:02

搜索引擎排序算法

2020-07-16 08:06:53

網關高性能

2022-12-26 00:38:00

外聯網關平臺
點贊
收藏

51CTO技術棧公眾號

古装做爰无遮挡三级聊斋艳谭| 日韩欧美99| 日本黄色片视频| 亚洲裸色大胆大尺寸艺术写真| 色成人在线视频| 一区二区三区不卡在线| 亚洲精品字幕在线| 天堂va蜜桃一区二区三区| 视频在线一区二区| 四季av综合网站| 亚洲男人在线| 欧美日韩激情小视频| 亚洲欧美精品在线观看| 可以免费看毛片的网站| 蜜桃视频在线观看一区| 久久久久久久久久久网站| 成人小视频免费看| 国产精品色呦| 欧美高清视频一二三区 | 国产综合自拍| 中文字幕精品国产| 女同毛片一区二区三区| 香蕉成人app| 欧美午夜一区二区三区| a级黄色一级片| 91在线中文| 中文欧美字幕免费| 久久亚洲免费| 肥臀熟女一区二区三区| 久久精品99国产精品| 668精品在线视频| 九九视频免费看| 午夜激情久久| 综合136福利视频在线| 精品影片一区二区入口| 日韩激情综合| 欧美一区午夜视频在线观看| wwwwww.色| 欧美电影网址| 色综合网站在线| 男女高潮又爽又黄又无遮挡| 国产探花在线观看| 一区二区三区中文免费| 亚洲欧美一二三| 最近高清中文在线字幕在线观看| 国产亚洲一区二区在线观看| 精品综合久久久| 日韩中文字幕免费观看| 国产91在线|亚洲| 国产高清不卡av| 亚洲精品一区二区三区蜜桃| 国产精品一区二区在线观看网站 | 青青视频在线播放| 欧美a级在线观看| 性感美女极品91精品| 黄色片网址在线观看| 波多一区二区| 精品电影在线观看| 国自产拍偷拍精品啪啪一区二区| 2020av在线| 精品免费在线视频| 97xxxxx| 91精品论坛| 在线看日韩精品电影| 爆乳熟妇一区二区三区霸乳| 欧美freesex| 在线观看视频欧美| 色一情一区二区| 精品一区二区三区中文字幕视频| 日韩亚洲欧美成人一区| 国产精九九网站漫画| aaa国产精品| 亚洲美女在线看| 亚洲精品成人无码| 久久福利综合| 欧美大秀在线观看| 欧美三级韩国三级日本三斤在线观看| 亚洲专区在线| 国产在线一区二区三区| 亚洲免费国产视频| 久久精品水蜜桃av综合天堂| 亚洲一卡二卡三卡| 国产99re66在线视频| 欧美视频13p| 久久99爱视频| 无码国模国产在线观看| 亚洲欧美变态国产另类| 国产日产在线观看| 伊人精品视频| 国产精品高清网站| 精品人妻一区二区三区含羞草 | 污污视频在线看| 五月天国产精品| 国产一伦一伦一伦| 风间由美性色一区二区三区四区| 亚洲美女激情视频| 欧美片一区二区| 日韩成人av影视| 91手机在线视频| 国产污视频在线| 亚洲国产婷婷综合在线精品| 国产精品天天av精麻传媒| 国产精品日本一区二区不卡视频| 日韩激情片免费| 亚洲色偷偷综合亚洲av伊人| 香蕉成人久久| 99久热re在线精品996热视频| 国产高清在线看| 一区二区三区丝袜| 一级在线免费视频| 牛牛影视一区二区三区免费看| 中文字幕日韩欧美在线| 西西44rtwww国产精品| 激情六月婷婷综合| 日本不卡二区高清三区| av福利导福航大全在线| 欧美裸体一区二区三区| 精品成人av一区二区三区| 欧美三级不卡| 国产日韩精品电影| 国产原创av在线| 欧美日韩免费看| 黑人无套内谢中国美女| 99久久夜色精品国产亚洲96 | 成人激情久久| 尤物九九久久国产精品的分类| 免费在线观看黄网站| 国产一区二区美女诱惑| 日韩国产在线一区| 日韩电影av| 亚洲精品视频播放| 精品成人久久久| 丁香网亚洲国际| 日韩不卡视频一区二区| 99热这里有精品| 日韩网站在线观看| 中文字幕精品在线观看| 日本一区二区动态图| 97在线播放视频| 久久av免费| 欧美在线视频在线播放完整版免费观看| 亚洲美女福利视频| 一区二区三区成人| 69久久精品无码一区二区 | 久久这里有精品视频| 中文字幕无码乱码人妻日韩精品| 久久久久久99精品| 亚洲国产精品毛片av不卡在线| 日韩在线黄色| 欧美在线视频a| 免费在线黄色电影| 色老头久久综合| av永久免费观看| 免费一级片91| 三年中文高清在线观看第6集 | 午夜宅男久久久| 欧美主播一区二区三区美女 久久精品人 | 少妇一级淫免费放| 欧美成免费一区二区视频| 91精品久久久久久久久久另类| 男人在线资源站| 91精品国产福利| 精品视频在线观看免费| av中文一区二区三区| 91精品91久久久中77777老牛| 羞羞色国产精品网站| 国产999精品视频| av二区在线| 日韩欧美在线影院| 日本最新中文字幕| 久久免费看少妇高潮| 国产精品一区二区羞羞答答| 国产精品国内免费一区二区三区| 91精品在线影院| 17videosex性欧美| 亚洲三级免费看| 国产一区二区在线不卡| 亚洲高清不卡在线| 新91视频在线观看| 九色综合国产一区二区三区| 黄色一级大片免费| 亚洲va久久| 成人黄色在线播放| 国产拍在线视频| 国产一区二区三区在线看 | 日韩成人在线视频观看| 国产成人精品一区二区色戒| ㊣最新国产の精品bt伙计久久| 香蕉视频免费网站| 日本午夜一本久久久综合| 久久久99精品视频| 亚洲男人都懂第一日本| 成人黄色在线观看| 亚洲黄色中文字幕| 九九热这里只有在线精品视| 天堂网www中文在线| 欧美日韩国产成人在线91| 久久久无码一区二区三区| 久久久久久一二三区| wwwxxx色| 蜜臀精品一区二区三区在线观看 | a级大胆欧美人体大胆666| 亚洲视频在线观看免费| 国产成人精品毛片| 欧洲av在线精品| 国产精品16p| 国产精品福利影院| 中文幕无线码中文字蜜桃| 国产电影精品久久禁18| 久久久久久蜜桃一区二区| 日韩一级在线| 女人床在线观看| 日本激情一区| 欧美精品二区三区四区免费看视频 | 欧美日本一区二区| 51国产偷自视频区视频| 亚洲一区在线免费观看| 午夜激情视频在线播放| 久久在线免费观看| 扒开伸进免费视频| 国产一区二区三区国产| 国产九九在线视频| 亚洲综合精品四区| 六月婷婷在线视频| 永久91嫩草亚洲精品人人| 色综合影院在线观看| 亚洲精品推荐| 免费久久久一本精品久久区| 澳门成人av| 97久久人人超碰caoprom欧美 | 7777精品伊人久久久大香线蕉完整版 | 国产在线拍揄自揄拍| 亚洲蜜臀av乱码久久精品蜜桃| 亚欧精品视频一区二区三区| 中文字幕人妻精品一区| 国产精品久久三| 国产成人一区二区在线观看| 久久免费看少妇高潮| 人体私拍套图hdxxxx| 国产91精品精华液一区二区三区| 伊人五月天婷婷| 极品少妇一区二区| 中文 日韩 欧美| 国产剧情av麻豆香蕉精品| 国产永久免费网站| 另类成人小视频在线| 玖玖爱视频在线| 久草在线在线精品观看| 九九热精品在线播放| 麻豆精品一区二区三区| 国产原创精品在线| 久久99精品国产麻豆婷婷| 国产三级生活片| 精品一区二区三区蜜桃| 91pony九色| 国产精品一区二区黑丝 | av在线综合网| 亚洲图片综合网| www激情久久| 五月天精品视频| 亚洲欧美在线另类| 欧美日韩精品在线观看视频 | 国产精品天美传媒| 性欧美疯狂猛交69hd| 一区二区三区视频在线看| 国产第一页在线播放| 精品久久久久久久中文字幕 | 欧美一级网站| 国产又粗又长又大的视频| 狠狠v欧美v日韩v亚洲ⅴ| 中文字幕乱妇无码av在线| 波多野结衣中文字幕一区 | 茄子视频成人在线| 欧美另类激情| 99在线国产| 久久97视频| 7777在线视频| 亚洲精品九九| 国产精品久久久毛片| 国产黄色精品网站| 毛片网站免费观看| 成人免费小视频| 国产做受高潮漫动| 欧美三级电影一区| 刘亦菲毛片一区二区三区| 亚洲人成网站999久久久综合| 国产传媒在线播放| 2020欧美日韩在线视频| 日韩黄色碟片| 精品日产一区2区三区黄免费 | 91成人短视频| 欧美性大战久久久久| 欧美在线首页| 日韩精品一区二区三区色欲av| 精品亚洲aⅴ乱码一区二区三区| 国产精品一区二区在线免费观看| 久久久国产精华| 强乱中文字幕av一区乱码| 一本色道a无线码一区v| www国产一区| 色七七影院综合| 是的av在线| 99热最新在线| 国产精品久久久久久麻豆一区软件| 99热在线这里只有精品| 国产精品一区免费视频| 日韩福利在线视频| 欧美视频裸体精品| www香蕉视频| 日韩在线观看免费网站| 欧美激情20| 成人看片在线| 999精品在线| av无码精品一区二区三区| heyzo一本久久综合| 一区二区三区四区五区| 欧美日韩在线不卡| 可以在线观看的av网站| 97高清免费视频| 亚洲一区二区三区四区电影| 亚洲精品乱码久久久久久蜜桃91 | 国产亚洲色婷婷久久| 国产精品私人自拍| av片免费观看| 国产丝袜一区二区三区| h片在线观看| 国产精品自拍首页| 国产一区亚洲| 日本一二三四区视频| 中文字幕一区二区三区不卡在线 | 欧美美女日韩| 精品人伦一区二区三区| 日韩一级网站| 熟女人妻在线视频| 性感美女久久精品| 免费观看黄一级视频| 久久久久久国产精品美女| 亚洲开心激情| 日本男女交配视频| 国产成人啪免费观看软件 | 亚洲欧洲一区| 国产人妻黑人一区二区三区| 亚洲国产一区二区三区| 女人18毛片水真多18精品| 欧美国产极速在线| 风间由美一区二区av101| 丰满少妇大力进入| 不卡视频一二三| 在线免费黄色av| 亚洲网站在线观看| 国产极品嫩模在线观看91精品| 日韩欧美视频一区二区三区四区 | 午夜视频久久久久久| 日韩在线视频免费| 青青草精品毛片| 国内精品伊人久久久| 日本高清久久久| 亚洲欧美日本在线| 刘玥91精选国产在线观看| 欧美在线视频免费观看| 欧美日韩精品在线一区| 亚洲精品综合在线观看| 亚洲另类一区二区| 欧美一级在线免费观看| 欧洲永久精品大片ww免费漫画| 国产乱码精品一区二区亚洲| 国产三级国产精品国产专区50| 综合分类小说区另类春色亚洲小说欧美| aa视频在线免费观看| 国产69精品久久久久99| 一本久久青青| 国产无遮挡猛进猛出免费软件| 亚洲精选免费视频| 五月婷婷在线观看视频| 国产精品亚洲激情| 欧美三级乱码| 久久视频精品在线观看| 日韩免费视频线观看| 爱情电影社保片一区| 亚洲一区二区三区精品在线观看| 国产激情一区二区三区四区| 国产午夜免费福利| 日韩中文字幕在线播放| www国产精品| 黄色一级免费大片| 亚洲一区二区欧美日韩| 国产二区在线播放| 7777奇米亚洲综合久久| 国产精品久久国产愉拍| 精品手机在线视频| 亚洲电影在线观看| 欧美视频第一| 精品这里只有精品| 亚洲天堂成人网| 无码国产精品一区二区色情男同| 国产精品中文字幕在线| 日韩视频在线一区二区三区| 5566中文字幕| 亚洲欧洲日产国产网站| 日本一区二区三区电影免费观看 |