久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Flux、Mono、Reactor 实战(史上最全)

發布時間:2023/12/18 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Flux、Mono、Reactor 实战(史上最全) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章很長,建議收藏起來慢慢讀! 瘋狂創客圈 總目錄 為您奉上珍貴的學習資源 :

  • 免費贈送 經典圖書:《Java高并發核心編程(卷1)》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領

  • 免費贈送 經典圖書:《Java高并發核心編程(卷2)》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領

  • 免費贈送 經典圖書:《Netty Zookeeper Redis 高并發實戰》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領

  • 免費贈送 經典圖書:《SpringCloud Nginx高并發核心編程》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領

  • 免費贈送 資源寶庫: Java 必備 百度網盤資源大合集 價值>10000元 加尼恩領取


前言

響應式編程用的是越來越多,尤其是在移動端 安卓的應用上邊。

在Java后臺服務開發中, 響應式編程用的不是太廣泛,主要原因是, 響應式編程需要一個完整的生態, 包括數據庫、緩存、中間件,都需要配套的響應式組件。 但是這點,其實很多并沒有。

但是,隨著 SpringCloud Gateway 的火爆, 響應式編程又變成了 不可回避, 不得不去學習的技術。

如果要做 SpringCloud Gateway 的開發, 就必須掌握一些響應式編程的知識。 由于最近在做 spring cloud gateway相關的開發工作, 所以:

把響應式編程Flux 和 Mono 的知識梳理一下,形成了此文

并且,此文會不斷完善。

姊妹篇:關于 SpringCloud Gateway 簡介

SpringCloud Gateway 是 Spring Cloud 的一個全新項目,該項目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技術開發的網關,它旨在為微服務架構提供一種簡單有效的統一的 API 路由管理方式。

SpringCloud Gateway 作為 Spring Cloud 生態系統中的網關,目標是替代 Zuul,在Spring Cloud 2.0以上版本中,沒有對新版本的Zuul 2.0以上最新高性能版本進行集成,仍然還是使用的Zuul 2.0之前的非Reactor模式的老版本。而為了提升網關的性能,SpringCloud Gateway是基于WebFlux框架實現的,而WebFlux框架底層則使用了高性能的Reactor模式通信框架Netty。

Spring Cloud Gateway 的目標,不僅提供統一的路由方式,并且基于 Filter 鏈的方式提供了網關基本的功能,例如:安全,監控/指標,和限流。

有關 Spring Cloud Gateway 響應式編程的實戰, 具體請參考本文姊妹篇:

《SpringCloud gateway (史上最全))》

特別說明

Spring Cloud Gateway 底層使用了高性能的通信框架Netty。

Netty 是高性能中間件的通訊底座, rocketmq 、seata、nacos 、sentinel 、redission 、dubbo 等太多、太多的的大名鼎鼎的中間件,無一例外都是基于netty。

可以毫不夸張的說: netty 是進入大廠、走向高端 的必備技能

要想深入了解springcloud gateway ,最好是掌握netty 編程

有關 netty學習 具體請參見機工社出版 、尼恩的暢銷書: 《Java高并發核心編程卷 1

響應式編程概述

背景知識

為了應對高并發服務器端開發場景,在2009 年,微軟提出了一個更優雅地實現異步編程的方式——Reactive Programming,我們稱之為響應式編程。隨后,Netflix 和LightBend 公司提供了RxJava 和Akka Stream 等技術,使得Java 平臺也有了能夠實現響應式編程的框架。

在2017 年9 月28 日,Spring 5 正式發布。Spring 5 發布最大的意義在于,它將響應式編程技術的普及向前推進了一大步。而同時,作為在背后支持Spring 5 響應式編程的框架Spring Reactor,也進入了里程碑式的3.1.0 版本。

什么是響應式編程

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

響應式編程基于reactor(Reactor 是一個運行在 Java8 之上的響應式框架)的思想,當你做一個帶有一定延遲的才能夠返回的io操作時,不會阻塞,而是立刻返回一個流,并且訂閱這個流,當這個流上產生了返回數據,可以立刻得到通知并調用回調函數處理數據。

電子表格程序就是響應式編程的一個例子。單元格可以包含字面值或類似"=B1+C1"的公式,而包含公式的單元格的值會依據其他單元格的值的變化而變化。

響應式傳播核心特點之一:變化傳播:一個單元格變化之后,會像多米諾骨牌一樣,導致直接和間接引用它的其他單元格均發生相應變化。

基于Java8實現觀察者模式

Observable類:此類表示可觀察對象,或模型視圖范例中的“數據”。

它可以被子類實現以表示應用程序想要觀察的對象。

//想要觀察的對象 ObserverDemo public class ObserverDemo extends Observable {public static void main(String[] args) {ObserverDemo observerDemo = new ObserverDemo();//添加觀察者observerDemo.addObserver((o,arg)->{System.out.println("數據發生變化A");});observerDemo.addObserver((o,arg)->{System.out.println("數據發生變化B");});observerDemo.setChanged();//將此Observable對象標記為已更改observerDemo.notifyObservers();//如果該對象發生了變化,則通知其所有觀察者} }

啟動程序測試:

創建一個Observable

rxjava中,可以使用Observable.create() 該方法接收一個Obsubscribe對象

Observable<Integer> observable = Observable.create(new Observable.OnSubscribe<Integer>() {@Overridepublic void call(Subscriber<? super Integer> subscriber) {}});

來個例子:

Observable<Integer> observable=Observable.create(new Observable.OnSubscribe<Integer>() {@Overridepublic void call(Subscriber<? super Integer> subscriber) {for(int i=0;i<5;i++){subscriber.onNext(i);}subscriber.onCompleted();}});//Observable.subscribe(Observer),Observer訂閱了ObservableSubscription subscribe = observable.subscribe(new Observer<Integer>() {@Overridepublic void onCompleted() {Log.e(TAG, "完成");}@Overridepublic void onError(Throwable e) {Log.e(TAG, "異常");}@Overridepublic void onNext(Integer integer) {Log.e(TAG, "接收Obsverable中發射的值:" + integer);}});輸出:接收Obsverable中發射的值:0 接收Obsverable中發射的值:1 接收Obsverable中發射的值:2 接收Obsverable中發射的值:3 接收Obsverable中發射的值:4

從上面的例子可以看出,在Observer訂閱了Observable后,

Observer作為OnSubscribe中call方法的參數傳入,從而調用了Observer的相關方法

基于 Reactor 實現

Reactor 是一個運行在 Java8 之上滿足 Reactice 規范的響應式框架,它提供了一組響應式風格的 API。

Reactor 有兩個核心類: Flux<T> 和 Mono<T>,這兩個類都實現 Publisher 接口。

  • Flux 類似 RxJava 的 Observable,它可以觸發零到多個事件,并根據實際情況結束處理或觸發錯誤。
  • Mono 最多只觸發一個事件,所以可以把 Mono 用于在異步任務完成時發出通知。

Flux 和 Mono 都是數據流的發布者,使用 Flux 和 Mono 都可以發出三種數據信號:元素值,錯誤信號,完成信號;錯誤信號和完成信號都代表終止信號,終止信號用于告訴訂閱者數據流結束了,錯誤信號終止數據流同時把錯誤信息傳遞給訂閱者。

三種信號的特點:

  • 錯誤信號和完成信號都是終止信號,不能共存
  • 如果沒有發送任何元素值,而是直接發送錯誤或者完成信號,表示是空數據流
  • 如果沒有錯誤信號,也沒有完成信號,表示是無限數據流

引入依賴

<dependency><groupId>org.projectreactor</groupId><artifactId>reactor-core</artifactId><version>1.1.6.RELEASE</version></dependency>

just 和 subscribe方法

just():創建Flux序列,并聲明指定數據流

subscribe():訂閱Flux序列,只有進行訂閱后才回觸發數據流,不訂閱就什么都不會發生

public class TestReactor {public static void main(String[] args) {//just():創建Flux序列,并聲明數據流,Flux<Integer> integerFlux = Flux.just(1, 2, 3, 4);//整形//subscribe():訂閱Flux序列,只有進行訂閱后才回觸發數據流,不訂閱就什么都不會發生integerFlux.subscribe(System.out::println);Flux<String> stringFlux = Flux.just("hello", "world");//字符串stringFlux.subscribe(System.out::println);//fromArray(),fromIterable()和fromStream():可以從一個數組、Iterable 對象或Stream 對象中創建Flux序列Integer[] array = {1,2,3,4};Flux.fromArray(array).subscribe(System.out::println);List<Integer> integers = Arrays.asList(array);Flux.fromIterable(integers).subscribe(System.out::println);Stream<Integer> stream = integers.stream();Flux.fromStream(stream).subscribe(System.out::println);} }

啟動測試:

響應流的特點

要搞清楚這兩個概念,必須說一下響應流規范。它是響應式編程的基石。他具有以下特點:

  • 響應流必須是無阻塞的。

  • 響應流必須是一個數據流。

  • 它必須可以異步執行。

  • 并且它也應該能夠處理背壓。

  • 即時響應性: 只要有可能, 系統就會及時地做出響應。 即時響應是可用性和實用性的基石, 而更加重要的是,即時響應意味著可以快速地檢測到問題并且有效地對其進行處理。 即時響應的系統專注于提供快速而一致的響應時間, 確立可靠的反饋上限, 以提供一致的服務質量。 這種一致的行為轉而將簡化錯誤處理、 建立最終用戶的信任并促使用戶與系統作進一步的互動。

  • **回彈性:**系統在出現失敗時依然保持即時響應性。 這不僅適用于高可用的、 任務關鍵型系統——任何不具備回彈性的系統都將會在發生失敗之后丟失即時響應性。 回彈性是通過復制、 遏制、 隔離以及委托來實現的。 失敗的擴散被遏制在了每個組件內部, 與其他組件相互隔離, 從而確保系統某部分的失敗不會危及整個系統,并能獨立恢復。 每個組件的恢復都被委托給了另一個(外部的)組件, 此外,在必要時可以通過復制來保證高可用性。 (因此)組件的客戶端不再承擔組件失敗的處理。

  • 彈性: 系統在不斷變化的工作負載之下依然保持即時響應性。 反應式系統可以對輸入(負載)的速率變化做出反應,比如通過增加或者減少被分配用于服務這些輸入(負載)的資源。 這意味著設計上并沒有爭用點和中央瓶頸, 得以進行組件的分片或者復制, 并在它們之間分布輸入(負載)。 通過提供相關的實時性能指標, 反應式系統能支持預測式以及反應式的伸縮算法。 這些系統可以在常規的硬件以及軟件平臺上實現成本高效的彈性。

  • **消息驅動:**反應式系統依賴異步的消息傳遞,從而確保了松耦合、隔離、位置透明的組件之間有著明確邊界。 這一邊界還提供了將失敗作為消息委托出去的手段。 使用顯式的消息傳遞,可以通過在系統中塑造并監視消息流隊列, 并在必要時應用回壓, 從而實現負載管理、 彈性以及流量控制。 使用位置透明的消息傳遞作為通信的手段, 使得跨集群或者在單個主機中使用相同的結構成分和語義來管理失敗成為了可能。 非阻塞的通信使得接收者可以只在活動時才消耗資源, 從而減少系統開銷。

Publisher/Flux和Mono

由于響應流的特點,我們不能再返回一個簡單的POJO對象來表示結果了。必須返回一個類似Java中的Future的概念,在有結果可用時通知消費者進行消費響應。

Reactive Stream規范中這種被定義為Publisher

Publisher是一個可以提供0-N個序列元素的提供者,并根據其訂閱者Subscriber<? super T>的需求推送元素。

一個Publisher可以支持多個訂閱者,并可以根據訂閱者的邏輯進行推送序列元素。

下面這個Excel計算就能說明一些Publisher的特點。

A1-A9就可以看做Publisher及其提供的元素序列。

A10-A13分別是求和函數SUM(A1:A9)、平均函數AVERAGE(A1:A9)、最大值函數MAX(A1:A9)、最小值函數MIN(A1:A9),

A10-A13可以看作訂閱者Subscriber。

假如說我們沒有A10-A13,那么A1-A9就沒有實際意義,它們并不產生計算。

這也是響應式的一個重要特點:當沒有訂閱時發布者什么也不做。而Flux和Mono都是Publisher在Reactor 3實現。

Publisher提供了subscribe方法,允許消費者在有結果可用時進行消費。

如果沒有消費者Publisher不會做任何事情,他根據消費情況進行響應。

Publisher可能返回零或者多個,甚至可能是無限的,為了更加清晰表示期待的結果就引入了兩個實現模型Mono和Flux。

Flux

Flux 是一個發出(emit)0-N個元素組成的異步序列的Publisher,可以被onComplete信號或者onError信號所終止。

在響應流規范中存在三種給下游消費者調用的方法 onNext, onComplete, 和onError。下面這張圖表示了Flux的抽象模型:

以上的的講解對于初次接觸反應式編程的依然是難以理解的,所以這里有一個循序漸進的理解過程。

有些類比并不是很妥當,但是對于你循序漸進的理解這些新概念還是有幫助的。

傳統數據處理

我們在平常是這么寫的:

public List<ClientUser> allUsers() {return Arrays.asList(new ClientUser("felord.cn", "reactive"),new ClientUser("Felordcn", "Reactor")); }

我們通過迭代返回值List來get這些元素進行再處理(消費),不管有沒有消費者, 菜品都會生產出來。

流式數據處理

Java 8中我們可以改寫為流的表示:

public Stream<ClientUser> allUsers() {return Stream.of(new ClientUser("felord.cn", "reactive"),new ClientUser("Felordcn", "Reactor")); }

反應式數據處理

Reactor中我們又可以改寫為Flux表示:

public Flux<ClientUser> allUsers(){return Flux.just(new ClientUser("felord.cn", "reactive"),new ClientUser("Felordcn", "Reactor")); }

這時候食客來了,發生了訂閱,廚師才開始做。

Flux 的創建Demo

Flux ints = Flux.range(1, 4); Flux seq1 = Flux.just("bole1", "bole2", "bole3"); List iterable = Arrays.asList("bole_01", "bole_02", "bole_03"); Flux seq2 = Flux.fromIterable(iterable); seq2.subscribe(i -> System.out.println(i));

Mono

Mono 是一個發出(emit)0-1個元素的Publisher,可以被onComplete信號或者onError信號所終止。

mono 整體和Flux差不多,只不過這里只會發出0-1個元素。也就是說不是有就是沒有。

象Flux一樣,我們來看看Mono的演化過程以幫助理解。

傳統數據處理

public ClientUser currentUser () {return isAuthenticated ? new ClientUser("felord.cn", "reactive") : null; }

直接返回符合條件的對象或者null`。

Optional的處理方式

public Optional<ClientUser> currentUser () {return isAuthenticated ? Optional.of(new ClientUser("felord.cn", "reactive")): Optional.empty(); }

這個Optional我覺得就有反應式的那種味兒了,當然它并不是反應式。當我們不從返回值Optional取其中具體的對象時,我們不清楚里面到底有沒有,但是Optional是一定客觀存在的,不會出現NPE問題。

反應式數據處理

public Mono<ClientUser> currentUser () {return isAuthenticated ? Mono.just(new ClientUser("felord.cn", "reactive")): Mono.empty(); }

和Optional有點類似的機制,當然Mono不是為了解決NPE問題的,它是為了處理響應流中單個值(也可能是Void)而存在的。

Mono的創建Demo

Mono data = Mono.just("bole");Mono noData = Mono.empty();m.subscribe(i -> System.out.println(i));

Flux和Mono總結

Flux和Mono是Java反應式中的重要概念,但是很多同學包括我在開始都難以理解它們。這其實是規定了兩種流式范式,這種范式讓數據具有一些新的特性,比如基于發布訂閱的事件驅動,異步流、背壓等等。另外數據是推送(Push)給消費者的以區別于平時我們的拉(Pull)模式。同時我們可以像Stream Api一樣使用類似map、flatmap等操作符(operator)來操作它們。

函數編程

反應式編程,常常和函數式編程結合,這就是讓大家困擾的地方

函數編程接口

接口函數名說明
BiConsumer表示接收兩個輸入參數和不返回結果的操作。
BiFunction表示接受兩個參數,并產生一個結果的函數。
BinaryOperator表示在相同類型的兩個操作數的操作,生產相同類型的操作數的結果。
BiPredicate代表兩個參數謂詞(布爾值函數)。
BooleanSupplier代表布爾值結果的提供者。
Consumer表示接受一個輸入參數和不返回結果的操作。
DoubleBinaryOperator代表在兩個double值操作數的運算,并產生一個double值結果。
DoubleConsumer表示接受一個double值參數,不返回結果的操作。
DoubleFunction表示接受double值參數,并產生一個結果的函數。
DoublePredicate代表一個double值參數謂詞(布爾值函數)。
DoubleSupplier表示表示接受double值參數,并產生一個結果的函數。值結果的提供者。
DoubleToIntFunction表示接受一個double值參數,不返回結果的操作。
DoubleFunction表示接受double值參數,并產生一個結果的函數。
DoublePredicate代表一個double值參數謂詞(布爾值函數)。
DoubleSupplierDoubleToIntFunction
DoubleToIntFunction表示接受double值參數,并產生一個int值結果的函數。
DoubleToLongFunction表示上產生一個double值結果的單個double值操作數的操作。
Function代表接受一個double值參數,并產生一個long值結果的函數。
DoubleUnaryOperator表示上產生一個double值結果的單個double值操作數的操作。
Function表示接受一個參數,并產生一個結果的函數。
IntConsumer表示接受單個int值的參數并沒有返回結果的操作。
IntFunction表示接受一個int值參數,并產生一個結果的函數。
IntPredicate表示一個整數值參數謂詞(布爾值函數)。
IntSupplier代表整型值的結果的提供者。
IntToLongFunction表示接受一個int值參數,并產生一個long值結果的函數。
IntUnaryOperator表示產生一個int值結果的單個int值操作數的運算。
LongBinaryOperator表示在兩個long值操作數的操作,并產生一個ObjLongConsumer值結果。
LongFunction表示接受long值參數,并產生一個結果的函數。
LongPredicate代表一個long值參數謂詞(布爾值函數)。
LongSupplier表示long值結果的提供者。
LongToDoubleFunction表示接受double參數,并產生一個double值結果的函數。
LongToIntFunction表示接受long值參數,并產生一個int值結果的函數。
LongUnaryOperator表示上產生一個long值結果單一的long值操作數的操作。
ObjDoubleConsumer表示接受對象值和double值參數,并且沒有返回結果的操作。
ObjIntConsumer表示接受對象值和整型值參數,并返回沒有結果的操作。
ObjLongConsumer表示接受對象值和整型值參數,并返回沒有結果的操作。
ObjLongConsumer表示接受對象值和double值參數,并且沒有返回結果的操作。
ObjIntConsumer表示接受對象值和整型值參數,并返回沒有結果的操作。
ObjLongConsumer表示接受對象的值和long值的說法,并沒有返回結果的操作。
Predicate代表一個參數謂詞(布爾值函數)。
Supplier表示一個提供者的結果。
ToDoubleBiFunction表示接受兩個參數,并產生一個double值結果的功能。
ToDoubleFunction代表一個產生一個double值結果的功能。
ToIntBiFunction表示接受兩個參數,并產生一個int值結果的函數。
ToIntFunction代表產生一個int值結果的功能。
ToLongBiFunction表示接受兩個參數,并產生long值結果的功能。
ToLongFunction代表一個產生long值結果的功能。
UnaryOperator表示上產生相同類型的操作數的結果的單個操作數的操作。

常用函數編程示例

Consumer 一個輸入 無輸出

Product product=new Product(); //類名+靜態方法 一個輸入T 沒有輸出 Consumer consumer1 = Product->Product.nameOf(product);//lambda consumer1.accept(product); Consumer consumer = Product::nameOf;//方法引用 consumer.accept(product);

Funtion<T,R> 一個輸入 一個輸出

//對象+方法 一個輸入T 一個輸出R Function<Integer, Integer> function = product::reduceStock; System.out.println("剩余庫存:" + function.apply(10)); //帶參數的構造函數 Function<Integer,Product> function1=Product::new; System.out.println("新對象:" +function1.apply(200));

Predicate 一個輸入T, 一個輸出 Boolean

//Predicate 一個輸入T 一個輸出Boolean Predicate predicate= i -> product.isEnough(i);//lambda System.out.println("庫存是否足夠:"+predicate.test(100)); Predicate predicate1= product::isEnough;//方法引用 System.out.println("庫存是否足夠:"+predicate1.test(100));

UnaryOperator 一元操作符 輸入輸出都是T

//一元操作符 輸入和輸出T UnaryOperator integerUnaryOperator =product::reduceStock; System.out.println("剩余庫存:" + integerUnaryOperator.apply(20)); IntUnaryOperator intUnaryOperator = product::reduceStock; System.out.println("剩余庫存:" + intUnaryOperator.applyAsInt(30));

Supplier 沒有輸入 只有輸出

//無參數構造函數 Supplier supplier = Product::new; System.out.println("創建新對象:" + supplier.get()); Supplier supplier1=()->product.getStock(); System.out.println("剩余庫存:" + supplier1.get());

BiFunction 二元操作符 兩個輸入<T,U> 一個輸出

//類名+方法 BiFunction<Product, Integer, Integer> binaryOperator = Product::reduceStock; System.out.println(" 剩余庫存(BiFunction):" + binaryOperator.apply(product, 10));

BinaryOperator 二元操作符 ,二個輸入 一個輸出

//BinaryOperator binaryOperator1=(x,y)->product.reduceStock(x,y); BinaryOperator binaryOperator1=product::reduceStock; System.out.println(" 剩余庫存(BinaryOperator):" +binaryOperator1.apply(product.getStock(),10));

Flux類中的靜態方法:

簡單的創建方法

just():

可以指定序列中包含的全部元素。創建出來的Flux序列在發布這些元素之后會自動結束

fromArray(),fromIterable(),fromStream():

可以從一個數組,Iterable對象或Stream對象中穿件Flux對象

empty():

創建一個不包含任何元素,只發布結束消息的序列

error(Throwable error):

創建一個只包含錯誤消息的序列

never():

傳建一個不包含任務消息通知的序列

range(int start, int count):

創建包含從start起始的count個數量的Integer對象的序列

interval(Duration period)和interval(Duration delay, Duration period):

創建一個包含了從0開始遞增的Long對象的序列。其中包含的元素按照指定的間隔來發布。除了間隔時間之外,還可以指定起始元素發布之前的延遲時間

intervalMillis(long period)和intervalMillis(long delay, long period):

與interval()方法相同,但該方法通過毫秒數來指定時間間隔和延遲時間

例子

Flux.just("Hello", "World").subscribe(System.out::println); Flux.fromArray(new Integer[]{1, 2, 3}).subscribe(System.out::println); Flux.empty().subscribe(System.out::println); Flux.range(1, 10).subscribe(System.out::println); Flux.interval(Duration.of(10, ChronoUnit.SECONDS)).subscribe(System.out::println); Flux.intervalMillis(1000).subscirbe(System.out::println);

復雜的序列創建 generate()

當序列的生成需要復雜的邏輯時,則應該使用generate()或create()方法。

generate()方法通過同步和逐一的方式來產生Flux序列。

序列的產生是通過調用所提供的的SynchronousSink對象的next(),complete()和error(Throwable)方法來完成的。

逐一生成的含義是在具體的生成邏輯中,next()方法只能最多被調用一次。

在某些情況下,序列的生成可能是有狀態的,需要用到某些狀態對象,此時可以使用

generate(Callable<S> stateSupplier, BiFunction<S, SynchronousSink<T>, S> generator),

其中stateSupplier用來提供初始的狀態對象。

在進行序列生成時,狀態對象會作為generator使用的第一個參數傳入,可以在對應的邏輯中對改狀態對象進行修改以供下一次生成時使用。

Flux.generate(sink -> {sink.next("Hello");sink.complete(); }).subscribe(System.out::println);final Random random = new Random(); Flux.generate(ArrayList::new, (list, sink) -> {int value = random.nextInt(100);list.add(value);sink.next(value);if( list.size() ==10 )sink.complete();return list; }).subscribe(System.out::println);

復雜的序列創建 create()

create()方法與generate()方法的不同之處在于所使用的是FluxSink對象。

FluxSink支持同步和異步的消息產生,并且可以在一次調用中產生多個元素。

Flux.create(sink -> {for(int i = 0; i < 10; i ++)sink.next(i);sink.complete(); }).subscribe(System.out::println);

Mono靜態方法

Mono類包含了與Flux類中相同的靜態方法:just(),empty()和never()等。

除此之外,Mono還有一些獨有的靜態方法:

fromCallable(),fromCompletionStage(),fromFuture(),fromRunnable()和fromSupplier():分別從Callable,CompletionStage,CompletableFuture,Runnable和Supplier中創建Mono

delay(Duration duration)和delayMillis(long duration):創建一個Mono序列,在指定的延遲時間之后,產生數字0作為唯一值

ignoreElements(Publisher source):創建一個Mono序列,忽略作為源的Publisher中的所有元素,只產生消息

justOrEmpty(Optional<? extends T> data)和justOrEmpty(T data):從一個Optional對象或可能為null的對象中創建Mono。只有Optional對象中包含之或對象不為null時,Mono序列才產生對應的元素

Mono.fromSupplier(() -> "Hello").subscribe(System.out::println); Mono.justOrEmpty(Optional.of("Hello")).subscribe(System.out::println); Mono.create(sink -> sink.success("Hello")).subscribte(System.out::println);

操作符

操作符buffer和bufferTimeout

這兩個操作符的作用是把當前流中的元素收集到集合中,并把集合對象作為流中的新元素。

在進行收集時可以指定不同的條件:所包含的元素的最大數量或收集的時間間隔。方法buffer()僅使用一個條件,而bufferTimeout()可以同時指定兩個條件。

指定時間間隔時可以使用Duration對象或毫秒數,即使用bufferMillis()或bufferTimeoutMillis()兩個方法。

除了元素數量和時間間隔外,還可以通過bufferUntil和bufferWhile操作符來進行收集。這兩個操作符的參數時表示每個集合中的元素索要滿足的條件的Predicate對象。

bufferUntil會一直收集直到Predicate返回true。

使得Predicate返回true的那個元素可以選擇添加到當前集合或下一個集合中;bufferWhile則只有當Predicate返回true時才會收集。一旦為false,會立即開始下一次收集。

Flux.range(1, 100).buffer(20).subscribe(System.out::println); Flux.intervalMillis(100).bufferMillis(1001).take(2).toStream().forEach(System.out::println); Flux.range(1, 10).bufferUntil(i -> i%2 == 0).subscribe(System.out::println); Flux.range(1, 10).bufferWhile(i -> i%2 == 0).subscribe(System.out::println);

操作符Filter

對流中包含的元素進行過濾,只留下滿足Predicate指定條件的元素。

Flux.range(1, 10).filter(i -> i%2 == 0).subscribe(System.out::println);

操作符zipWith

zipWith操作符把當前流中的元素與另一個流中的元素按照一對一的方式進行合并。在合并時可以不做任何處理,由此得到的是一個元素類型為Tuple2的流;也可以通過一個BiFunction函數對合并的元素進行處理,所得到的流的元素類型為該函數的返回值。

Flux.just("a", "b").zipWith(Flux.just("c", "d")).subscribe(System.out::println); Flux.just("a", "b").zipWith(Flux.just("c", "d"), (s1, s2) -> String.format("%s-%s", s1, s2)).subscribe(System.out::println);

操作符take

take系列操作符用來從當前流中提取元素。提取方式如下:

take(long n),take(Duration timespan)和takeMillis(long timespan):按照指定的數量或時間間隔來提取

takeLast(long n):提取流中的最后N個元素

takeUntil(Predicate<? super T> predicate) :提取元素直到Predicate返回true

takeWhile(Predicate<? super T> continuePredicate):當Predicate返回true時才進行提取

takeUntilOther(Publisher<?> other):提取元素知道另外一個流開始產生元素

Flux.range(1, 1000).take(10).subscribe(System.out::println); Flux.range(1, 1000).takeLast(10).subscribe(System.out::println); Flux.range(1, 1000).takeWhile(i -> i < 10).subscribe(System.out::println); Flux.range(1, 1000).takeUntil(i -> i == 10).subscribe(System.out::println);

操作符reduce和reduceWith

reduce和reduceWith操作符對流中包含的所有元素進行累計操作,得到一個包含計算結果的Mono序列。累計操作是通過一個BiFunction來表示的。在操作時可以指定一個初始值。若沒有初始值,則序列的第一個元素作為初始值。

Flux.range(1, 100).reduce((x, y) -> x + y).subscribe(System.out::println); Flux.range(1, 100).reduceWith(() -> 100, (x + y) -> x + y).subscribe(System.out::println);

操作符merge和mergeSequential

merge和mergeSequential操作符用來把多個流合并成一個Flux序列。merge按照所有流中元素的實際產生序列來合并,而mergeSequential按照所有流被訂閱的順序,以流為單位進行合并。

Flux.merge(Flux.intervalMillis(0, 100).take(5), Flux.intervalMillis(50, 100).take(5)).toStream().forEach(System.out::println); Flux.mergeSequential(Flux.intervalMillis(0, 100).take(5), Flux.intervalMillis(50, 100).take(5)).toStream().forEach(System.out::println);

操作符flatMap和flatMapSequential

flatMap和flatMapSequential操作符把流中的每個元素轉換成一個流,再把所有流中的元素進行合并。flatMapSequential和flatMap之間的區別與mergeSequential和merge是一樣的。

Flux.just(5, 10).flatMap(x -> Flux.intervalMillis(x * 10, 100).take(x)).toStream().forEach(System.out::println);

操作符concatMap

concatMap操作符的作用也是把流中的每個元素轉換成一個流,再把所有流進行合并。concatMap會根據原始流中的元素順序依次把轉換之后的流進行合并,并且concatMap堆轉換之后的流的訂閱是動態進行的,而flatMapSequential在合并之前就已經訂閱了所有的流。

Flux.just(5, 10).concatMap(x -> Flux.intervalMillis(x * 10, 100).take(x)).toStream().forEach(System.out::println);

操作符combineLatest

combineLatest操作符把所有流中的最新產生的元素合并成一個新的元素,作為返回結果流中的元素。只要其中任何一個流中產生了新的元素,合并操作就會被執行一次,結果流中就會產生新的元素。

Flux.combineLatest(Arrays::toString, Flux.intervalMillis(100).take(5), Flux.intervalMillis(50, 100).take(5)).toStream().forEach(System.out::println);

消息處理

當需要處理Flux或Mono中的消息時,可以通過subscribe方法來添加相應的訂閱邏輯。

在調用subscribe方法時可以指定需要處理的消息類型。

Flux.just(1, 2).concatWith(Mono.error(new IllegalStateException())).subscribe(System.out::println, System.err::println);Flux.just(1, 2).concatWith(Mono.error(new IllegalStateException())).onErrorReturn(0).subscribe(System.out::println);

第2種可以通過switchOnError()方法來使用另外的流來產生元素。

Flux.just(1, 2).concatWith(Mono.error(new IllegalStateException())).switchOnError(Mono.just(0)).subscribe(System.out::println);

第三種是通過onErrorResumeWith()方法來根據不同的異常類型來選擇要使用的產生元素的流。

Flux.just(1, 2).concatWith(Mono.error(new IllegalArgumentException())).onErrorResumeWith(e -> {if(e instanceof IllegalStateException)return Mono.just(0);else if(e instanceof IllegalArgumentException)return Mono.just(-1);return Mono.epmty(); }).subscribe(System,.out::println);

當出現錯誤時還可以使用retry操作符來進行重試。重試的動作是通過重新訂閱序列來實現的。在使用retry操作時還可以指定重試的次數。

Flux.just(1, 2).concatWith(Mono.error(new IllegalStateException())).retry(1).subscrible(System.out::println);

調度器Scheduler

通過調度器可以指定操作執行的方式和所在的線程。有以下幾種不同的調度器實現

當前線程,通過Schedulers.immediate()方法來創建

單一的可復用的線程,通過Schedulers.single()方法來創建

使用彈性的線程池,通過Schedulers.elastic()方法來創建。線程池中的線程是可以復用的。當所需要時,新的線程會被創建。若一個線程閑置時間太長,則會被銷毀。該調度器適用于I/O操作相關的流的處理

使用對并行操作優化的線程池,通過Schedulers.parallel()方法來創建。其中的線程數量取決于CPU的核的數量。該調度器適用于計算密集型的流的處理

使用支持任務調度的調度器,通過Schedulers.timer()方法來創建

從已有的ExecutorService對象中創建調度器,通過Schedulers.fromExecutorService()方法來創建

通過publishOn()和subscribeOn()方法可以切換執行操作調度器。publishOn()方法切換的是操作符的執行方式,而subscribeOn()方法切換的是產生流中元素時的執行方式

Flux.create(sink -> {sink.next(Thread.currentThread().getName());sink.complete(); }).publishOn(Schedulers.single()) .map(x -> String.format("[%s] %s", Thread.currentThread().getName(), x)) .publishOn(Schedulers.elastic()) .map(x -> String.format("[%s] %s", Thread.currentThread().getName(), x)) .subscribeOn(Schedulers.parallel()) .toStream() .forEach(System.out::println);

測試

StepVerifier的作用是可以對序列中包含的元素進行逐一驗證。通過StepVerifier.create()方法對一個流進行包裝之后再進行驗證。expectNext()方法用來聲明測試時所期待的流中的下一個元素的值,而verifyComplete()方法則驗證流是否正常結束。verifyError()來驗證流由于錯誤而終止。

StepVerifier.create(Flux.just(a, b)).expectNext("a").expectNext("b").verifyComplete();

使用StepVerifier.withVirtualTime()方法可以創建出使用虛擬時鐘的SteoVerifier。通過thenAwait(Duration)方法可以讓虛擬時鐘前進。

StepVerifier.withVirtualTime(() -> Flux.interval(Duration.ofHours(4), Duration.ofDays(1)).take(2)).expectSubscription().expectNoEvent(Duration.ofHours(4)).expectNext(0L).thenAwait(Duration.ofDays(1)).expectNext(1L).verifyComplete();

TestPublisher的作用在于可以控制流中元素的產生,甚至是違反反應流規范的情況。通過create()方法創建一個新的TestPublisher對象,然后使用next()方法來產生元素,使用complete()方法來結束流。

final TestPublisher<String> testPublisher = TestPublisher.creater(); testPublisher.next("a"); testPublisher.next("b"); testPublisher.complete();StepVerifier.create(testPublisher).expectNext("a").expectNext("b").expectComplete();

調試

在調試模式啟用之后,所有的操作符在執行時都會保存額外的與執行鏈相關的信息。當出現錯誤時,這些信息會被作為異常堆棧信息的一部分輸出。

Hooks.onOperator(providedHook -> providedHook.operatorStacktrace());

也可以通過checkpoint操作符來對特定的流處理鏈來啟用調試模式。

Flux.just(1, 0).map(x -> 1/x).checkpoint("test").subscribe(System.out::println);

日志記錄

可以通過添加log操作把流相關的事件記錄在日志中,

Flux.range(1, 2).log("Range").subscribe(System.out::println);

冷熱序列

冷序列的含義是不論訂閱者在何時訂閱該序列,總是能收到序列中產生的全部消息。熱序列是在持續不斷的產生消息,訂閱者只能獲取到在其訂閱之后產生的消息。

final Flux<Long> source = Flux.intervalMillis(1000).take(10).publish.autoConnect(); source.subscribe(); Thread.sleep(5000); source.toStream().forEach(System.out::println);

ServerWebExchange交換機

ServerWebExchange與過濾器的關系:

Spring Cloud Gateway同zuul類似,有“pre”和“post”兩種方式的filter。

客戶端的請求先經過“pre”類型的filter,然后將請求轉發到具體的業務服務,收到業務服務的響應之后,再經過“post”類型的filter處理,最后返回響應到客戶端。

引用Spring Cloud Gateway官網上的一張圖:

與zuul不同的是,filter除了分為“pre”和“post”兩種方式的filter外,在Spring Cloud Gateway中,filter從作用范圍可分為另外兩種,

一種是針對于單個路由的gateway filter,它在配置文件中的寫法同predict類似;

一種是針對于所有路由的global gateway filer

現在從作用范圍劃分的維度來講解這兩種filter。

我們在使用Spring Cloud Gateway的時候,注意到過濾器(包括GatewayFilter、GlobalFilter和過濾器鏈GatewayFilterChain)。

Spring Cloud Gateway根據作用范圍劃分為GatewayFilter和GlobalFilter,二者區別如下:

  • GatewayFilter : 需要通過spring.cloud.routes.filters 配置在具體路由下,只作用在當前路由上或通過spring.cloud.default-filters配置在全局,作用在所有路由上
  • GlobalFilter : 全局過濾器,不需要在配置文件中配置,作用在所有的路由上,最終通過GatewayFilterAdapter包裝成GatewayFilterChain可識別的過濾器,它為請求業務以及路由的URI轉換為真實業務服務的請求地址的核心過濾器,不需要配置,系統初始化時加載,并作用在每個路由上。

Spring Cloud Gateway框架內置的GlobalFilter如下:

上圖中每一個GlobalFilter都作用在每一個router上,能夠滿足大多數的需求。

但是如果遇到業務上的定制,可能需要編寫滿足自己需求的GlobalFilter。

過濾器都依賴到ServerWebExchange:

public interface GlobalFilter {Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain); }public interface GatewayFilter extends ShortcutConfigurable {Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain); }public interface GatewayFilterChain {Mono<Void> filter(ServerWebExchange exchange); }

這里的設計和Servlet中的Filter是相似的,

當前過濾器可以決定是否執行下一個過濾器的邏輯,由GatewayFilterChain#filter()是否被調用來決定。

而ServerWebExchange就相當于當前請求和響應的上下文。

ServerWebExchange實例不單存儲了Request和Response對象,還提供了一些擴展方法,如果想實現改造請求參數或者響應參數,就必須深入了解ServerWebExchange。

理解ServerWebExchange

先看ServerWebExchange的注釋:

Contract for an HTTP request-response interaction.

Provides access to the HTTP request and response and also exposes additional server-side processing related properties and features such as request attributes.

翻譯一下大概是:

ServerWebExchange是一個HTTP請求-響應交互的契約。提供對HTTP請求和響應的訪問,并公開額外的服務器端處理相關屬性和特性,如請求屬性。

其實,ServerWebExchange命名為服務網絡交換器,存放著重要的請求-響應屬性、請求實例和響應實例等等,有點像Context的角色。

ServerWebExchange接口

ServerWebExchange接口的所有方法:

public interface ServerWebExchange {// 日志前綴屬性的KEY,值為org.springframework.web.server.ServerWebExchange.LOG_ID// 可以理解為 attributes.set("org.springframework.web.server.ServerWebExchange.LOG_ID","日志前綴的具體值");// 作用是打印日志的時候會拼接這個KEY對飲的前綴值,默認值為""String LOG_ID_ATTRIBUTE = ServerWebExchange.class.getName() + ".LOG_ID";String getLogPrefix();// 獲取ServerHttpRequest對象ServerHttpRequest getRequest();// 獲取ServerHttpResponse對象ServerHttpResponse getResponse();// 返回當前exchange的請求屬性,返回結果是一個可變的MapMap<String, Object> getAttributes();// 根據KEY獲取請求屬性@Nullabledefault <T> T getAttribute(String name) {return (T) getAttributes().get(name);}// 根據KEY獲取請求屬性,做了非空判斷@SuppressWarnings("unchecked")default <T> T getRequiredAttribute(String name) {T value = getAttribute(name);Assert.notNull(value, () -> "Required attribute '" + name + "' is missing");return value;}// 根據KEY獲取請求屬性,需要提供默認值@SuppressWarnings("unchecked")default <T> T getAttributeOrDefault(String name, T defaultValue) {return (T) getAttributes().getOrDefault(name, defaultValue);} // 返回當前請求的網絡會話Mono<WebSession> getSession();// 返回當前請求的認證用戶,如果存在的話<T extends Principal> Mono<T> getPrincipal(); // 返回請求的表單數據或者一個空的Map,只有Content-Type為application/x-www-form-urlencoded的時候這個方法才會返回一個非空的Map -- 這個一般是表單數據提交用到Mono<MultiValueMap<String, String>> getFormData(); // 返回multipart請求的part數據或者一個空的Map,只有Content-Type為multipart/form-data的時候這個方法才會返回一個非空的Map -- 這個一般是文件上傳用到Mono<MultiValueMap<String, Part>> getMultipartData();// 返回Spring的上下文@NullableApplicationContext getApplicationContext(); // 這幾個方法和lastModified屬性相關boolean isNotModified();boolean checkNotModified(Instant lastModified);boolean checkNotModified(String etag);boolean checkNotModified(@Nullable String etag, Instant lastModified);// URL轉換String transformUrl(String url); // URL轉換映射void addUrlTransformer(Function<String, String> transformer); // 注意這個方法,方法名是:改變,這個是修改ServerWebExchange屬性的方法,返回的是一個Builder實例,Builder是ServerWebExchange的內部類default Builder mutate() {return new DefaultServerWebExchangeBuilder(this);}interface Builder { // 覆蓋ServerHttpRequestBuilder request(Consumer<ServerHttpRequest.Builder> requestBuilderConsumer);Builder request(ServerHttpRequest request);// 覆蓋ServerHttpResponseBuilder response(ServerHttpResponse response);// 覆蓋當前請求的認證用戶Builder principal(Mono<Principal> principalMono);// 構建新的ServerWebExchange實例ServerWebExchange build();} }

ServerWebExchange#mutate()方法

注意到ServerWebExchange#mutate()方法,ServerWebExchange實例可以理解為不可變實例,

如果我們想要修改它,需要通過mutate()方法生成一個新的實例,例如這樣:

public class CustomGlobalFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();// 這里可以修改ServerHttpRequest實例ServerHttpRequest newRequest = ...ServerHttpResponse response = exchange.getResponse();// 這里可以修改ServerHttpResponse實例ServerHttpResponse newResponse = ...// 構建新的ServerWebExchange實例ServerWebExchange newExchange = exchange.mutate().request(newRequest).response(newResponse).build();return chain.filter(newExchange);} }

ServerHttpRequest接口

ServerHttpRequest實例是用于承載請求相關的屬性和請求體,

Spring Cloud Gateway中底層使用Netty處理網絡請求,通過追溯源碼,

可以從ReactorHttpHandlerAdapter中得知ServerWebExchange實例中持有的ServerHttpRequest實例的具體實現是ReactorServerHttpRequest。

之所以列出這些實例之間的關系,是因為這樣比較容易理清一些隱含的問題,例如:

  • ReactorServerHttpRequest的父類AbstractServerHttpRequest中初始化內部屬性headers的時候把請求的HTTP頭部封裝為只讀的實例
public AbstractServerHttpRequest(URI uri, @Nullable String contextPath, HttpHeaders headers) {this.uri = uri;this.path = RequestPath.parse(uri, contextPath);this.headers = HttpHeaders.readOnlyHttpHeaders(headers); }// HttpHeaders類中的readOnlyHttpHeaders方法, // ReadOnlyHttpHeaders屏蔽了所有修改請求頭的方法,直接拋出UnsupportedOperationException public static HttpHeaders readOnlyHttpHeaders(HttpHeaders headers) {Assert.notNull(headers, "HttpHeaders must not be null");if (headers instanceof ReadOnlyHttpHeaders) {return headers;}else {return new ReadOnlyHttpHeaders(headers);} }

所以, 不能直接從ServerHttpRequest實例中直接獲取請求頭HttpHeaders實例并且進行修改

ServerHttpRequest接口如下:

public interface HttpMessage {// 獲取請求頭,目前的實現中返回的是ReadOnlyHttpHeaders實例,只讀HttpHeaders getHeaders(); } public interface ReactiveHttpInputMessage extends HttpMessage {// 返回請求體的Flux封裝Flux<DataBuffer> getBody(); }public interface HttpRequest extends HttpMessage {// 返回HTTP請求方法,解析為HttpMethod實例@Nullabledefault HttpMethod getMethod() {return HttpMethod.resolve(getMethodValue());}// 返回HTTP請求方法,字符串String getMethodValue(); // 請求的URIURI getURI(); } public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage {// 連接的唯一標識或者用于日志處理標識String getId(); // 獲取請求路徑,封裝為RequestPath對象RequestPath getPath();// 返回查詢參數,是只讀的MultiValueMap實例MultiValueMap<String, String> getQueryParams();// 返回Cookie集合,是只讀的MultiValueMap實例MultiValueMap<String, HttpCookie> getCookies(); // 遠程服務器地址信息@Nullabledefault InetSocketAddress getRemoteAddress() {return null;}// SSL會話實現的相關信息@Nullabledefault SslInfo getSslInfo() {return null;} // 修改請求的方法,返回一個建造器實例Builder,Builder是內部類default ServerHttpRequest.Builder mutate() {return new DefaultServerHttpRequestBuilder(this);} interface Builder {// 覆蓋請求方法Builder method(HttpMethod httpMethod);// 覆蓋請求的URI、請求路徑或者上下文,這三者相互有制約關系,具體可以參考API注釋Builder uri(URI uri);Builder path(String path);Builder contextPath(String contextPath);// 覆蓋請求頭Builder header(String key, String value);Builder headers(Consumer<HttpHeaders> headersConsumer);// 覆蓋SslInfoBuilder sslInfo(SslInfo sslInfo);// 構建一個新的ServerHttpRequest實例ServerHttpRequest build();} }

注意:

ServerHttpRequest或者說HttpMessage接口提供的獲取請求頭方法HttpHeaders getHeaders();

返回結果是一個只讀的實例,具體是ReadOnlyHttpHeaders類型,

如果要修改ServerHttpRequest實例,那么需要這樣做:

ServerHttpRequest request = exchange.getRequest(); ServerHttpRequest newRequest = request.mutate().header("key","value").path("/myPath").build();

ServerHttpResponse接口

ServerHttpResponse實例是用于承載響應相關的屬性和響應體,

Spring Cloud Gateway中底層使用Netty處理網絡請求,通過追溯源碼,可以從ReactorHttpHandlerAdapter中得知ServerWebExchange實例中持有的ServerHttpResponse實例的具體實現是ReactorServerHttpResponse。

之所以列出這些實例之間的關系,是因為這樣比較容易理清一些隱含的問題,例如:

// ReactorServerHttpResponse的父類 public AbstractServerHttpResponse(DataBufferFactory dataBufferFactory, HttpHeaders headers) {Assert.notNull(dataBufferFactory, "DataBufferFactory must not be null");Assert.notNull(headers, "HttpHeaders must not be null");this.dataBufferFactory = dataBufferFactory;this.headers = headers;this.cookies = new LinkedMultiValueMap<>(); }public ReactorServerHttpResponse(HttpServerResponse response, DataBufferFactory bufferFactory) {super(bufferFactory, new HttpHeaders(new NettyHeadersAdapter(response.responseHeaders())));Assert.notNull(response, "HttpServerResponse must not be null");this.response = response; }

可知ReactorServerHttpResponse構造函數初始化實例的時候,存放響應Header的是HttpHeaders實例,也就是響應Header是可以直接修改的。

ServerHttpResponse接口如下:

public interface HttpMessage {// 獲取響應Header,目前的實現中返回的是HttpHeaders實例,可以直接修改HttpHeaders getHeaders(); } public interface ReactiveHttpOutputMessage extends HttpMessage {// 獲取DataBufferFactory實例,用于包裝或者生成數據緩沖區DataBuffer實例(創建響應體)DataBufferFactory bufferFactory();// 注冊一個動作,在HttpOutputMessage提交之前此動作會進行回調void beforeCommit(Supplier<? extends Mono<Void>> action);// 判斷HttpOutputMessage是否已經提交boolean isCommitted();// 寫入消息體到HTTP協議層Mono<Void> writeWith(Publisher<? extends DataBuffer> body);// 寫入消息體到HTTP協議層并且刷新緩沖區Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body);// 指明消息處理已經結束,一般在消息處理結束自動調用此方法,多次調用不會產生副作用Mono<Void> setComplete(); }public interface ServerHttpResponse extends ReactiveHttpOutputMessage {// 設置響應狀態碼boolean setStatusCode(@Nullable HttpStatus status);// 獲取響應狀態碼@NullableHttpStatus getStatusCode();// 獲取響應Cookie,封裝為MultiValueMap實例,可以修改MultiValueMap<String, ResponseCookie> getCookies(); // 添加響應Cookievoid addCookie(ResponseCookie cookie); }

這里可以看到除了響應體比較難修改之外,其他的屬性都是可變的。

ServerWebExchangeUtils和上下文屬性

ServerWebExchangeUtils里面存放了很多靜態公有的字符串KEY值

(這些字符串KEY的實際值是org.springframework.cloud.gateway.support.ServerWebExchangeUtils. + 下面任意的靜態公有KEY),

這些字符串KEY值一般是用于ServerWebExchange的屬性(Attribute,見上文的ServerWebExchange#getAttributes()方法)的KEY,這些屬性值都是有特殊的含義,在使用過濾器的時候如果時機適當可以直接取出來使用,下面逐個分析。

  • PRESERVE_HOST_HEADER_ATTRIBUTE:是否保存Host屬性,值是布爾值類型,寫入位置是PreserveHostHeaderGatewayFilterFactory,使用的位置是NettyRoutingFilter,作用是如果設置為true,HTTP請求頭中的Host屬性會寫到底層Reactor-Netty的請求Header屬性中。
  • CLIENT_RESPONSE_ATTR:保存底層Reactor-Netty的響應對象,類型是reactor.netty.http.client.HttpClientResponse。
  • CLIENT_RESPONSE_CONN_ATTR:保存底層Reactor-Netty的連接對象,類型是reactor.netty.Connection。
  • URI_TEMPLATE_VARIABLES_ATTRIBUTE:PathRoutePredicateFactory解析路徑參數完成之后,把解析完成后的占位符KEY-路徑Path映射存放在ServerWebExchange的屬性中,KEY就是URI_TEMPLATE_VARIABLES_ATTRIBUTE。
  • CLIENT_RESPONSE_HEADER_NAMES:保存底層Reactor-Netty的響應Header的名稱集合。
  • GATEWAY_ROUTE_ATTR:用于存放RoutePredicateHandlerMapping中匹配出來的具體的路由(org.springframework.cloud.gateway.route.Route)實例,通過這個路由實例可以得知當前請求會路由到下游哪個服務。
  • GATEWAY_REQUEST_URL_ATTR:java.net.URI類型的實例,這個實例代表直接請求或者負載均衡處理之后需要請求到下游服務的真實URI。
  • GATEWAY_ORIGINAL_REQUEST_URL_ATTR:java.net.URI類型的實例,需要重寫請求URI的時候,保存原始的請求URI。
  • GATEWAY_HANDLER_MAPPER_ATTR:保存當前使用的HandlerMapping具體實例的類型簡稱(一般是字符串"RoutePredicateHandlerMapping")。
  • GATEWAY_SCHEME_PREFIX_ATTR:確定目標路由URI中如果存在schemeSpecificPart屬性,則保存該URI的scheme在此屬性中,路由URI會被重新構造,見RouteToRequestUrlFilter。
  • GATEWAY_PREDICATE_ROUTE_ATTR:用于存放RoutePredicateHandlerMapping中匹配出來的具體的路由(org.springframework.cloud.gateway.route.Route)實例的ID。
  • WEIGHT_ATTR:實驗性功能(此版本還不建議在正式版本使用)存放分組權重相關屬性,見WeightCalculatorWebFilter。
  • ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR:存放響應Header中的ContentType的值。
  • HYSTRIX_EXECUTION_EXCEPTION_ATTR:Throwable的實例,存放的是Hystrix執行異常時候的異常實例,見HystrixGatewayFilterFactory。
  • GATEWAY_ALREADY_ROUTED_ATTR:布爾值,用于判斷是否已經進行了路由,見NettyRoutingFilter。
  • GATEWAY_ALREADY_PREFIXED_ATTR:布爾值,用于判斷請求路徑是否被添加了前置部分,見PrefixPathGatewayFilterFactory。

ServerWebExchangeUtils提供的上下文屬性用于Spring Cloud Gateway的ServerWebExchange組件處理請求和響應的時候,內部一些重要實例或者標識屬性的安全傳輸和使用,使用它們可能存在一定的風險,

因為沒有人可以確定在版本升級之后,原有的屬性KEY或者VALUE是否會發生改變,如果評估過風險或者規避了風險之后,可以安心使用。

例如我們**在做請求和響應日志(類似Nginx的Access Log)的時候,可以依賴到GATEWAY_ROUTE_ATTR,因為我們要打印路由的目標信息。**舉個簡單例子:

@Slf4j @Component public class AccessLogFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();String path = request.getPath().pathWithinApplication().value();HttpMethod method = request.getMethod();// 獲取路由的目標URIURI targetUri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);InetSocketAddress remoteAddress = request.getRemoteAddress();return chain.filter(exchange.mutate().build()).then(Mono.fromRunnable(() -> {ServerHttpResponse response = exchange.getResponse();HttpStatus statusCode = response.getStatusCode();log.info("請求路徑:{},客戶端遠程IP地址:{},請求方法:{},目標URI:{},響應碼:{}",path, remoteAddress, method, targetUri, statusCode);}));} }

修改請求體

修改請求體是一個比較常見的需求。

例如我們使用Spring Cloud Gateway實現網關的時候,要實現一個功能:

把存放在請求頭中的JWT解析后,提取里面的用戶ID,然后寫入到請求體中。

我們簡化這個場景,假設我們把userId明文存放在請求頭中的accessToken中,請求體是一個JSON結構:

{"serialNumber": "請求流水號","payload" : {// ... 這里是有效載荷,存放具體的數據} }

我們需要提取accessToken,也就是userId插入到請求體JSON中如下:

{"userId": "用戶ID","serialNumber": "請求流水號","payload" : {// ... 這里是有效載荷,存放具體的數據} }

這里為了簡化設計,用全局過濾器GlobalFilter實現,實際需要結合具體場景考慮:

@Slf4j @Component public class ModifyRequestBodyGlobalFilter implements GlobalFilter {private final DataBufferFactory dataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);@Autowiredprivate ObjectMapper objectMapper;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();String accessToken = request.getHeaders().getFirst("accessToken");if (!StringUtils.hasLength(accessToken)) {throw new IllegalArgumentException("accessToken");}// 新建一個ServerHttpRequest裝飾器,覆蓋需要裝飾的方法ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(request) {@Overridepublic Flux<DataBuffer> getBody() {Flux<DataBuffer> body = super.getBody();InputStreamHolder holder = new InputStreamHolder();body.subscribe(buffer -> holder.inputStream = buffer.asInputStream());if (null != holder.inputStream) {try {// 解析JSON的節點JsonNode jsonNode = objectMapper.readTree(holder.inputStream);Assert.isTrue(jsonNode instanceof ObjectNode, "JSON格式異常");ObjectNode objectNode = (ObjectNode) jsonNode;// JSON節點最外層寫入新的屬性objectNode.put("userId", accessToken);DataBuffer dataBuffer = dataBufferFactory.allocateBuffer();String json = objectNode.toString();log.info("最終的JSON數據為:{}", json);dataBuffer.write(json.getBytes(StandardCharsets.UTF_8));return Flux.just(dataBuffer);} catch (Exception e) {throw new IllegalStateException(e);}} else {return super.getBody();}}};// 使用修改后的ServerHttpRequestDecorator重新生成一個新的ServerWebExchangereturn chain.filter(exchange.mutate().request(decorator).build());}private class InputStreamHolder {InputStream inputStream;} }

測試一下:

// HTTP POST /order/json HTTP/1.1 Host: localhost:9090 Content-Type: application/json accessToken: 10086 Accept: */* Cache-Control: no-cache Host: localhost:9090 accept-encoding: gzip, deflate content-length: 94 Connection: keep-alive cache-control: no-cache{"serialNumber": "請求流水號","payload": {"name": "doge"} }// 日志輸出 最終的JSON數據為:{"serialNumber":"請求流水號","payload":{"name":"doge"},"userId":"10086"}

最重要的是用到了ServerHttpRequest裝飾器ServerHttpRequestDecorator,主要覆蓋對應獲取請求體數據緩沖區的方法即可,至于怎么處理其他邏輯需要自行考慮,這里只是做一個簡單的示范。

一般的代碼邏輯如下:

ServerHttpRequest request = exchange.getRequest(); ServerHttpRequestDecorator requestDecorator = new ServerHttpRequestDecorator(request) {@Overridepublic Flux<DataBuffer> getBody() {// 拿到承載原始請求體的FluxFlux<DataBuffer> body = super.getBody();// 這里通過自定義方式生成新的承載請求體的FluxFlux<DataBuffer> newBody = ...return newBody;} } return chain.filter(exchange.mutate().request(requestDecorator).build());

修改響應體

修改響應體的需求也是比較常見的,具體的做法和修改請求體差不多。

例如我們想要實現下面的功能:第三方服務請求經過網關,原始報文是密文,我們需要在網關實現密文解密,然后把解密后的明文路由到下游服務,下游服務處理成功響應明文,需要在網關把明文加密成密文再返回到第三方服務。

現在簡化整個流程,用AES加密算法,統一密碼為字符串"throwable",假設請求報文和響應報文明文如下:

// 請求密文 {"serialNumber": "請求流水號","payload" : "加密后的請求消息載荷" }// 請求明文(僅僅作為提示) {"serialNumber": "請求流水號","payload" : "{\"name:\":\"doge\"}" }// 響應密文 {"code": 200,"message":"ok","payload" : "加密后的響應消息載荷" }// 響應明文(僅僅作為提示) {"code": 200,"message":"ok","payload" : "{\"name:\":\"doge\",\"age\":26}" }

為了方便一些加解密或者編碼解碼的實現,需要引入Apache的commons-codec類庫:

<dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.12</version> </dependency>

這里定義一個全局過濾器專門處理加解密,實際上最好結合真實的場景決定是否適合全局過濾器,這里只是一個示例:

// AES加解密工具類 public enum AesUtils {// 單例X;private static final String PASSWORD = "throwable";private static final String KEY_ALGORITHM = "AES";private static final String SECURE_RANDOM_ALGORITHM = "SHA1PRNG";private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";public String encrypt(String content) {try {Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, provideSecretKey());return Hex.encodeHexString(cipher.doFinal(content.getBytes(StandardCharsets.UTF_8)));} catch (Exception e) {throw new IllegalArgumentException(e);}}public byte[] decrypt(String content) {try {Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, provideSecretKey());return cipher.doFinal(Hex.decodeHex(content));} catch (Exception e) {throw new IllegalArgumentException(e);}}private SecretKey provideSecretKey() {try {KeyGenerator keyGen = KeyGenerator.getInstance(KEY_ALGORITHM);SecureRandom secureRandom = SecureRandom.getInstance(SECURE_RANDOM_ALGORITHM);secureRandom.setSeed(PASSWORD.getBytes(StandardCharsets.UTF_8));keyGen.init(128, secureRandom);return new SecretKeySpec(keyGen.generateKey().getEncoded(), KEY_ALGORITHM);} catch (Exception e) {throw new IllegalArgumentException(e);}} }// EncryptionGlobalFilter @Slf4j @Component public class EncryptionGlobalFilter implements GlobalFilter, Ordered {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic int getOrder() {return -2;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();// 響應體ServerHttpResponse response = exchange.getResponse();DataBufferFactory bufferFactory = exchange.getResponse().bufferFactory();ServerHttpRequestDecorator requestDecorator = processRequest(request, bufferFactory);ServerHttpResponseDecorator responseDecorator = processResponse(response, bufferFactory);return chain.filter(exchange.mutate().request(requestDecorator).response(responseDecorator).build());}private ServerHttpRequestDecorator processRequest(ServerHttpRequest request, DataBufferFactory bufferFactory) {Flux<DataBuffer> body = request.getBody();DataBufferHolder holder = new DataBufferHolder();body.subscribe(dataBuffer -> {int len = dataBuffer.readableByteCount();holder.length = len;byte[] bytes = new byte[len];dataBuffer.read(bytes);DataBufferUtils.release(dataBuffer);String text = new String(bytes, StandardCharsets.UTF_8);JsonNode jsonNode = readNode(text);JsonNode payload = jsonNode.get("payload");String payloadText = payload.asText();byte[] content = AesUtils.X.decrypt(payloadText);String requestBody = new String(content, StandardCharsets.UTF_8);log.info("修改請求體payload,修改前:{},修改后:{}", payloadText, requestBody);rewritePayloadNode(requestBody, jsonNode);DataBuffer data = bufferFactory.allocateBuffer();data.write(jsonNode.toString().getBytes(StandardCharsets.UTF_8));holder.dataBuffer = data;});HttpHeaders headers = new HttpHeaders();headers.putAll(request.getHeaders());headers.remove(HttpHeaders.CONTENT_LENGTH);return new ServerHttpRequestDecorator(request) {@Overridepublic HttpHeaders getHeaders() {int contentLength = holder.length;if (contentLength > 0) {headers.setContentLength(contentLength);} else {headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked");}return headers;}@Overridepublic Flux<DataBuffer> getBody() {return Flux.just(holder.dataBuffer);}};}private ServerHttpResponseDecorator processResponse(ServerHttpResponse response, DataBufferFactory bufferFactory) {return new ServerHttpResponseDecorator(response) {@SuppressWarnings("unchecked")@Overridepublic Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {if (body instanceof Flux) {Flux<? extends DataBuffer> flux = (Flux<? extends DataBuffer>) body;return super.writeWith(flux.map(buffer -> {CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());DataBufferUtils.release(buffer);JsonNode jsonNode = readNode(charBuffer.toString());JsonNode payload = jsonNode.get("payload");String text = payload.toString();String content = AesUtils.X.encrypt(text);log.info("修改響應體payload,修改前:{},修改后:{}", text, content);setPayloadTextNode(content, jsonNode);return bufferFactory.wrap(jsonNode.toString().getBytes(StandardCharsets.UTF_8));}));}return super.writeWith(body);}};}private void rewritePayloadNode(String text, JsonNode root) {try {JsonNode node = objectMapper.readTree(text);ObjectNode objectNode = (ObjectNode) root;objectNode.set("payload", node);} catch (Exception e) {throw new IllegalStateException(e);}}private void setPayloadTextNode(String text, JsonNode root) {try {ObjectNode objectNode = (ObjectNode) root;objectNode.set("payload", new TextNode(text));} catch (Exception e) {throw new IllegalStateException(e);}}private JsonNode readNode(String in) {try {return objectMapper.readTree(in);} catch (Exception e) {throw new IllegalStateException(e);}}private class DataBufferHolder {DataBuffer dataBuffer;int length;} }

先準備一份密文:

Map<String, Object> json = new HashMap<>(8); json.put("serialNumber", "請求流水號"); String content = "{\"name\": \"doge\"}"; json.put("payload", AesUtils.X.encrypt(content)); System.out.println(new ObjectMapper().writeValueAsString(json));// 輸出 {"serialNumber":"請求流水號","payload":"144e3dc734743f5709f1adf857bca473da683246fd612f86ac70edeb5f2d2729"}

模擬請求:

POST /order/json HTTP/1.1 Host: localhost:9090 accessToken: 10086 Content-Type: application/json User-Agent: PostmanRuntime/7.13.0 Accept: */* Cache-Control: no-cache Postman-Token: bda07fc3-ea1a-478c-b4d7-754fe6f37200,634734d9-feed-4fc9-ba20-7618bd986e1c Host: localhost:9090 cookie: customCookieName=customCookieValue accept-encoding: gzip, deflate content-length: 104 Connection: keep-alive cache-control: no-cache{"serialNumber": "請求流水號","payload": "FE49xzR0P1cJ8a34V7ykc9poMkb9YS+GrHDt618tJyk=" }// 響應結果 {"serialNumber": "請求流水號","payload": "oo/K1igg2t/S8EExkBVGWOfI1gAh5pBpZ0wyjNPW6e8=" # <--- 解密后:{"name":"doge","age":26} }

遇到的問題:

  • 必須實現Ordered接口,返回一個小于-1的order值,這是因為NettyWriteResponseFilter的order值為-1,我們需要覆蓋返回響應體的邏輯,自定義的GlobalFilter必須比NettyWriteResponseFilter優先執行。
  • 網關每次重啟之后,第一個請求總是無法從原始的ServerHttpRequest讀取到有效的Body,準確來說出現的現象是NettyRoutingFilter調用ServerHttpRequest#getBody()的時候獲取到一個空的對象,導致空指針;奇怪的是從第二個請求開始就能正常調用。筆者把**Spring Cloud Gateway**的版本降低到**Finchley.SR3****Spring Boot**的版本降低到**2.0.8.RELEASE**,問題不再出現,初步確定是**Spring Cloud Gateway**版本升級導致的兼容性問題或者是BUG

最重要的是用到了ServerHttpResponse裝飾器ServerHttpResponseDecorator,主要覆蓋寫入響應體數據緩沖區的部分,至于怎么處理其他邏輯需要自行考慮,這里只是做一個簡單的示范。一般的代碼邏輯如下:

ServerHttpResponse response = exchange.getResponse(); ServerHttpResponseDecorator responseDecorator = new ServerHttpResponseDecorator(response) {@Overridepublic Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {if (body instanceof Flux) {Flux<? extends DataBuffer> flux = (Flux<? extends DataBuffer>) body;return super.writeWith(flux.map(buffer -> {// buffer就是原始的響應數據的緩沖區// 下面處理完畢之后返回新的響應數據的緩沖區即可return bufferFactory.wrap(...);}));}return super.writeWith(body);}}; return chain.filter(exchange.mutate().response(responseDecorator).build());

參考文獻

https://blog.csdn.net/wpc2018/article/details/122634049

https://www.jianshu.com/p/7d80b94068b3

https://blog.csdn.net/yhj_911/article/details/119540000

http://bjqianye.cn/detail/6845.html

https://blog.csdn.net/hao134838/article/details/110824092

https://blog.csdn.net/hao134838/article/details/110824092

https://blog.csdn.net/weixin_34096182/article/details/91436704

https://blog.csdn.net/fly910905/article/details/121682625

總結

以上是生活随笔為你收集整理的Flux、Mono、Reactor 实战(史上最全)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

97久久国产亚洲精品超碰热 | 亚洲国产午夜精品理论片 | 毛片内射-百度 | 久久久久99精品国产片 | 在线 国产 欧美 亚洲 天堂 | 久久久中文字幕日本无吗 | 亚洲欧美精品伊人久久 | 国产人妻精品一区二区三区 | 无码av中文字幕免费放 | 最新版天堂资源中文官网 | 国产性生交xxxxx无码 | 扒开双腿吃奶呻吟做受视频 | 国产sm调教视频在线观看 | 久久天天躁夜夜躁狠狠 | 国产在线无码精品电影网 | 亚洲综合另类小说色区 | 国产一精品一av一免费 | 精品国产乱码久久久久乱码 | 国产片av国语在线观看 | 成在人线av无码免观看麻豆 | 日韩人妻无码中文字幕视频 | 久久人人爽人人人人片 | 人人妻人人澡人人爽精品欧美 | 免费视频欧美无人区码 | 美女张开腿让人桶 | 免费看少妇作爱视频 | 欧美午夜特黄aaaaaa片 | 内射白嫩少妇超碰 | 美女毛片一区二区三区四区 | www国产精品内射老师 | 麻豆国产人妻欲求不满谁演的 | 国产精品久久久久久无码 | 久久国产自偷自偷免费一区调 | 日本精品人妻无码77777 天堂一区人妻无码 | 亚洲精品欧美二区三区中文字幕 | 未满成年国产在线观看 | 婷婷五月综合缴情在线视频 | 中文无码精品a∨在线观看不卡 | 久久久久久久人妻无码中文字幕爆 | 国产极品美女高潮无套在线观看 | 亚洲乱码中文字幕在线 | 国产精品沙发午睡系列 | 亚洲国产精品久久久久久 | 天堂亚洲2017在线观看 | 日产精品高潮呻吟av久久 | 天天躁夜夜躁狠狠是什么心态 | 亚洲国产精品无码久久久久高潮 | 亚洲性无码av中文字幕 | 中国女人内谢69xxxx | 日本xxxx色视频在线观看免费 | 夫妻免费无码v看片 | 国产亚洲精品久久久ai换 | 久久久久99精品成人片 | 色综合视频一区二区三区 | 亚洲中文字幕久久无码 | 国产精品久久久午夜夜伦鲁鲁 | 午夜不卡av免费 一本久久a久久精品vr综合 | 日韩欧美中文字幕在线三区 | 国产麻豆精品精东影业av网站 | 国产成人人人97超碰超爽8 | 99久久精品国产一区二区蜜芽 | 国产精品无码成人午夜电影 | 六十路熟妇乱子伦 | 国产一区二区三区日韩精品 | 亚洲精品久久久久久久久久久 | 亚洲自偷精品视频自拍 | 98国产精品综合一区二区三区 | 亚洲 激情 小说 另类 欧美 | 中国女人内谢69xxxx | 日韩精品一区二区av在线 | 任你躁在线精品免费 | 无码乱肉视频免费大全合集 | 国产精品亚洲а∨无码播放麻豆 | 精品久久久无码中文字幕 | 亚洲日本va午夜在线电影 | 亚洲 欧美 激情 小说 另类 | 熟女少妇在线视频播放 | 一本色道久久综合狠狠躁 | 久久久久免费看成人影片 | 免费视频欧美无人区码 | 午夜成人1000部免费视频 | 午夜福利试看120秒体验区 | 久久国产精品精品国产色婷婷 | 国产综合在线观看 | av无码电影一区二区三区 | 高潮毛片无遮挡高清免费 | 伊人色综合久久天天小片 | √8天堂资源地址中文在线 | 久久97精品久久久久久久不卡 | 亚洲中文字幕va福利 | 亚洲第一网站男人都懂 | 精品国产一区二区三区四区在线看 | 麻豆md0077饥渴少妇 | 日本高清一区免费中文视频 | 亚洲综合无码一区二区三区 | 日韩av无码一区二区三区 | 欧美xxxx黑人又粗又长 | 国产亚洲精品久久久久久大师 | 色婷婷欧美在线播放内射 | 欧美黑人性暴力猛交喷水 | 久久国产精品二国产精品 | 久久国产自偷自偷免费一区调 | 无码国内精品人妻少妇 | 99精品国产综合久久久久五月天 | 日产精品高潮呻吟av久久 | 日本精品少妇一区二区三区 | 99久久精品无码一区二区毛片 | 亚洲性无码av中文字幕 | 7777奇米四色成人眼影 | 无码国内精品人妻少妇 | 免费人成网站视频在线观看 | 国产97人人超碰caoprom | 亚洲小说春色综合另类 | 中文字幕久久久久人妻 | 狠狠色噜噜狠狠狠7777奇米 | 亚洲男人av香蕉爽爽爽爽 | 内射白嫩少妇超碰 | 精品厕所偷拍各类美女tp嘘嘘 | 国产色精品久久人妻 | 久久成人a毛片免费观看网站 | 日本精品少妇一区二区三区 | 欧美丰满熟妇xxxx性ppx人交 | 99riav国产精品视频 | 一个人免费观看的www视频 | 亚洲乱码中文字幕在线 | 日本一区二区更新不卡 | 国产精品无码一区二区桃花视频 | 欧美人与禽猛交狂配 | 人妻少妇精品久久 | 激情人妻另类人妻伦 | 亚洲精品综合一区二区三区在线 | av人摸人人人澡人人超碰下载 | 麻豆av传媒蜜桃天美传媒 | 国内综合精品午夜久久资源 | 亚洲成av人片天堂网无码】 | 日本精品人妻无码免费大全 | 日韩在线不卡免费视频一区 | 人人爽人人爽人人片av亚洲 | 少妇性荡欲午夜性开放视频剧场 | 俺去俺来也www色官网 | 亚洲人成无码网www | 国产精品内射视频免费 | 精品人人妻人人澡人人爽人人 | 成在人线av无码免观看麻豆 | 波多野结衣av一区二区全免费观看 | 一个人看的www免费视频在线观看 | 中文字幕av无码一区二区三区电影 | 成人无码精品1区2区3区免费看 | 婷婷色婷婷开心五月四房播播 | 国产av人人夜夜澡人人爽麻豆 | 欧美日韩视频无码一区二区三 | 无码av中文字幕免费放 | 99精品国产综合久久久久五月天 | 久久久国产精品无码免费专区 | 四虎4hu永久免费 | 亚洲の无码国产の无码步美 | 无码人中文字幕 | 久久熟妇人妻午夜寂寞影院 | 欧美国产日韩亚洲中文 | 久久久中文字幕日本无吗 | 国产精品va在线播放 | 亚洲s码欧洲m码国产av | 国产精品久久久久7777 | 国产人妖乱国产精品人妖 | 日本大乳高潮视频在线观看 | 欧美xxxxx精品 | 国产亚洲精品久久久久久大师 | 亚洲精品一区二区三区在线 | 大肉大捧一进一出视频出来呀 | 成人三级无码视频在线观看 | 美女毛片一区二区三区四区 | 任你躁在线精品免费 | 秋霞成人午夜鲁丝一区二区三区 | 狠狠cao日日穞夜夜穞av | 77777熟女视频在线观看 а天堂中文在线官网 | 久久99精品久久久久婷婷 | 色婷婷久久一区二区三区麻豆 | 无套内谢的新婚少妇国语播放 | 亚洲精品久久久久avwww潮水 | 荫蒂被男人添的好舒服爽免费视频 | 无码帝国www无码专区色综合 | 狠狠色噜噜狠狠狠狠7777米奇 | 欧美freesex黑人又粗又大 | 水蜜桃av无码 | 天天爽夜夜爽夜夜爽 | 国产精品亚洲一区二区三区喷水 | 老子影院午夜伦不卡 | 嫩b人妻精品一区二区三区 | 成熟妇人a片免费看网站 | 国产精品无码一区二区三区不卡 | 国产亚洲精品久久久ai换 | 精品一区二区三区波多野结衣 | 欧美国产日韩亚洲中文 | 精品 日韩 国产 欧美 视频 | 国产亚洲精品久久久闺蜜 | 澳门永久av免费网站 | 性欧美熟妇videofreesex | 成人女人看片免费视频放人 | 国产特级毛片aaaaaaa高清 | 牛和人交xxxx欧美 | 国产乱人偷精品人妻a片 | 午夜无码区在线观看 | 亚洲成熟女人毛毛耸耸多 | 亚洲精品无码国产 | 国产av剧情md精品麻豆 | 久久综合给合久久狠狠狠97色 | 内射老妇bbwx0c0ck | 色窝窝无码一区二区三区色欲 | 人人妻人人澡人人爽精品欧美 | 亚洲精品一区三区三区在线观看 | 国语精品一区二区三区 | 扒开双腿吃奶呻吟做受视频 | 福利一区二区三区视频在线观看 | 国产精品国产自线拍免费软件 | 2019nv天堂香蕉在线观看 | 国产精品高潮呻吟av久久4虎 | 波多野结衣av一区二区全免费观看 | 亚欧洲精品在线视频免费观看 | 麻豆蜜桃av蜜臀av色欲av | 给我免费的视频在线观看 | 色欲av亚洲一区无码少妇 | 2020最新国产自产精品 | 精品日本一区二区三区在线观看 | 国产精品资源一区二区 | 蜜臀aⅴ国产精品久久久国产老师 | 精品久久久久久亚洲精品 | 亚洲无人区午夜福利码高清完整版 | 亚洲区欧美区综合区自拍区 | 日本xxxx色视频在线观看免费 | 女人被爽到呻吟gif动态图视看 | 丰满少妇高潮惨叫视频 | 亚洲日本va午夜在线电影 | 熟妇人妻无码xxx视频 | 精品人人妻人人澡人人爽人人 | 性欧美疯狂xxxxbbbb | 欧美性猛交xxxx富婆 | 99久久久无码国产aaa精品 | 日本一卡2卡3卡四卡精品网站 | 一本一道久久综合久久 | 无码人妻久久一区二区三区不卡 | 久久综合狠狠综合久久综合88 | 国产精品久久久久久久9999 | 亚洲の无码国产の无码影院 | 精品国精品国产自在久国产87 | 无码福利日韩神码福利片 | 日本一区二区三区免费高清 | 性色欲情网站iwww九文堂 | 久久亚洲精品中文字幕无男同 | 亚洲天堂2017无码中文 | 婷婷色婷婷开心五月四房播播 | 岛国片人妻三上悠亚 | 国产亚洲精品久久久久久久 | 女人被男人爽到呻吟的视频 | 又湿又紧又大又爽a视频国产 | 内射后入在线观看一区 | 无套内谢的新婚少妇国语播放 | 久久久国产精品无码免费专区 | 亚洲精品一区二区三区四区五区 | 亚洲经典千人经典日产 | 国产手机在线αⅴ片无码观看 | 国产精品无码久久av | 丰满人妻翻云覆雨呻吟视频 | 牲欲强的熟妇农村老妇女视频 | 色妞www精品免费视频 | 人妻天天爽夜夜爽一区二区 | 人人澡人人妻人人爽人人蜜桃 | 免费看少妇作爱视频 | 国产成人无码av片在线观看不卡 | 亚洲无人区一区二区三区 | 动漫av网站免费观看 | 亚洲色www成人永久网址 | 四虎国产精品免费久久 | 国产成人精品久久亚洲高清不卡 | 无码av岛国片在线播放 | 狠狠色噜噜狠狠狠7777奇米 | 日韩无套无码精品 | 正在播放东北夫妻内射 | 四虎国产精品免费久久 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 欧美亚洲日韩国产人成在线播放 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 俺去俺来也在线www色官网 | 亚洲日韩av片在线观看 | 欧美黑人巨大xxxxx | 久久久www成人免费毛片 | 无码吃奶揉捏奶头高潮视频 | 秋霞特色aa大片 | 国产精品igao视频网 | 无码人中文字幕 | 亚洲欧洲日本无在线码 | 久久久精品456亚洲影院 | 精品无码国产一区二区三区av | 老熟女重囗味hdxx69 | 国产精品爱久久久久久久 | 中文字幕乱码亚洲无线三区 | 国产舌乚八伦偷品w中 | 国产在线精品一区二区高清不卡 | 水蜜桃色314在线观看 | 亚洲中文字幕成人无码 | 国产高清av在线播放 | 欧美丰满老熟妇xxxxx性 | 丰满少妇女裸体bbw | 精品久久久久香蕉网 | 又大又紧又粉嫩18p少妇 | 在教室伦流澡到高潮hnp视频 | 精品久久久中文字幕人妻 | 欧洲极品少妇 | 性色欲网站人妻丰满中文久久不卡 | 无码av岛国片在线播放 | 国产精品香蕉在线观看 | 色诱久久久久综合网ywww | 蜜桃视频插满18在线观看 | 免费观看又污又黄的网站 | 国产麻豆精品精东影业av网站 | 国产成人无码a区在线观看视频app | 亚洲aⅴ无码成人网站国产app | a片免费视频在线观看 | 国产亚洲日韩欧美另类第八页 | 国产乱码精品一品二品 | 久久久久久久女国产乱让韩 | 亚洲国产日韩a在线播放 | 在线а√天堂中文官网 | 黑人粗大猛烈进出高潮视频 | 亚洲色欲色欲欲www在线 | 中文字幕av日韩精品一区二区 | 无码人妻精品一区二区三区不卡 | 国产亚洲精品久久久久久大师 | 国产亚洲精品久久久久久久久动漫 | 成年美女黄网站色大免费视频 | 日韩视频 中文字幕 视频一区 | 国产人妻久久精品二区三区老狼 | 日韩精品一区二区av在线 | 久久国语露脸国产精品电影 | 亚洲色偷偷男人的天堂 | 一区二区传媒有限公司 | 国产精品手机免费 | 免费无码午夜福利片69 | 伊人久久大香线蕉亚洲 | 色婷婷久久一区二区三区麻豆 | 蜜桃视频插满18在线观看 | 无遮无挡爽爽免费视频 | 国产猛烈高潮尖叫视频免费 | 乱人伦人妻中文字幕无码 | 日韩欧美中文字幕公布 | 国产在线aaa片一区二区99 | 老熟女重囗味hdxx69 | 欧美xxxxx精品 | 少妇无套内谢久久久久 | 九九热爱视频精品 | 色窝窝无码一区二区三区色欲 | 午夜精品一区二区三区在线观看 | 99久久人妻精品免费二区 | 国产精品久久久久影院嫩草 | 综合人妻久久一区二区精品 | 一二三四在线观看免费视频 | av人摸人人人澡人人超碰下载 | 乌克兰少妇性做爰 | 麻豆国产人妻欲求不满 | 国产精品多人p群无码 | 午夜不卡av免费 一本久久a久久精品vr综合 | 亚洲欧美国产精品久久 | 免费乱码人妻系列无码专区 | 国内综合精品午夜久久资源 | 久久精品视频在线看15 | 国产成人精品三级麻豆 | 波多野结衣av一区二区全免费观看 | 人妻体内射精一区二区三四 | 又粗又大又硬又长又爽 | 亚洲人成影院在线无码按摩店 | 麻豆国产人妻欲求不满 | 呦交小u女精品视频 | 妺妺窝人体色www在线小说 | 夜精品a片一区二区三区无码白浆 | 伊人色综合久久天天小片 | 玩弄少妇高潮ⅹxxxyw | 久激情内射婷内射蜜桃人妖 | 欧美人与善在线com | 中文字幕乱码人妻二区三区 | 中文字幕日韩精品一区二区三区 | 曰韩无码二三区中文字幕 | 强辱丰满人妻hd中文字幕 | 玩弄人妻少妇500系列视频 | 乱码午夜-极国产极内射 | 国产欧美精品一区二区三区 | 99久久精品无码一区二区毛片 | 国产情侣作爱视频免费观看 | 亚洲人交乣女bbw | 欧美日本免费一区二区三区 | 最近免费中文字幕中文高清百度 | 亚洲自偷自偷在线制服 | 丰满人妻被黑人猛烈进入 | 久久久久久久久蜜桃 | 午夜丰满少妇性开放视频 | 少妇人妻大乳在线视频 | www国产精品内射老师 | 高潮毛片无遮挡高清免费视频 | 亚洲色偷偷男人的天堂 | 欧美大屁股xxxxhd黑色 | 99久久久国产精品无码免费 | 国产真实夫妇视频 | 午夜理论片yy44880影院 | 亚洲日本va中文字幕 | 人人爽人人澡人人高潮 | 国产午夜福利100集发布 | 丰满少妇高潮惨叫视频 | 99久久久无码国产精品免费 | 天堂亚洲2017在线观看 | 久久天天躁夜夜躁狠狠 | 国产xxx69麻豆国语对白 | 国产偷抇久久精品a片69 | 国产一区二区三区精品视频 | 午夜不卡av免费 一本久久a久久精品vr综合 | 欧美xxxx黑人又粗又长 | 国产成人精品视频ⅴa片软件竹菊 | 一本久久伊人热热精品中文字幕 | 伊人久久婷婷五月综合97色 | 日韩无套无码精品 | 丝袜足控一区二区三区 | 成人女人看片免费视频放人 | 成人一在线视频日韩国产 | 国产乱人伦偷精品视频 | 国产卡一卡二卡三 | 丰满诱人的人妻3 | 红桃av一区二区三区在线无码av | 天堂一区人妻无码 | 成人av无码一区二区三区 | 久久精品国产一区二区三区 | 亚洲精品一区二区三区在线观看 | 亚洲精品一区二区三区在线观看 | 国内精品人妻无码久久久影院 | 两性色午夜视频免费播放 | 国产香蕉97碰碰久久人人 | 中文字幕无码av波多野吉衣 | 熟女俱乐部五十路六十路av | 性色欲网站人妻丰满中文久久不卡 | 精品一二三区久久aaa片 | 国产明星裸体无码xxxx视频 | 午夜精品一区二区三区在线观看 | 国产成人一区二区三区别 | 亚洲成av人影院在线观看 | 欧美日本免费一区二区三区 | 国产成人人人97超碰超爽8 | 高清无码午夜福利视频 | 久久综合久久自在自线精品自 | 亚洲中文字幕无码中字 | 免费人成在线观看网站 | www成人国产高清内射 | 一本色道婷婷久久欧美 | 99精品国产综合久久久久五月天 | 欧美丰满少妇xxxx性 | 亚洲理论电影在线观看 | 理论片87福利理论电影 | 宝宝好涨水快流出来免费视频 | 日韩欧美中文字幕公布 | 国产成人一区二区三区在线观看 | 伊人久久大香线焦av综合影院 | 夜先锋av资源网站 | 欧美性生交xxxxx久久久 | 亚洲码国产精品高潮在线 | 午夜福利一区二区三区在线观看 | 男人的天堂2018无码 | 熟女少妇人妻中文字幕 | 国产精华av午夜在线观看 | 无遮无挡爽爽免费视频 | 成年美女黄网站色大免费视频 | 久久99精品久久久久婷婷 | 亚洲欧洲无卡二区视頻 | 久久综合香蕉国产蜜臀av | 欧美第一黄网免费网站 | www国产亚洲精品久久久日本 | 亚洲精品久久久久久久久久久 | 97精品人妻一区二区三区香蕉 | 性色欲情网站iwww九文堂 | 亚洲中文字幕久久无码 | 国内揄拍国内精品人妻 | 天海翼激烈高潮到腰振不止 | 特级做a爰片毛片免费69 | 国产乱人伦偷精品视频 | 国内精品久久毛片一区二区 | 亚洲成av人影院在线观看 | 人妻与老人中文字幕 | 中文字幕日产无线码一区 | 国产三级久久久精品麻豆三级 | 亚洲色偷偷偷综合网 | 人妻插b视频一区二区三区 | 一二三四社区在线中文视频 | 鲁鲁鲁爽爽爽在线视频观看 | 大肉大捧一进一出好爽视频 | 亚洲小说图区综合在线 | 国产偷国产偷精品高清尤物 | 国产精品自产拍在线观看 | 亚洲国产av精品一区二区蜜芽 | 亚洲色大成网站www国产 | 国产精品自产拍在线观看 | 少女韩国电视剧在线观看完整 | 精品亚洲韩国一区二区三区 | 亚洲一区二区三区国产精华液 | 国产精品美女久久久 | 精品熟女少妇av免费观看 | 天天躁夜夜躁狠狠是什么心态 | 无码人妻丰满熟妇区五十路百度 | 久久精品国产一区二区三区肥胖 | 亚洲日本va午夜在线电影 | 性色欲网站人妻丰满中文久久不卡 | 亚洲精品午夜国产va久久成人 | 东京热一精品无码av | 国产精品人人妻人人爽 | 日日天干夜夜狠狠爱 | v一区无码内射国产 | 国产精品鲁鲁鲁 | 亚洲天堂2017无码 | 水蜜桃亚洲一二三四在线 | 麻豆av传媒蜜桃天美传媒 | 亚洲精品午夜无码电影网 | 国产成人无码午夜视频在线观看 | 午夜时刻免费入口 | 精品久久久久久亚洲精品 | 亚洲日韩av一区二区三区中文 | 免费无码午夜福利片69 | 又粗又大又硬毛片免费看 | 亲嘴扒胸摸屁股激烈网站 | 丝袜美腿亚洲一区二区 | 老司机亚洲精品影院无码 | 国产综合在线观看 | 婷婷五月综合激情中文字幕 | 清纯唯美经典一区二区 | 国产综合在线观看 | √8天堂资源地址中文在线 | 精品久久久中文字幕人妻 | 成人免费视频视频在线观看 免费 | 色婷婷综合中文久久一本 | www国产亚洲精品久久久日本 | 久久久中文字幕日本无吗 | 国产香蕉尹人综合在线观看 | 377p欧洲日本亚洲大胆 | 少女韩国电视剧在线观看完整 | 亚洲国产av精品一区二区蜜芽 | 99久久精品午夜一区二区 | 无码中文字幕色专区 | 婷婷色婷婷开心五月四房播播 | 日韩人妻无码一区二区三区久久99 | 婷婷色婷婷开心五月四房播播 | 少妇人妻大乳在线视频 | 日日噜噜噜噜夜夜爽亚洲精品 | 九一九色国产 | 熟妇人妻无码xxx视频 | 女人被男人躁得好爽免费视频 | 精品无码一区二区三区的天堂 | 国产成人无码av片在线观看不卡 | 国产极品美女高潮无套在线观看 | 永久黄网站色视频免费直播 | 国产成人综合色在线观看网站 | 国产日产欧产精品精品app | 九九热爱视频精品 | 无码av免费一区二区三区试看 | 大地资源中文第3页 | 国产精品福利视频导航 | 无遮无挡爽爽免费视频 | 久久精品成人欧美大片 | 国产成人一区二区三区在线观看 | 日韩欧美成人免费观看 | 国语精品一区二区三区 | 1000部啪啪未满十八勿入下载 | 亚洲七七久久桃花影院 | 久久www免费人成人片 | 国产精品高潮呻吟av久久 | a国产一区二区免费入口 | 久久aⅴ免费观看 | 中文字幕av无码一区二区三区电影 | 国产激情无码一区二区 | 亚洲色偷偷偷综合网 | 日产精品99久久久久久 | 亚洲欧美中文字幕5发布 | 亚洲中文字幕乱码av波多ji | 久久精品人人做人人综合 | 国产无遮挡又黄又爽又色 | 成年美女黄网站色大免费视频 | 无套内谢老熟女 | 99re在线播放 | 装睡被陌生人摸出水好爽 | 国产无遮挡又黄又爽又色 | 亚洲熟女一区二区三区 | 亚洲天堂2017无码 | 少妇愉情理伦片bd | 99久久精品无码一区二区毛片 | 超碰97人人射妻 | 日日橹狠狠爱欧美视频 | 精品欧洲av无码一区二区三区 | 女人被男人躁得好爽免费视频 | 亚洲成av人综合在线观看 | 久久99精品久久久久久动态图 | 人人妻人人澡人人爽欧美一区 | 一本久久伊人热热精品中文字幕 | 超碰97人人射妻 | 人妻插b视频一区二区三区 | 在线视频网站www色 | 国产综合色产在线精品 | 久久综合色之久久综合 | 国产特级毛片aaaaaaa高清 | 色情久久久av熟女人妻网站 | 精品无码av一区二区三区 | 一本一道久久综合久久 | 性史性农村dvd毛片 | 国产精品久久久久久亚洲影视内衣 | 国产国语老龄妇女a片 | 99久久久国产精品无码免费 | 亚洲精品久久久久久久久久久 | 狠狠色噜噜狠狠狠狠7777米奇 | 亚洲精品成人av在线 | 免费无码av一区二区 | 亚洲熟妇色xxxxx欧美老妇y | 久久精品中文字幕一区 | 东京热无码av男人的天堂 | 97夜夜澡人人爽人人喊中国片 | 久久久www成人免费毛片 | 999久久久国产精品消防器材 | 欧美性猛交内射兽交老熟妇 | 亚洲中文字幕成人无码 | 国产va免费精品观看 | 欧洲欧美人成视频在线 | 最近免费中文字幕中文高清百度 | а天堂中文在线官网 | 领导边摸边吃奶边做爽在线观看 | 人妻aⅴ无码一区二区三区 | 国产乡下妇女做爰 | 亚洲熟妇自偷自拍另类 | 丰满少妇女裸体bbw | 日本成熟视频免费视频 | 红桃av一区二区三区在线无码av | 国产免费观看黄av片 | 欧美黑人乱大交 | 亚洲 另类 在线 欧美 制服 | 久久这里只有精品视频9 | 夜夜高潮次次欢爽av女 | 国产免费久久久久久无码 | 亚洲精品一区二区三区在线 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 欧美自拍另类欧美综合图片区 | 亚洲熟悉妇女xxx妇女av | 婷婷丁香六月激情综合啪 | 亚洲国产精品成人久久蜜臀 | 亚洲熟妇色xxxxx亚洲 | 双乳奶水饱满少妇呻吟 | 思思久久99热只有频精品66 | 九九久久精品国产免费看小说 | 欧美黑人性暴力猛交喷水 | 天天综合网天天综合色 | 曰韩无码二三区中文字幕 | 欧美大屁股xxxxhd黑色 | 午夜理论片yy44880影院 | 国产亚洲欧美日韩亚洲中文色 | 久久无码中文字幕免费影院蜜桃 | 国产高潮视频在线观看 | 中文精品久久久久人妻不卡 | 中文字幕人成乱码熟女app | 99久久亚洲精品无码毛片 | 国产人妻人伦精品1国产丝袜 | 久久国产精品精品国产色婷婷 | 国产极品美女高潮无套在线观看 | 国产日产欧产精品精品app | 欧美精品无码一区二区三区 | 欧美性猛交内射兽交老熟妇 | 中文字幕无码乱人伦 | 国产亚洲欧美日韩亚洲中文色 | 麻豆国产人妻欲求不满 | 久久久久久av无码免费看大片 | 亚洲熟妇色xxxxx欧美老妇y | 中文字幕乱码人妻无码久久 | 国产精品久久国产精品99 | 亚洲国产精品久久久久久 | 中文字幕 人妻熟女 | 亚洲成a人片在线观看无码3d | 国产精品毛多多水多 | 精品国产aⅴ无码一区二区 | 国产亚洲精品精品国产亚洲综合 | 人人澡人人妻人人爽人人蜜桃 | 扒开双腿疯狂进出爽爽爽视频 | 久久99久久99精品中文字幕 | 丰满少妇弄高潮了www | 精品成人av一区二区三区 | 中文字幕人成乱码熟女app | 天天综合网天天综合色 | 久久午夜无码鲁丝片秋霞 | 国产极品美女高潮无套在线观看 | 久久久久久久人妻无码中文字幕爆 | 无码成人精品区在线观看 | 鲁鲁鲁爽爽爽在线视频观看 | 亚洲第一无码av无码专区 | 秋霞成人午夜鲁丝一区二区三区 | 欧美人与善在线com | 日产精品高潮呻吟av久久 | 国产日产欧产精品精品app | 日产国产精品亚洲系列 | 精品国产国产综合精品 | 国产亚洲精品久久久久久久 | 国内精品一区二区三区不卡 | 亚洲成a人片在线观看无码3d | 精品国产青草久久久久福利 | 麻豆果冻传媒2021精品传媒一区下载 | 国产特级毛片aaaaaaa高清 | 未满小14洗澡无码视频网站 | 亚洲国产精品久久人人爱 | 欧美第一黄网免费网站 | 久久久久久久人妻无码中文字幕爆 | 亚洲国产欧美在线成人 | 欧美自拍另类欧美综合图片区 | 日日摸日日碰夜夜爽av | 亚洲综合无码一区二区三区 | 欧美性生交活xxxxxdddd | 亚洲欧洲日本无在线码 | 无码吃奶揉捏奶头高潮视频 | 波多野结衣乳巨码无在线观看 | 国产精品怡红院永久免费 | 国产精品资源一区二区 | 国精品人妻无码一区二区三区蜜柚 | 国产内射爽爽大片视频社区在线 | 亚洲一区二区观看播放 | 最新国产麻豆aⅴ精品无码 | 亚洲午夜久久久影院 | 99久久久无码国产aaa精品 | 内射老妇bbwx0c0ck | 少妇激情av一区二区 | 久久成人a毛片免费观看网站 | 日韩亚洲欧美中文高清在线 | 日本乱人伦片中文三区 | 欧美第一黄网免费网站 | 国产婷婷色一区二区三区在线 | 色综合久久88色综合天天 | 国产手机在线αⅴ片无码观看 | 国产成人一区二区三区在线观看 | 国产人妻精品一区二区三区不卡 | 九九在线中文字幕无码 | 无码毛片视频一区二区本码 | 精品国产av色一区二区深夜久久 | 精品偷自拍另类在线观看 | 少妇无码一区二区二三区 | 永久免费观看美女裸体的网站 | 成在人线av无码免费 | 欧美猛少妇色xxxxx | 国产高清不卡无码视频 | 成人欧美一区二区三区黑人免费 | 国产小呦泬泬99精品 | 99精品久久毛片a片 | 久久久久久国产精品无码下载 | 亚洲国产精品无码久久久久高潮 | 蜜桃无码一区二区三区 | 日韩av无码一区二区三区不卡 | 日韩精品无码一区二区中文字幕 | 久久亚洲日韩精品一区二区三区 | 国精产品一品二品国精品69xx | 亚洲中文字幕无码中字 | 久久久婷婷五月亚洲97号色 | 天堂无码人妻精品一区二区三区 | 乱中年女人伦av三区 | 成人片黄网站色大片免费观看 | 精品国产一区二区三区av 性色 | 色婷婷久久一区二区三区麻豆 | 一本色道久久综合狠狠躁 | 一本精品99久久精品77 | aa片在线观看视频在线播放 | 亚洲精品国产第一综合99久久 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 国产成人无码a区在线观看视频app | 夜夜躁日日躁狠狠久久av | 无码av中文字幕免费放 | 熟女少妇人妻中文字幕 | 人人妻人人澡人人爽欧美一区九九 | 亚洲国产一区二区三区在线观看 | 日产精品高潮呻吟av久久 | 欧美激情综合亚洲一二区 | 少妇久久久久久人妻无码 | 日产国产精品亚洲系列 | 人妻少妇精品无码专区二区 | 久久综合激激的五月天 | 婷婷丁香五月天综合东京热 | 欧美国产亚洲日韩在线二区 | 国产熟妇高潮叫床视频播放 | 性欧美牲交在线视频 | 永久免费精品精品永久-夜色 | 激情五月综合色婷婷一区二区 | 国产人成高清在线视频99最全资源 | 丰满护士巨好爽好大乳 | 国产精品久久久一区二区三区 | 丰满护士巨好爽好大乳 | 国精品人妻无码一区二区三区蜜柚 | 无码人妻丰满熟妇区五十路百度 | 99久久婷婷国产综合精品青草免费 | 日欧一片内射va在线影院 | 日本丰满熟妇videos | 亚洲国产欧美国产综合一区 | 亚洲欧洲中文日韩av乱码 | 亚洲小说图区综合在线 | 国产猛烈高潮尖叫视频免费 | 中国女人内谢69xxxxxa片 | 波多野42部无码喷潮在线 | 真人与拘做受免费视频一 | 76少妇精品导航 | 六月丁香婷婷色狠狠久久 | 国产高清不卡无码视频 | 中文字幕无码av波多野吉衣 | 成人免费无码大片a毛片 | 少妇性俱乐部纵欲狂欢电影 | 欧美自拍另类欧美综合图片区 | 一本色道久久综合亚洲精品不卡 | 亚洲欧美日韩综合久久久 | 国产日产欧产精品精品app | 天天综合网天天综合色 | 女人色极品影院 | 少妇无码av无码专区在线观看 | www国产亚洲精品久久网站 | 欧美一区二区三区 | 在教室伦流澡到高潮hnp视频 | www一区二区www免费 | 无码国产激情在线观看 | 清纯唯美经典一区二区 | 午夜无码人妻av大片色欲 | 国产乡下妇女做爰 | 精品国产福利一区二区 | 色狠狠av一区二区三区 | 成人片黄网站色大片免费观看 | 国产精品亚洲一区二区三区喷水 | 亚洲欧美综合区丁香五月小说 | 中文字幕 亚洲精品 第1页 | 亚洲欧美精品伊人久久 | 国产香蕉97碰碰久久人人 | 午夜精品久久久内射近拍高清 | 午夜无码人妻av大片色欲 | 99久久久国产精品无码免费 | 日日夜夜撸啊撸 | 又色又爽又黄的美女裸体网站 | 亚洲人成网站色7799 | 丰满人妻精品国产99aⅴ | 中文无码伦av中文字幕 | 亚洲综合无码久久精品综合 | 国产三级久久久精品麻豆三级 | 沈阳熟女露脸对白视频 | 亚洲国产精华液网站w | 日欧一片内射va在线影院 | 亚洲成熟女人毛毛耸耸多 | av在线亚洲欧洲日产一区二区 | 日本高清一区免费中文视频 | 狠狠色色综合网站 | 亚洲gv猛男gv无码男同 | 性欧美牲交xxxxx视频 | 性史性农村dvd毛片 | 国产精品va在线观看无码 | 爆乳一区二区三区无码 | 国产特级毛片aaaaaa高潮流水 | 东京热无码av男人的天堂 | 国产亚洲精品久久久久久国模美 | 成人无码视频免费播放 | 亚洲精品鲁一鲁一区二区三区 | 啦啦啦www在线观看免费视频 | 荡女精品导航 | 任你躁国产自任一区二区三区 | 国内揄拍国内精品人妻 | 2020久久香蕉国产线看观看 | 亚洲爆乳精品无码一区二区三区 | 98国产精品综合一区二区三区 | 亚洲乱码国产乱码精品精 | 人人妻人人澡人人爽欧美一区 | 中文字幕乱码中文乱码51精品 | 一个人免费观看的www视频 | 中文无码成人免费视频在线观看 | 欧美兽交xxxx×视频 | 欧美兽交xxxx×视频 | 荫蒂添的好舒服视频囗交 | 中文字幕人妻丝袜二区 | 日韩人妻少妇一区二区三区 | 性啪啪chinese东北女人 | 久久天天躁狠狠躁夜夜免费观看 | 双乳奶水饱满少妇呻吟 | 国产两女互慰高潮视频在线观看 | 欧美日韩精品 | 精品欧美一区二区三区久久久 | 一本色道婷婷久久欧美 | 最近免费中文字幕中文高清百度 | 亚洲日韩精品欧美一区二区 | 久久99精品久久久久久动态图 | 亚洲天堂2017无码中文 | 国产欧美精品一区二区三区 | 精品国产青草久久久久福利 | 久久无码中文字幕免费影院蜜桃 | 精品久久久久久人妻无码中文字幕 | 国色天香社区在线视频 | 亚洲国产精品毛片av不卡在线 | 纯爱无遮挡h肉动漫在线播放 | 蜜桃av抽搐高潮一区二区 | 久久国产精品精品国产色婷婷 | 日韩精品无码一区二区中文字幕 | 在线观看免费人成视频 | 久久久中文久久久无码 | 图片小说视频一区二区 | 少妇愉情理伦片bd | 国产亚洲精品久久久久久国模美 | 亚洲中文字幕无码中字 | 日韩av激情在线观看 | 欧美喷潮久久久xxxxx | 最近的中文字幕在线看视频 | 亚洲成av人片天堂网无码】 | 天天做天天爱天天爽综合网 | 99久久久国产精品无码免费 | 成人精品天堂一区二区三区 | 丰满少妇人妻久久久久久 | 欧美人妻一区二区三区 | 性色av无码免费一区二区三区 | 清纯唯美经典一区二区 | 国产偷国产偷精品高清尤物 | 国产精品毛多多水多 | 日日橹狠狠爱欧美视频 | 欧美激情综合亚洲一二区 | aⅴ在线视频男人的天堂 | 小sao货水好多真紧h无码视频 | 爽爽影院免费观看 | 无码人妻精品一区二区三区不卡 | 亚洲精品一区二区三区四区五区 | 99久久久无码国产aaa精品 | 波多野结衣 黑人 | 人妻插b视频一区二区三区 | 色婷婷综合激情综在线播放 | 人人妻人人澡人人爽人人精品 | 97久久精品无码一区二区 | ass日本丰满熟妇pics | 免费无码午夜福利片69 | 久久aⅴ免费观看 | 大乳丰满人妻中文字幕日本 | 国产精品理论片在线观看 | 少女韩国电视剧在线观看完整 | 久久久久久久女国产乱让韩 | 波多野结衣av在线观看 | 欧美日韩在线亚洲综合国产人 | 国产va免费精品观看 | 免费人成网站视频在线观看 | 麻豆果冻传媒2021精品传媒一区下载 | 欧美激情一区二区三区成人 | 日本精品高清一区二区 | 大地资源中文第3页 | 国产无套内射久久久国产 | 亚洲国产精品毛片av不卡在线 | 国内少妇偷人精品视频 | 亚洲熟悉妇女xxx妇女av | 欧美喷潮久久久xxxxx | 国产乱人伦偷精品视频 | 亚洲成av人综合在线观看 | 一区二区传媒有限公司 | 大肉大捧一进一出好爽视频 | 国产精品久久久一区二区三区 | 国产精品怡红院永久免费 | 日本熟妇人妻xxxxx人hd | 国产激情无码一区二区 | 99精品无人区乱码1区2区3区 | 在线a亚洲视频播放在线观看 | 国产精品久久久午夜夜伦鲁鲁 | 水蜜桃亚洲一二三四在线 | 日韩亚洲欧美精品综合 | 亚洲中文字幕无码一久久区 | 国产精品免费大片 | 好男人社区资源 | 欧美成人午夜精品久久久 | 国产精品美女久久久网av | 十八禁视频网站在线观看 | 黑人大群体交免费视频 | 欧美成人午夜精品久久久 | 无码人妻久久一区二区三区不卡 | 久久午夜无码鲁丝片秋霞 | 高中生自慰www网站 | 激情爆乳一区二区三区 | 无码人妻久久一区二区三区不卡 | 中文字幕无码人妻少妇免费 | 天天拍夜夜添久久精品大 | 强辱丰满人妻hd中文字幕 | 97色伦图片97综合影院 | 久久综合给合久久狠狠狠97色 | 国产xxx69麻豆国语对白 | 国产成人精品一区二区在线小狼 | 午夜福利电影 | 人妻少妇精品视频专区 | 伊人色综合久久天天小片 | 18黄暴禁片在线观看 | 久久人人爽人人人人片 | 中文字幕av伊人av无码av | 成人毛片一区二区 | 日产精品高潮呻吟av久久 | 国产麻豆精品一区二区三区v视界 | 欧美 丝袜 自拍 制服 另类 | 婷婷六月久久综合丁香 | 午夜精品久久久内射近拍高清 | 妺妺窝人体色www在线小说 | 精品一二三区久久aaa片 | 牲欲强的熟妇农村老妇女 | 99久久久国产精品无码免费 | 97久久国产亚洲精品超碰热 | 无码人妻精品一区二区三区下载 | 久久亚洲日韩精品一区二区三区 | 亚洲国产成人a精品不卡在线 | 丝袜美腿亚洲一区二区 | 欧美人妻一区二区三区 | 国产精品办公室沙发 | 蜜臀aⅴ国产精品久久久国产老师 | 黑人粗大猛烈进出高潮视频 | 无码毛片视频一区二区本码 | 澳门永久av免费网站 | 久久久成人毛片无码 | 久久99精品国产.久久久久 | 巨爆乳无码视频在线观看 | 欧美 日韩 人妻 高清 中文 | 国产免费久久精品国产传媒 | 人人妻人人澡人人爽人人精品浪潮 | 久久久久成人精品免费播放动漫 | 无码av岛国片在线播放 | 亚洲 a v无 码免 费 成 人 a v | 玩弄中年熟妇正在播放 | 中文无码成人免费视频在线观看 | 性欧美videos高清精品 | 国产艳妇av在线观看果冻传媒 | 久久精品人人做人人综合 | 亚洲欧美中文字幕5发布 | 国产内射老熟女aaaa | 成人精品一区二区三区中文字幕 | 欧美日韩一区二区免费视频 | 亚洲精品国偷拍自产在线观看蜜桃 | 88国产精品欧美一区二区三区 | 人妻与老人中文字幕 | 久久人妻内射无码一区三区 | 免费无码的av片在线观看 | 午夜熟女插插xx免费视频 | 国产精品久久久久久亚洲影视内衣 | 亚洲s码欧洲m码国产av | 国产亚av手机在线观看 | 久久久av男人的天堂 | 四十如虎的丰满熟妇啪啪 | 日韩精品成人一区二区三区 | 欧美日韩一区二区三区自拍 | 欧美性猛交xxxx富婆 | 99久久精品无码一区二区毛片 | 久青草影院在线观看国产 | 久久99精品久久久久久动态图 | 无码人妻精品一区二区三区下载 | aⅴ亚洲 日韩 色 图网站 播放 | 亚洲热妇无码av在线播放 | 两性色午夜视频免费播放 | 少妇愉情理伦片bd | 纯爱无遮挡h肉动漫在线播放 | 亚洲国产精品久久久久久 | 啦啦啦www在线观看免费视频 | 风流少妇按摩来高潮 | 国产莉萝无码av在线播放 | 亚洲一区二区三区偷拍女厕 | 色诱久久久久综合网ywww | 成人性做爰aaa片免费看 | 四虎永久在线精品免费网址 | 久久精品国产日本波多野结衣 | 亚洲中文字幕va福利 | 综合人妻久久一区二区精品 | 色情久久久av熟女人妻网站 | 中文字幕+乱码+中文字幕一区 | 久久久精品国产sm最大网站 | 俺去俺来也www色官网 | 波多野结衣av一区二区全免费观看 | 伊人久久婷婷五月综合97色 | 亚洲一区二区观看播放 | 麻豆果冻传媒2021精品传媒一区下载 | 国内揄拍国内精品人妻 | 亚洲狠狠色丁香婷婷综合 | 18精品久久久无码午夜福利 | 久久久久99精品国产片 | 欧美xxxx黑人又粗又长 | 亚洲七七久久桃花影院 | 国产免费观看黄av片 | 久久国产精品萌白酱免费 | 国产欧美精品一区二区三区 | 国产精品第一区揄拍无码 | 日本欧美一区二区三区乱码 | 久久久www成人免费毛片 | 免费无码肉片在线观看 | 国产精品毛片一区二区 | 天天拍夜夜添久久精品大 | 在线播放无码字幕亚洲 | 成 人 免费观看网站 | 无码任你躁久久久久久久 | 亚洲人成影院在线无码按摩店 | 精品国产一区二区三区四区 | 性做久久久久久久免费看 | 成人一区二区免费视频 | 亚洲国产av精品一区二区蜜芽 | 国产99久久精品一区二区 | 精品久久久久久人妻无码中文字幕 | 国産精品久久久久久久 | 国产激情无码一区二区 | 又大又黄又粗又爽的免费视频 | 久久精品国产大片免费观看 | 免费看男女做好爽好硬视频 | 日日碰狠狠躁久久躁蜜桃 | 日本护士xxxxhd少妇 | 亚洲成熟女人毛毛耸耸多 | 乱人伦中文视频在线观看 | 国产熟女一区二区三区四区五区 | 中文字幕av伊人av无码av | 亚洲天堂2017无码中文 | 性色欲网站人妻丰满中文久久不卡 | 牲欲强的熟妇农村老妇女视频 | 亚洲一区二区三区播放 | 中文精品无码中文字幕无码专区 | 国产办公室秘书无码精品99 | 人人妻在人人 | 亚洲热妇无码av在线播放 | 少妇一晚三次一区二区三区 | 夜夜躁日日躁狠狠久久av | 伊人久久大香线蕉亚洲 | 人人妻人人澡人人爽欧美一区 | 人妻插b视频一区二区三区 | av无码电影一区二区三区 | 亚洲精品国产精品乱码视色 | 亚洲精品成a人在线观看 | 人人爽人人爽人人片av亚洲 | 激情亚洲一区国产精品 | 99精品视频在线观看免费 | 亚洲精品国产精品乱码不卡 | 欧美老人巨大xxxx做受 | 激情综合激情五月俺也去 | 欧美变态另类xxxx | 亚洲综合无码一区二区三区 | 亚洲欧洲中文日韩av乱码 | 成人一在线视频日韩国产 | 国产在线aaa片一区二区99 | 亚洲 a v无 码免 费 成 人 a v | 色综合久久久无码网中文 | 欧美人与善在线com | 婷婷五月综合缴情在线视频 | 国产办公室秘书无码精品99 | 人人妻人人澡人人爽欧美精品 | 日韩 欧美 动漫 国产 制服 | 国产在线一区二区三区四区五区 | 亚洲成熟女人毛毛耸耸多 | 免费观看的无遮挡av | 亚洲精品综合五月久久小说 | 久久人人爽人人爽人人片ⅴ | 亚洲精品一区三区三区在线观看 | 人妻无码久久精品人妻 | 中文字幕无码av激情不卡 | 特级做a爰片毛片免费69 | 国内综合精品午夜久久资源 | 任你躁在线精品免费 | 国内精品一区二区三区不卡 | 无遮挡国产高潮视频免费观看 | 亚洲成a人片在线观看无码3d | 亚洲精品综合一区二区三区在线 | 欧美激情综合亚洲一二区 | 天天摸天天透天天添 | 免费网站看v片在线18禁无码 | 国色天香社区在线视频 | 无码人妻精品一区二区三区下载 | 偷窥日本少妇撒尿chinese | 国产av人人夜夜澡人人爽麻豆 | 野外少妇愉情中文字幕 | 亚洲a无码综合a国产av中文 | 国产精品久久久久影院嫩草 | √天堂资源地址中文在线 | 国产精品-区区久久久狼 | 5858s亚洲色大成网站www | 少妇太爽了在线观看 | 熟妇激情内射com | 日本精品少妇一区二区三区 | 成人免费视频一区二区 | 精品夜夜澡人妻无码av蜜桃 | 呦交小u女精品视频 | 国产熟妇高潮叫床视频播放 | 久久伊人色av天堂九九小黄鸭 | 久久精品国产日本波多野结衣 | 亚洲精品美女久久久久久久 | 久久久久久久久蜜桃 | 日本大香伊一区二区三区 | 亚洲人成人无码网www国产 | 国产成人综合在线女婷五月99播放 | 图片小说视频一区二区 | 亚洲精品综合一区二区三区在线 | 精品熟女少妇av免费观看 | 中文字幕+乱码+中文字幕一区 | 麻花豆传媒剧国产免费mv在线 | 久久www免费人成人片 | 97se亚洲精品一区 | 国产三级精品三级男人的天堂 | 狠狠亚洲超碰狼人久久 | 人妻少妇被猛烈进入中文字幕 | 欧美 亚洲 国产 另类 | 中文字幕中文有码在线 | 亚洲精品午夜国产va久久成人 | 草草网站影院白丝内射 | √天堂中文官网8在线 | 丰满人妻一区二区三区免费视频 | v一区无码内射国产 | 欧美丰满老熟妇xxxxx性 | 日本在线高清不卡免费播放 | 国产精品自产拍在线观看 | 精品人妻人人做人人爽 | 高清不卡一区二区三区 | 国产精品丝袜黑色高跟鞋 | 18禁止看的免费污网站 | 国产卡一卡二卡三 | 黑森林福利视频导航 | 亚洲人成网站免费播放 | 成人试看120秒体验区 | aⅴ亚洲 日韩 色 图网站 播放 | 久久久久成人片免费观看蜜芽 | 捆绑白丝粉色jk震动捧喷白浆 | 欧美野外疯狂做受xxxx高潮 | 国产精品永久免费视频 | 人人妻人人澡人人爽欧美一区 | 日韩人妻无码中文字幕视频 | 欧美 丝袜 自拍 制服 另类 | 中文字幕无码日韩专区 | 国产成人精品无码播放 | 波多野结衣av在线观看 | 精品久久久中文字幕人妻 | 人妻aⅴ无码一区二区三区 | 图片区 小说区 区 亚洲五月 | 天堂а√在线地址中文在线 | 中文字幕无码热在线视频 | 精品少妇爆乳无码av无码专区 | 大乳丰满人妻中文字幕日本 | 亚洲无人区一区二区三区 | 免费视频欧美无人区码 | 国产无遮挡吃胸膜奶免费看 | 日本免费一区二区三区最新 | 国产成人精品一区二区在线小狼 | 亚洲国产精品久久久天堂 | 日韩精品一区二区av在线 | 男女性色大片免费网站 | 欧美第一黄网免费网站 | 国产综合在线观看 | 激情爆乳一区二区三区 | 中文无码伦av中文字幕 | 国产色视频一区二区三区 | 精品厕所偷拍各类美女tp嘘嘘 | 国产又爽又猛又粗的视频a片 | 中文字幕无码免费久久99 | 亚洲乱码国产乱码精品精 | 无码av岛国片在线播放 | 四虎影视成人永久免费观看视频 | 午夜精品久久久内射近拍高清 | 岛国片人妻三上悠亚 | 香蕉久久久久久av成人 | а√天堂www在线天堂小说 | 亚洲精品一区二区三区大桥未久 | 久久久久人妻一区精品色欧美 | 久久精品国产99久久6动漫 | 在线精品国产一区二区三区 | 色五月五月丁香亚洲综合网 | 5858s亚洲色大成网站www | 伦伦影院午夜理论片 | 亚洲成色www久久网站 | 亚洲成a人片在线观看日本 | aⅴ亚洲 日韩 色 图网站 播放 | 国产农村乱对白刺激视频 | 亚洲精品一区二区三区大桥未久 | 无码福利日韩神码福利片 | 伊人久久大香线蕉av一区二区 | 欧美性生交xxxxx久久久 | 国内精品久久毛片一区二区 | 日韩成人一区二区三区在线观看 | 99久久99久久免费精品蜜桃 | 奇米影视888欧美在线观看 | 久久久中文字幕日本无吗 | 欧美亚洲国产一区二区三区 | 亚洲熟妇色xxxxx欧美老妇 | 国产av无码专区亚洲a∨毛片 | 精品久久久中文字幕人妻 | 少女韩国电视剧在线观看完整 | 欧美xxxxx精品 | 人妻体内射精一区二区三四 | 久久无码专区国产精品s | 131美女爱做视频 | 正在播放东北夫妻内射 | 99国产精品白浆在线观看免费 | 国产精品久久久久9999小说 | 国色天香社区在线视频 | 免费无码av一区二区 | 久久国产36精品色熟妇 | 亚洲色偷偷偷综合网 | 亚洲精品久久久久久久久久久 | 久久久成人毛片无码 | 成年女人永久免费看片 | 男人的天堂2018无码 | 18禁黄网站男男禁片免费观看 | 国产精品高潮呻吟av久久 | 日本丰满熟妇videos | 久久久久成人片免费观看蜜芽 | 真人与拘做受免费视频 | 久久久久免费看成人影片 | 久久精品人妻少妇一区二区三区 | 天天爽夜夜爽夜夜爽 | 亚洲熟女一区二区三区 | 国产区女主播在线观看 | 兔费看少妇性l交大片免费 | 男人的天堂av网站 | 夜先锋av资源网站 | 99riav国产精品视频 | 午夜时刻免费入口 | 免费观看又污又黄的网站 | 撕开奶罩揉吮奶头视频 | 少妇一晚三次一区二区三区 | 欧美性黑人极品hd | 麻豆国产丝袜白领秘书在线观看 | 激情五月综合色婷婷一区二区 | 国产精品人人爽人人做我的可爱 | 亚洲一区二区观看播放 | 国产女主播喷水视频在线观看 | 国产成人精品视频ⅴa片软件竹菊 | 国内精品人妻无码久久久影院 | 99久久婷婷国产综合精品青草免费 | 亚洲精品一区三区三区在线观看 | 久久久成人毛片无码 | 久久成人a毛片免费观看网站 | 九九热爱视频精品 | 国产精品久久国产精品99 | 久久www免费人成人片 | 国产无遮挡吃胸膜奶免费看 | 少妇人妻大乳在线视频 | 无码纯肉视频在线观看 | 国产精品久久国产精品99 | 7777奇米四色成人眼影 | 性生交大片免费看l | 未满成年国产在线观看 | 国产免费久久精品国产传媒 | 久久久精品欧美一区二区免费 | 中国女人内谢69xxxxxa片 | 日韩av激情在线观看 | 国产又爽又猛又粗的视频a片 | 亚洲性无码av中文字幕 | 国产三级精品三级男人的天堂 | 男人和女人高潮免费网站 | 日本一卡2卡3卡四卡精品网站 | 日本一区二区三区免费高清 | 人妻无码αv中文字幕久久琪琪布 | 国产精品无码mv在线观看 | 欧美丰满熟妇xxxx性ppx人交 | 亚洲区小说区激情区图片区 | 国产熟妇另类久久久久 | 国产av剧情md精品麻豆 | 又黄又爽又色的视频 | 精品欧洲av无码一区二区三区 | 久久久亚洲欧洲日产国码αv | 色五月五月丁香亚洲综合网 | 欧美国产日韩久久mv | 无码精品人妻一区二区三区av | 色五月五月丁香亚洲综合网 | 东京热男人av天堂 | 亚洲熟妇色xxxxx亚洲 | 国产精品爱久久久久久久 | 色窝窝无码一区二区三区色欲 | 国产精品视频免费播放 | 国产午夜无码视频在线观看 | 国产又爽又黄又刺激的视频 | 亚洲精品欧美二区三区中文字幕 | 欧美熟妇另类久久久久久多毛 | 亚洲熟悉妇女xxx妇女av | 日韩人妻少妇一区二区三区 | 一本色道婷婷久久欧美 | 欧美阿v高清资源不卡在线播放 | 九九在线中文字幕无码 | 日日麻批免费40分钟无码 | 小鲜肉自慰网站xnxx | 日韩 欧美 动漫 国产 制服 | 东京热一精品无码av | 欧美丰满熟妇xxxx | 无码人妻精品一区二区三区下载 | 亚洲s色大片在线观看 | 免费国产成人高清在线观看网站 | 亚洲日韩av一区二区三区中文 | 成年女人永久免费看片 | 亚洲欧美综合区丁香五月小说 | 婷婷丁香五月天综合东京热 | 熟女俱乐部五十路六十路av | 欧美35页视频在线观看 | 久久精品无码一区二区三区 | 色综合久久中文娱乐网 | 国内精品人妻无码久久久影院蜜桃 | 一个人看的www免费视频在线观看 | 亚洲精品国产a久久久久久 | 国产亚洲视频中文字幕97精品 | 一二三四在线观看免费视频 | 成人无码视频免费播放 | 亚洲男人av天堂午夜在 | 亚洲成av人片天堂网无码】 | 精品无人区无码乱码毛片国产 | 久久久久亚洲精品中文字幕 | 国产成人精品一区二区在线小狼 | 成年女人永久免费看片 | 99久久久无码国产精品免费 | 亚洲男人av天堂午夜在 | 国内丰满熟女出轨videos | 国产猛烈高潮尖叫视频免费 | 国内精品人妻无码久久久影院蜜桃 | 中文字幕av伊人av无码av | 免费国产成人高清在线观看网站 | 亚洲精品综合五月久久小说 | 乱人伦中文视频在线观看 | 精品无码一区二区三区爱欲 | 久久久久亚洲精品中文字幕 | 玩弄人妻少妇500系列视频 | 国产精品久免费的黄网站 | 欧美日韩在线亚洲综合国产人 | 十八禁真人啪啪免费网站 | 欧美人与物videos另类 | 人妻少妇精品久久 | 高清不卡一区二区三区 | 午夜福利一区二区三区在线观看 | av无码久久久久不卡免费网站 | 亚洲精品久久久久avwww潮水 | 好屌草这里只有精品 | 在线观看国产午夜福利片 | 水蜜桃色314在线观看 | 久久久久久久女国产乱让韩 | 骚片av蜜桃精品一区 | 午夜无码人妻av大片色欲 | 久久精品国产99久久6动漫 | 少妇人妻大乳在线视频 | 青青青手机频在线观看 | 日本丰满护士爆乳xxxx | 中文字幕乱码人妻无码久久 | 搡女人真爽免费视频大全 | 亚洲精品午夜国产va久久成人 | 免费中文字幕日韩欧美 | 亚洲区欧美区综合区自拍区 | 成人免费视频在线观看 | 亚洲国产av美女网站 | 无遮挡国产高潮视频免费观看 | 在线a亚洲视频播放在线观看 | 久久久久亚洲精品男人的天堂 | 亚洲精品久久久久久一区二区 | 日韩av无码一区二区三区不卡 | 在线精品国产一区二区三区 | 国产精品久久久 | 久久午夜无码鲁丝片 | 六月丁香婷婷色狠狠久久 | 性色av无码免费一区二区三区 | 又粗又大又硬又长又爽 | 欧美黑人巨大xxxxx | 99视频精品全部免费免费观看 | 国产suv精品一区二区五 | 乱人伦人妻中文字幕无码 | 性欧美熟妇videofreesex | 久久五月精品中文字幕 | 欧美freesex黑人又粗又大 | 九九综合va免费看 | 色婷婷综合激情综在线播放 | 国产成人综合色在线观看网站 | 无码精品国产va在线观看dvd | 女高中生第一次破苞av | 亚洲一区二区观看播放 | 老熟女乱子伦 | 日本丰满熟妇videos | 一二三四社区在线中文视频 | 久久 国产 尿 小便 嘘嘘 | 97色伦图片97综合影院 | 帮老师解开蕾丝奶罩吸乳网站 | 帮老师解开蕾丝奶罩吸乳网站 | av在线亚洲欧洲日产一区二区 | 国产人妻人伦精品1国产丝袜 | 99久久亚洲精品无码毛片 | 亚拍精品一区二区三区探花 | 久久久久av无码免费网 | 国内精品九九久久久精品 | 国产熟妇另类久久久久 | 国产sm调教视频在线观看 | 东京无码熟妇人妻av在线网址 | 亚洲国产精品毛片av不卡在线 | 国产无遮挡又黄又爽免费视频 | 中文字幕无码日韩专区 | 中文字幕无码视频专区 | 成 人 免费观看网站 | 久久99精品久久久久久 | 99精品无人区乱码1区2区3区 | 无码人妻出轨黑人中文字幕 | 麻豆果冻传媒2021精品传媒一区下载 | 久久99精品久久久久婷婷 | 精品无码成人片一区二区98 | 国产又爽又黄又刺激的视频 | 亚洲色成人中文字幕网站 | 天天躁日日躁狠狠躁免费麻豆 | 骚片av蜜桃精品一区 | 女人被男人躁得好爽免费视频 | 亚洲热妇无码av在线播放 | 日本精品久久久久中文字幕 | 男女作爱免费网站 | 国产精品手机免费 | a在线观看免费网站大全 | 少妇性俱乐部纵欲狂欢电影 | 黑人巨大精品欧美黑寡妇 | 男女性色大片免费网站 | 无码人妻出轨黑人中文字幕 | 麻豆国产97在线 | 欧洲 | 大屁股大乳丰满人妻 | 久久久国产一区二区三区 | 中文字幕日韩精品一区二区三区 | 日韩欧美中文字幕在线三区 | 国产三级精品三级男人的天堂 | 一本久久a久久精品vr综合 | 国产激情综合五月久久 | 内射爽无广熟女亚洲 | 一本色道久久综合亚洲精品不卡 | 亚洲成a人一区二区三区 | aa片在线观看视频在线播放 | 人妻互换免费中文字幕 | 国产色视频一区二区三区 | 亚洲欧美精品aaaaaa片 | yw尤物av无码国产在线观看 | 亚无码乱人伦一区二区 | 久久综合给合久久狠狠狠97色 | 无码成人精品区在线观看 | 中文字幕乱码人妻二区三区 | 又紧又大又爽精品一区二区 | 水蜜桃亚洲一二三四在线 | 2020久久香蕉国产线看观看 | 伊在人天堂亚洲香蕉精品区 | 成人无码影片精品久久久 | 欧洲vodafone精品性 | 少妇人妻偷人精品无码视频 | 一本色道久久综合狠狠躁 | 又湿又紧又大又爽a视频国产 | 精品少妇爆乳无码av无码专区 | 少妇性荡欲午夜性开放视频剧场 | 国产真人无遮挡作爱免费视频 | 亚洲国产精品无码一区二区三区 | 亚洲国产综合无码一区 | 东京热一精品无码av | 成 人 网 站国产免费观看 | 亚洲一区二区三区含羞草 | 亚洲精品国产a久久久久久 | 性啪啪chinese东北女人 | a在线观看免费网站大全 | 暴力强奷在线播放无码 | 精品人妻人人做人人爽夜夜爽 | 一二三四在线观看免费视频 | 亚洲中文字幕无码中字 | 精品午夜福利在线观看 | 国产真实乱对白精彩久久 | 久久国产自偷自偷免费一区调 | 久久99精品国产.久久久久 | 美女黄网站人色视频免费国产 | 人人妻人人澡人人爽人人精品浪潮 | 国产一区二区三区日韩精品 | 精品无码一区二区三区爱欲 | 中文字幕中文有码在线 | 色综合视频一区二区三区 | 67194成是人免费无码 | 国产亚洲视频中文字幕97精品 | 国精产品一区二区三区 | 国产精品久久福利网站 | 福利一区二区三区视频在线观看 | 国产精品无码成人午夜电影 | 高清无码午夜福利视频 | 午夜理论片yy44880影院 | 兔费看少妇性l交大片免费 | 2019nv天堂香蕉在线观看 | 麻豆国产人妻欲求不满谁演的 | 在线成人www免费观看视频 | 亚洲а∨天堂久久精品2021 | 国产成人无码av一区二区 | 老司机亚洲精品影院 | 亚洲午夜久久久影院 | 亚洲欧美精品伊人久久 | 熟女少妇在线视频播放 | 日本熟妇浓毛 | 成人一在线视频日韩国产 | 午夜性刺激在线视频免费 | 成在人线av无码免观看麻豆 | 377p欧洲日本亚洲大胆 | 精品国产av色一区二区深夜久久 | 中文字幕无码乱人伦 | 美女毛片一区二区三区四区 | 亚洲欧美综合区丁香五月小说 | a片在线免费观看 | 人人妻人人澡人人爽精品欧美 | 成人性做爰aaa片免费看 | 国内综合精品午夜久久资源 | 欧美日韩一区二区三区自拍 | 亚洲精品www久久久 | 正在播放老肥熟妇露脸 | 国产精品久久久一区二区三区 | 少妇性俱乐部纵欲狂欢电影 | 日本精品高清一区二区 | 午夜福利试看120秒体验区 | 欧美日韩视频无码一区二区三 | 中文字幕无码免费久久99 | 天天摸天天透天天添 | 亚洲成在人网站无码天堂 | 乌克兰少妇xxxx做受 | av无码久久久久不卡免费网站 | 日本护士毛茸茸高潮 | 亚洲男人av香蕉爽爽爽爽 | 国产免费久久久久久无码 | 久久精品国产亚洲精品 | 亚洲欧美中文字幕5发布 | 国产午夜无码精品免费看 | 久久久久成人精品免费播放动漫 | 给我免费的视频在线观看 | 中文字幕乱码人妻二区三区 | 六月丁香婷婷色狠狠久久 | 国产成人一区二区三区在线观看 | 久久久精品人妻久久影视 | 无码毛片视频一区二区本码 | 日产国产精品亚洲系列 | 色欲久久久天天天综合网精品 | 国产精品爱久久久久久久 | 少妇性l交大片欧洲热妇乱xxx | 国产真实乱对白精彩久久 | 99国产欧美久久久精品 | 97se亚洲精品一区 | 亚洲精品无码人妻无码 | 欧美国产亚洲日韩在线二区 | 成人片黄网站色大片免费观看 | 亚洲中文字幕va福利 | 亚洲中文字幕久久无码 | 亚洲熟女一区二区三区 | 377p欧洲日本亚洲大胆 | 波多野结衣一区二区三区av免费 | 黑人巨大精品欧美一区二区 | 图片区 小说区 区 亚洲五月 | 伊人色综合久久天天小片 | 内射爽无广熟女亚洲 | 成人女人看片免费视频放人 | 奇米影视888欧美在线观看 | 亚洲国产精品久久久久久 | 俄罗斯老熟妇色xxxx | 性色av无码免费一区二区三区 | 亚洲精品一区二区三区婷婷月 | 国产一区二区三区四区五区加勒比 | 波多野结衣av一区二区全免费观看 | 色妞www精品免费视频 | 亚洲国产精品久久人人爱 | 国产无套粉嫩白浆在线 | 日韩av无码一区二区三区 | 精品日本一区二区三区在线观看 | 女人被男人躁得好爽免费视频 | 日韩精品无码免费一区二区三区 | 久久人人爽人人爽人人片av高清 | 老熟妇乱子伦牲交视频 | 国产精品久久久久久无码 | 久久久久久久女国产乱让韩 | 亚洲成色www久久网站 | 自拍偷自拍亚洲精品10p | 青青青手机频在线观看 | 亚洲乱亚洲乱妇50p | 国语精品一区二区三区 | 成人欧美一区二区三区黑人免费 | 国产情侣作爱视频免费观看 | 欧美精品免费观看二区 | 999久久久国产精品消防器材 | 国产艳妇av在线观看果冻传媒 | 日产国产精品亚洲系列 | 国精品人妻无码一区二区三区蜜柚 | 亚洲爆乳精品无码一区二区三区 | 人妻有码中文字幕在线 | 精品国产福利一区二区 | 成人aaa片一区国产精品 | 精品无码成人片一区二区98 | 97久久精品无码一区二区 | 亚洲中文字幕无码中文字在线 | 精品一区二区不卡无码av | 男人的天堂2018无码 | 亚洲中文字幕成人无码 | 国产精品久久国产三级国 | 天天燥日日燥 | 日本熟妇大屁股人妻 | 又紧又大又爽精品一区二区 | av人摸人人人澡人人超碰下载 | 国产激情艳情在线看视频 | 精品无码一区二区三区的天堂 | 国产成人精品久久亚洲高清不卡 | 老熟妇乱子伦牲交视频 | 亚洲日本va中文字幕 | 中文字幕无码乱人伦 | 少妇被粗大的猛进出69影院 | 成人女人看片免费视频放人 | 免费人成网站视频在线观看 |