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

委派模式——從SLF4J說起

開發(fā)
將某個通用解決方案包裝成成熟的工具包,是每一個技術(shù)建設(shè)工作者必須思考且必須解決的問題。本文從業(yè)內(nèi)流行的既有工具包入手,解析實現(xiàn)思路,沉淀一般方法。為技術(shù)建設(shè)的初學(xué)者提供一些實踐思路的參考。尤其是文中提倡的“去中心化”的協(xié)作模式,和“關(guān)鍵鏈路+開發(fā)接口”的開發(fā)模式,具有一定的實際落地意義。當然本文在行文中,不可避免存在一定主觀偏見性,讀者可酌情閱讀。

一、前言

熟悉JAVA服務(wù)器開發(fā)的同學(xué)應(yīng)該都使用過日志模塊,并且大概率使用過"log4j-over-slf4j"和“slf4j-log4j”這兩個包。那么這兩個包的區(qū)別是什么?為什么會互相引用包含呢?這篇文章會解釋下這幾個概念的區(qū)別。

首先說一下SLF4J

二、從SLF4J開始

SLF4J全稱"Simple Logging Facade for Java (SLF4J) ", 它誕生之初的目的,是為了針對不同的log解決方案,提供一套統(tǒng)一的接口適配標準,從而讓業(yè)務(wù)代碼無須關(guān)心使用到的第三方模塊都使用了哪些log方案。

舉個例子, Apache Dubbo和RabbitMQ使用到的日志模塊便不相同。從某種意義上而言,SLF4J只是一個facade,類似于當年的ODBC(針對不同的數(shù)據(jù)庫廠商而制定的統(tǒng)一接口標準, 下文會涉及到)。而這個facade對應(yīng)的包名,是 “slf4j-api-xxx.xxx.xxx.jar”。所以,當你應(yīng)用了"slf4j-api-xxx.jar"的包時,其實只是引入了一個日志接口標準,而并沒有引入日志具體實現(xiàn)

2.1、業(yè)內(nèi)實現(xiàn)

SLF4J標準在應(yīng)用層的核心類,就是兩個: org.slf4j.Logger 和 org.slf4j.LoggerFactory。其中,自版本1.6.0后,如果并沒有具體的實現(xiàn),slf4j-api會默認提供一個啥也不干的Logger實現(xiàn)(org.slf4j.helpers.NOPLogger)。

在當前(本稿件于2022-03-01擬制)的市面上,既有的實現(xiàn)SLF4J的方案有以下幾種:

圖片

整體層次如下圖:

圖片

綜上而言:以SLF4J-開頭的jar包,一般指的是采用某種第三方框架實現(xiàn)的slf4j解決方案。

2.2 工作機制

那么整個SLF4J的工作機制是如何運作的呢,換句話說,系統(tǒng)是如何知道應(yīng)該使用哪個實現(xiàn)方案的呢?

對于那種不需要適配器的原生實現(xiàn)方式,直接引入對應(yīng)的包即可。

對于那種需要適配器的委托式實現(xiàn)方式,則需要通過另外的一個渠道來告知SLF4J應(yīng)該使用哪個實現(xiàn)類: SPI機制。

舉個例子,我們看一下slf4j-log4j的包結(jié)構(gòu):

圖片

我們先看pom文件,就包含兩個依賴:


<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>

slf4j-log4j同時引入了slf4j-api和log4j。那么slf4j-log4j本身的作用不言而喻:使用LOG4J的功能,實現(xiàn)SLF4J的接口標準。

整體的接口/類關(guān)系路徑如下圖:

圖片

但是這仍然沒有解決本章節(jié)開始提出的問題(程序怎么知道應(yīng)該用哪個Logger)。

可以從源碼入手:(??slf4j/slf4j-log4j12 at master · qos-ch/slf4j · GitHub??),我們看到了以下關(guān)鍵的文件:

圖片

也就是說:slf4j-log4j使用了java的SPI機制告知JVM在運行時調(diào)用具體哪一個實現(xiàn)類。由于SPI機制暫不屬于本文章討論范圍,讀者可以去官網(wǎng)獲取信息。

讀者可以去??GitHub - qos-ch/slf4j: Simple Logging Facade for Java??看其他的實現(xiàn)方式的適配器是如何工作的。

那么本章開始的問題答案便是:

  1. SLF4J制定一套日志打印流程,然后把核心類抽象出接口給外部去實現(xiàn);
  2. 適配器使用第三方日志組件實現(xiàn)了這些核心類接口,并采用SPI機制,讓JAVA運行時意識到核心接口的具體實現(xiàn)類。

而上述兩點,構(gòu)成了本文接下來要講述的知識點:委派模式。

三、委派模式

從上文中,我們從SLF4J的案例,引出了"委派模式"這個概念,下面我們就重點討論委派模式(delegation)。

接下來我們按照認知流程,依次從三個問題,解釋委派模式:

  • 為什么使用委派模式
  • 什么是委派模式
  • 如何使用委派模式

然后會在下一章,用業(yè)內(nèi)的典型案例,分析委派模式的使用情況。

3.1 為什么采用委派模式?

我們回到SLF4J。為什么它會用委派模式呢?因為日志打印功能存在各種不同的實現(xiàn)方式。對于應(yīng)用開發(fā)者而言,最好需要一個標準的打印流程,其他第三方組件可以在某些地方有些不同,但是核心流程是最好不要變。對于標準制定者 而言,他無法控制每一個第三方組件的所有細節(jié),所以只能暴露出有限的自定制能力。

而我們放大到軟件領(lǐng)域,或者在互聯(lián)網(wǎng)開發(fā)領(lǐng)域,不同的開發(fā)者的協(xié)作模式,主要靠jar包應(yīng)用:第三方開發(fā)一個工具包,放在中心倉庫中(maven, gradle), 使用者從其他信息渠道(csdn, stackoverflow等等)根據(jù)問題定位到這個jar包,然后在代碼工程中引用。理論上,如果這個第三方j(luò)ar包很穩(wěn)定(例如c3p0),那么該jar包的維護者就很少甚至幾乎不會和使用者建立聯(lián)系。如果某些中間件開發(fā)者覺得不滿足自己公司/部門的需求,會根據(jù)該jar包再做一次自定義封裝。

縱觀上述整個過程,不難發(fā)現(xiàn)兩點:

  1. 工具包開發(fā)者和使用者沒有建立穩(wěn)定的協(xié)同渠道
  2. 工具包開發(fā)者對自己成品的發(fā)展掌控很薄弱

那么如果有人想要建立一套標準呢?比如log標準,比如數(shù)據(jù)庫連接標準,那么只能有幾個大公司聯(lián)盟,或者著名的開發(fā)團隊聯(lián)盟,制定一個標準,并實現(xiàn)其中核心鏈路部分。至于為什么不實現(xiàn)全部鏈路,原因也很簡單:軟件領(lǐng)域的協(xié)同本身就是弱中心化的 ,否則你不帶別人玩,別人也不會采用你的標準(參考當年IBM推廣的COBOL)。

綜上而言:委派模式是基于當前軟件領(lǐng)域的協(xié)作特性,采取的較好的軟件結(jié)構(gòu)模式。


圖片

所以啥時候采用委派模式呢?

  • 存在設(shè)定某個標準并由中心化團隊負責(zé)的必要
  • 使用者有強烈的需求自定制某些局部實現(xiàn)

這里就舉一個硬件領(lǐng)域的反例:快充標準。在2018年甚至更早,消費者就需要一個快充的功能。但是快充需要定制很多硬件才能實現(xiàn),所以此時就具備了條件一,但是當時并沒有任何一個團隊或者公司能夠掌控安卓手機硬件整個生態(tài),無法共同推出一個中心化團隊去負責(zé),從而導(dǎo)致各個手機廠商的快充功能百花齊放:A公司的快充線,無法給B公司的手機快充。

3.2 什么是委派模式?

基于上述的討論,委派模式的核心構(gòu)成就顯而易見了:核心鏈路, 開放接口。

核心鏈路指的是:為了達到某個目的,特定的一組構(gòu)件,按照特定的順序,特定的協(xié)同標準,共同執(zhí)行計算的邏輯。

開放接口指的是:給定特定的輸入和輸出,將實現(xiàn)細節(jié)交給外部的功能接口。

舉個比較現(xiàn)實的例子:傳統(tǒng)汽車。

幾乎每一輛傳統(tǒng)汽車,都按照三大件進行集成和協(xié)作:發(fā)動機,變速器,底盤。發(fā)動機做功, 通過變速器將動力傳輸給底盤(這么說并不標準,甚至在汽車工業(yè)的工人眼中,這種描述幾乎是謬論,但是大致是這樣)。也基于此,發(fā)動機的接口, 變速箱的接口,底盤的接口都已經(jīng)固定,剩下的就各個廠商去實現(xiàn)了:三菱的發(fā)動機, 日產(chǎn)的發(fā)動機,愛信的變速箱,采埃孚的變速箱,倫福德的底盤,天合的底盤等等。甚至連輪胎的接口都制定好了:大陸的輪胎,普利司通的輪胎,固特異的輪胎。

不同的汽車廠商,選擇不同公司的組件,集成出某個汽車型號。當然也有公司自己去實現(xiàn)某個標準:比如大眾自己生產(chǎn)EA888發(fā)動機,PSA自己生產(chǎn)并調(diào)教的底盤并引以為傲。

如果大家覺得不夠熟悉,那么可以舉一個tomcat的例子。

經(jīng)歷過00年代的軟件開發(fā)者,應(yīng)該知道當時開發(fā)一個web應(yīng)用是多么的困難:如何監(jiān)聽socket, 如何編碼解碼,如何處理并發(fā),如何管理進程等等。但是有一點是共通的:每一個Web開發(fā)者都想要一個框架去管理整個http服務(wù)的協(xié)議層和內(nèi)核層。于是出現(xiàn)了JBoss, WebSphere, Tomcat(笑到了最后)。

這些產(chǎn)品,都是指定了核心的鏈路:監(jiān)聽socket → 讀數(shù)據(jù)包→ 封裝成http報文 → 派發(fā)給處理池子 → 處理池的線程調(diào)用處理邏輯去處理 → 編碼返回的報文 → 編組成tcp包 → 調(diào)用內(nèi)核函數(shù)→ 發(fā)出數(shù)據(jù)。

基于這個核心鏈路,制定標準:業(yè)務(wù)處理邏輯的輸入是什么,輸出是什么,如何讓web框架識別到業(yè)務(wù)處理模塊。

Tomcat的方案就是web.xml。開發(fā)者只要遵從web.xml標準去實現(xiàn)servlet即可。也就是說,在整個http服務(wù)器鏈路中,Tomcat將特定的幾個流程處理構(gòu)件(listener, filter, interceptor, servlet)委派給了業(yè)務(wù)開發(fā)者去實現(xiàn)。

3.3 如何使用委派模式

在使用委派模式之前,先根據(jù)上文的模式匹配條件進行自我判斷:

  • 存在設(shè)定某個標準并由中心化團隊負責(zé)的必要
  • 使用者有強烈的需求自定制某些局部實現(xiàn)

如果并不符合條件一,那么就不需要考慮使用委派模式;如果符合條件一但是不符合條件二,那就先預(yù)留好接口,采用依賴注入的方式,自己開發(fā)接口實現(xiàn)類并注入到主流程中。這個做法在很多的第三方依賴包中能夠看到,比如spring的BeanFactory, BeanAware等等,還有各個公司開發(fā)SSO時預(yù)留的一些hook和filter等等。

在確定使用委派模式后,第一件事就是“確定核心鏈路”,這一步最難,因為往往使用者都有某種期望,但是讓他們具體描述出來,卻又經(jīng)常不夠精準,甚至有時候后主次顛倒。筆者的建議是:直接讓他們說出原始的需求/痛點,然后自己嘗試給出方案,再對比他們的方案,進行溝通,并逐漸將兩個方案統(tǒng)一。統(tǒng)一的過程也就是不斷試探和確定的過程。

圖片

上述的過程是筆者自己的經(jīng)驗,僅當借鑒。

在確定核心流程后,再將流程中的一些需要自定制的功能抽象成接口暴露出去。接口的定義中,盡量減少對整個流程中其他類的調(diào)用依賴。

所以整體的流程分為三步:確認使用該模式;提取核心流程;抽象開放接口。

至于是采用SPI機制還是像TOMCAT一樣使用XML配置識別,需要看具體情況,在此不做涉及。

四、 業(yè)內(nèi)案例

4.1 JDBC

JDBC的誕生很大程度上是借鑒了ODBC的思想,為JAVA設(shè)計了專用的數(shù)據(jù)庫連接規(guī)范JDBC(JAVA Database Connectivity)。JDBC期望的目標是讓Java開發(fā)人員在編寫數(shù)據(jù)庫應(yīng)用程序時,可以有統(tǒng)一的接口,無須依賴特定數(shù)據(jù)庫API,達到“ 一次開發(fā),適用所有數(shù)據(jù)庫”。雖然實際開發(fā)中,經(jīng)常會因為使用了數(shù)據(jù)庫特定的語法、數(shù)據(jù)類型或函數(shù)等而無法達到目標,但JDBC的標準還是大大簡化了開發(fā)工作。

整體而言,JDBC的接入結(jié)構(gòu)大致如下圖:

圖片

但是實際上,在JDBC誕生之初,市面上并未有很多的廠家響應(yīng)SUN公司(那時候SUN還并未被ORACLE收購), 于是SUN公司就使用了本文介紹的橋接模式,如下圖:

圖片

也是說,形式上,出現(xiàn)了初步委派的結(jié)構(gòu)形式。

下文會只針對單次委托的JDBC層級做分析。

按照上文所言,每一個委派結(jié)構(gòu),必然存在兩個要素:核心路徑和開放接口。我們從這兩個維度開始分析JDBC。

JDBC的核心路徑分為六步, 包含委托機制需要的兩步(引入包,聲明委托承接人),總共八步,如下:

  1. 引入JDBC實現(xiàn)包
  2. 注冊JDBC Driver
  3. 和數(shù)據(jù)庫建立連接
  4. 發(fā)起transaction(必要的話),創(chuàng)建statement
  5. 執(zhí)行statement并讀取返回,塞入ResultSet
  6. 處理ResultSet
  7. 關(guān)閉ResultSet, 關(guān)閉Statement
  8. 關(guān)閉Connection

縱觀整個過程,核心的參與者為:Driver, Connection, Statement, ResultSet。transaction實際上是基于Connection的三個方法(setAutoCommit, commit, rollback)包裝而成的會話層,理論上不屬于標準層。

以mysql-connector-java為例,具體實現(xiàn)JDBC接口的情況如下:

圖片

通過Java自帶的overriding機制,只要使用com.mysql.jdbc.Driver,那么其他組件的實現(xiàn)類便直接被應(yīng)用實現(xiàn)。具體細節(jié)不做討論。那么mysql-connector-java是如何告知JVM應(yīng)該使用com.mysql.jdbc.Driver呢?

兩種模式

  1. 明文模式——在業(yè)務(wù)代碼中明文使用Class.forName("com.mysql.jdbc.Driver")
  2. SPA機制

其實上述的兩種方法,核心就是初始化com.mysql.jdbc.Driver,執(zhí)行以下類初始化邏輯。


try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}

也就是說,JDBC通過DriveManager維護委托承接者的信息。讀者如果有興趣查看DriverManager的源碼,會發(fā)現(xiàn)JDBC的另一種實現(xiàn)類發(fā)現(xiàn)方式。不過考慮行文長度,筆者在此不表。

4.2 Apach Dubbo

Dubbo的核心路徑大致如下(不考慮服務(wù)管理那一套):

consumer調(diào)用 → 參數(shù)序列化 → 網(wǎng)絡(luò)請求 → 接收請求 → 參數(shù)反序列化 → provider計算并返回 → 結(jié)果序列化 → 網(wǎng)絡(luò)返回 → consumer方接收 → 結(jié)果反序列化

(斜體代表consumer方的dubbo職責(zé),下劃線代表provider方的dubbo職責(zé))

Dubbo的可定制接口有很多,整體大量采用了“類SPI”機制,為整個RPC流程的很多環(huán)節(jié),提供了自定制的注入機制。相較于傳統(tǒng)的Java SPI, Dubbo SPI在封裝性和實現(xiàn)類發(fā)現(xiàn)性上做了很多的擴展和自定制。

Dubbo SPI整體實現(xiàn)機制及工作機制不在本文范圍,但為了行文方便,在此做一些必要說明。整體的Dubbo SPI機制可以分為三部分:

  • @SPI注解——聲明當前接口類為可擴展接口。
  • @Adaptive注解——聲明當前接口類(或者當前接口類的當前方法)能根據(jù)特定條件(注解中的value),動態(tài)調(diào)用具體實現(xiàn)類實現(xiàn)方法。
  • @Activate注解——聲明當前類/方法實現(xiàn)了某個可擴展接口(或者可擴展接口的某個具體方法的實現(xiàn)),并注明被激活的條件,以及所有的被激活實現(xiàn)類中的排序信息。

我們以Dubbo-Auth(??dubbo/dubbo-plugin/dubbo-auth at 3.0 · apache/dubbo · GitHub??)為例,從核心路徑和開放接口兩個維度進行分析。

Dubbo-Auth的實現(xiàn)邏輯,是基于Dubbo-filter的原理,也就是說:Dubbo-Auth本身就是Dubbo整體流程中的某一個環(huán)節(jié)的委派實現(xiàn)方。

Dubbo-Auth的核心入口(也就是核心路徑的起始點), 是ProviderAuthFilter,是org.apache.dubbo.auth.filter的具體實現(xiàn), 也就是說:

  1. org.apache.dubbo.auth.filter是dubbo核心鏈路中對外暴露的一個開發(fā)接口(類定義上標注了@SPI)。
  2. ProviderAuthFilter是實現(xiàn)了dubbo核心鏈路中對外暴露的開發(fā)接口Filter(ProviderAuthFilter實現(xiàn)類定義上標注了@Activate)。

ProviderAuthFilter的核心路徑比較簡單:獲取Authenticator對象,使用Authenticator對象進行auth驗證。

具體代碼如下:


@Activate(group = CommonConstants.PROVIDER, order = -10000)
public class ProviderAuthFilter implements Filter {

@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
URL url = invoker.getUrl();
boolean shouldAuth = url.getParameter(Constants.SERVICE_AUTH, false);
if (shouldAuth) {
Authenticator authenticator = ExtensionLoader.getExtensionLoader(Authenticator.class)
.getExtension(url.getParameter(Constants.AUTHENTICATOR, Constants.DEFAULT_AUTHENTICATOR));
try {
authenticator.authenticate(invocation, url);
} catch (Exception e) {
return AsyncRpcResult.newDefaultAsyncResult(e, invocation);
}
}
return invoker.invoke(invocation);
}
}

注意,上文代碼中

url.getParameter(Constants.AUTHENTICATOR, Constants.DEFAULT_AUTHENTICATOR)

是dubbo spi 的Adaptive機制中的選擇條件,讀者可以深究,本文在此略過。

由于核心路徑包含了Authenticator ,那么Authenticator 自然就很可能是對外暴露的開發(fā)接口了。也就是說,Authenticator 的聲明類中,必然是注解了@SPI。


@SPI("accessKey")
public interface Authenticator {

/**
* give a sign to request
*
* @param invocation
* @param url
*/
void sign(Invocation invocation, URL url);


/**
* verify the signature of the request is valid or not
* @param invocation
* @param url
* @throws RpcAuthenticationException when failed to authenticate current invocation
*/
void authenticate(Invocation invocation, URL url) throws RpcAuthenticationException;
}

上述代碼證明了筆者的猜想。

在Dubbo-Auth中,提供了一個默認的Authenticator :AccessKeyAuthenticator。在這個實現(xiàn)類中,核心路徑被再次具體化:

  1. 獲取accessKeyPai;
  2. 使用accessKeyPair, 計算簽名;
  3. 對比請求中的簽名和計算的簽名是否相同。

在此核心路徑中,由于引入了accessKeyPair概念,于是就引出一個環(huán)節(jié):如何獲取accessKeyPair, 針對此, dubbo-auth又定義了一個開放接口:AccessKeyStorage。


@SPI
public interface AccessKeyStorage {

/**
* get AccessKeyPair of this request
*
* @param url
* @param invocation
* @return
*/
AccessKeyPair getAccessKey(URL url, Invocation invocation);
}

4.3 LOG4J

最后一個案例,我們又回到了日志組件,而之所以介紹LOG4J, 是由于它使用了非常規(guī)的“反向委派”機制。

LOG4J借鑒了SLF4J的思想(或者LOG4J在前?SLF4J借鑒的LOG4J ?), 也采用了 接口標準+ 適配器+第三方方案的思路來實現(xiàn)委派。


圖片

那么顯然,這里就有個問題:SLF4J確認了自己的核心路徑,然后暴露出待實現(xiàn)接口,SLF4J-LOG4J在嘗試實現(xiàn)SLF4J的待實現(xiàn)接口時,又使用了委托機制,把相關(guān)的路徑細節(jié)外包了出去,從而形成了一個環(huán)。

圖片

所以說,如果我同時引入了"log4j-over-slf4j"和"slf4j-log4j",會造成stackoverflow。

這個問題非常典型, google一下就可能看到很多的案例,比如??Analysis of stack overflow exception of log4j-over-slf4j and slf4j-log4j12 coexistence - actorsfit??等等, 官方也給出了警告(??SLF4J Error Codes??)。

由于此文的關(guān)注點在委派模式,所以關(guān)于此問題并不詳細討論。而此案例的重點,是說明了一件事:委派模式的缺點,就是對于開放接口的實現(xiàn)邏輯不可控。如果第三方實現(xiàn)存在重大機制性隱患,會導(dǎo)致整體核心流程出現(xiàn)問題。

五、總結(jié)

綜上所述, 

委派模式的使用場景是:

  • 存在設(shè)定某個標準并由中心化團隊負責(zé)的必要;
  • 使用者有強烈的需求自定制某些局部實現(xiàn)。

委派模式的核心點 核心路徑, 開放接口

委派模式的隱藏機制實現(xiàn)方式的注冊/發(fā)現(xiàn)

參考資料:

  1. ?SLF4J Manual?
  2. ??Using log4j2 with slf4j: java.lang.StackOverflowError - Stack Overflow???
  3. ??Creating Extensible Applications (The Java? Tutorials > The Extension Mechanism > Creating and Using Extensions) (oracle.com)???
  4. ??slf4j/slf4j-log4j12 at master · qos-ch/slf4j · GitHub???
  5. ??Delegation pattern - Wikipedia???
  6. ??What is a JDBC driver? - IBM Documentation???
  7. ??Lesson: JDBC Basics (The Java? Tutorials > JDBC Database Access) (oracle.com)???
  8. ?GitHub - apache/dubbo: Apache Dubbo is a high-performance, java based, open source RPC framework.?
責(zé)任編輯:龐桂玉 來源: vivo互聯(lián)網(wǎng)技術(shù)
相關(guān)推薦

2024-03-01 16:52:02

SLF4J日志框架

2021-03-15 18:47:25

日志開發(fā)源碼

2016-10-21 13:10:18

javalog4jslf4j

2023-10-28 16:19:18

Android日志

2013-02-20 09:42:34

JavaLogbackSLF4J

2020-01-07 10:06:26

Slf4jLog4JLogback

2025-01-20 08:10:00

微服務(wù)架構(gòu)SLF4J

2025-05-26 08:50:00

SLF4JMDC全鏈路追蹤

2024-03-01 08:17:28

SLF4J日志框架

2023-10-07 10:08:54

2023-05-06 07:51:22

JavaFacade設(shè)計模式

2020-10-27 08:24:45

阿里巴巴SLF4J

2020-11-04 12:33:08

Log4j 2日志Logback

2025-10-10 04:10:00

2022-12-30 08:31:27

MDC查詢?nèi)罩?/a>

2021-06-04 07:55:19

委派模式GOF

2020-10-30 12:37:42

日志系統(tǒng)

2022-05-12 11:38:26

Java日志Slf4j

2010-09-16 10:46:47

2024-06-28 09:25:51

點贊
收藏

51CTO技術(shù)棧公眾號

国产免费高清一区| 欧美国产日韩中文字幕在线| 8x8x最新地址| www久久日com| 波多野结衣视频一区| 国产91在线高潮白浆在线观看| 国产精品免费无码| 日韩精品一级| 日本道精品一区二区三区| 亚洲一区二区精品在线| 色网站免费观看| 久久精品免费看| 欧美一级黄色网| 久久免费看少妇高潮v片特黄| 九九热hot精品视频在线播放| 欧美性一二三区| 免费看欧美黑人毛片| jzzjzzjzz亚洲成熟少妇| 国产福利一区在线观看| 国产成人中文字幕| 国产亚洲精品久久久久久打不开| 精品国产一区二区三区久久久樱花| 日韩欧美视频在线| 日本人视频jizz页码69| 久久男人天堂| 亚洲精品第一国产综合野| 欧美午夜视频在线| 日本精品一二区| 狠狠色伊人亚洲综合成人| 欧美在线免费视频| 久久久久97国产| 久久伦理在线| 曰本色欧美视频在线| 日本黄色片在线播放| 91蜜桃臀久久一区二区| 欧美男女性生活在线直播观看| 男人的天堂99| 国产丝袜精品丝袜| 亚洲猫色日本管| 亚洲欧洲精品在线| 波多野结衣在线影院| 93久久精品日日躁夜夜躁欧美| 999热视频在线观看| 国产精品-色哟哟| 免费欧美在线视频| 国产999精品久久久影片官网| 免费观看成人毛片| 日韩视频不卡| 91国产精品91| 欧美成人精品欧美一级乱黄| 亚洲视频日本| 久久久久久美女| 久久精品一级片| 欧美视频成人| 久久久免费在线观看| 欧美人与禽zozzo禽性配| 午夜国产精品视频免费体验区| www.日本久久久久com.| 五月天色婷婷丁香| 羞羞色午夜精品一区二区三区| 啊v视频在线一区二区三区 | 成人午夜视频免费观看| 中文在线免费| 亚洲国产一区二区在线播放| 欧美亚洲黄色片| 欧美13videosex性极品| 粉嫩av一区二区三区免费野| 亚洲熟女乱色一区二区三区| 在线观看欧美日韩电影| 在线看国产日韩| 在线免费视频a| 国产成人久久精品一区二区三区| 日韩一二三区视频| 国产免费一区二区三区最新6| 天堂99x99es久久精品免费| 精品无码久久久久久国产| 亚洲av无码一区二区三区人| 日韩精品一区二区三区免费观看| www国产精品视频| 黄页网站免费观看| 99精品国产在热久久婷婷| 日韩av电影国产| 亚洲一区精品在线观看| 高清免费成人av| 欧美日韩综合网| 黄色av电影在线播放| 亚洲一区在线免费观看| 免费无码av片在线观看| 国产麻豆久久| 欧美电视剧在线看免费| 欧美大片免费播放器| 欧美一区二区三区高清视频| 欧美人与物videos| 黄色污污网站在线观看| 久久99蜜桃精品| 国产一区二区中文字幕免费看| 国产在线观看精品一区| 一区二区在线观看免费视频播放| 99热在线这里只有精品| 国产精品99久久免费| 亚洲精品国产精品国自产在线| 国产一二三av| 一区二区91| 亚洲综合最新在线| 可以免费看污视频的网站在线| 亚洲欧美日韩国产另类专区| 无码人妻h动漫| 日韩免费精品| 日韩在线观看免费| 国产免费一级视频| 国产91精品一区二区麻豆网站| 亚洲第一导航| 日韩伦理在线| 欧美成人猛片aaaaaaa| xxxx日本黄色| 国产婷婷精品| 99久久99久久| 麻豆影院在线| 欧美亚洲综合久久| 熟妇高潮精品一区二区三区| 亚洲高清影视| 国产精品主播视频| 国产精品二线| 欧美性黄网官网| 日本人添下边视频免费| 欧美a级在线| 成人黄色片在线| 欧美尤物美女在线| 欧美性xxxxxx少妇| 欧美熟妇一区二区| 一区二区国产在线观看| 国产精华一区| 国产盗摄精品一区二区酒店| 91精品国产综合久久久久久| 老司机福利在线观看| 久久激情一区| 久久亚洲精品欧美| 蜜桃麻豆av在线| 亚洲国产精品大全| 国产一级在线免费观看| 高清不卡一区二区| 韩国无码av片在线观看网站| 韩国三级大全久久网站| 色七七影院综合| 一级黄色片网站| 中文字幕一区二区视频| 孩娇小videos精品| 欧美aaaaaaaaaaaa| 国产综合香蕉五月婷在线| 九七电影韩国女主播在线观看| 欧美日韩一区二区在线观看视频| 妖精视频在线观看免费| 美女爽到高潮91| 中文字幕久精品免| 看亚洲a级一级毛片| 久久影院中文字幕| 99久久精品免费看国产交换| 亚洲另类一区二区| 岛国精品一区二区三区| 亚洲人成免费| 欧美凹凸一区二区三区视频| 高清不卡亚洲| 视频在线一区二区| 国产精品久久无码一三区| 亚洲人成人一区二区在线观看| 欧美又黄又嫩大片a级| 亚洲成av人片一区二区密柚| 91免费在线视频| 国产探花在线观看| 亚洲精品一二区| 在线免费观看一级片| 亚洲精品自拍动漫在线| 亚洲一区二区三区四区av| 香蕉视频成人在线观看| 色综合视频二区偷拍在线| 亚洲人体在线| 久久久亚洲影院你懂的| 国产一区二区三区不卡在线| 欧美日韩精品福利| 激情五月婷婷在线| 久久久久亚洲蜜桃| 亚洲理论中文字幕| 国产日韩视频| 亚洲午夜久久久影院伊人| 久久中文字幕一区二区| 91精品国产91久久久久| 92国产在线视频| 精品欧美一区二区久久| 亚洲天堂五月天| 亚洲精品老司机| 国产精品国产三级国产专业不| 精品在线一区二区三区| 国精产品一区一区三区视频| 成人免费看片39| 国产精品视频一区二区三区经| 91超碰碰碰碰久久久久久综合| 欧美成人黑人xx视频免费观看| 日本私人网站在线观看| 7777精品伊人久久久大香线蕉超级流畅 | 丰满人妻一区二区三区免费视频| 色狠狠av一区二区三区| 九九热只有精品| 国产人成亚洲第一网站在线播放| 4438x全国最大成人| 免费在线观看一区二区三区| 国产 欧美 日韩 一区| 成人黄色av| 精品综合在线| 一区二区亚洲视频| 国产精品毛片a∨一区二区三区|国 | 影音先锋黄色网址| 欧美日韩精品在线播放| www.xxxx日本| 国产精品久久久久久久久快鸭| 日本道中文字幕| 国产精品影音先锋| 香港日本韩国三级网站| 欧美专区在线| 少妇人妻大乳在线视频| 女人香蕉久久**毛片精品| 日韩欧美在线电影| 色天下一区二区三区| 不卡视频一区| 日韩一二三区| 成人亚洲欧美一区二区三区| 成人av色网站| 国产精品久久婷婷六月丁香| 成人免费看黄| 欧美在线视频在线播放完整版免费观看| av在线free| 久久久精品欧美| 在线a免费看| 亚洲日本欧美日韩高观看| 亚洲日本在线播放| 日韩av在线不卡| 天天操天天操天天干| 精品99999| 亚洲欧美强伦一区二区| 日韩欧美在线综合网| 国产欧美一级片| 欧美一级二级在线观看| 91麻豆国产在线| 69久久99精品久久久久婷婷| 国产强被迫伦姧在线观看无码| 欧美疯狂做受xxxx富婆| ,一级淫片a看免费| 91.com视频| 国产农村妇女毛片精品久久| 51精品国自产在线| 国产人妻精品一区二区三| 日韩一级完整毛片| 亚洲精品一区二区三区新线路 | 天天干天天色天天| 亚洲国产另类久久精品| 水中色av综合| 一区二区三区回区在观看免费视频| 九色视频网站在线观看| 在线观看亚洲视频| 免费在线观看av片| 超碰91人人草人人干| 肉体视频在线| 97视频在线观看视频免费视频 | 欧美精品视频www在线观看| 亚洲特级黄色片| 欧美一二三区在线观看| 国产不卡av在线播放| 精品对白一区国产伦| 无码精品人妻一区二区| 国产亚洲在线播放| 精品视频在线一区二区| 国内精品模特av私拍在线观看| 蜜桃av.网站在线观看| 国产精品高清在线| 视频精品一区| 快播日韩欧美| 国产精品久久久乱弄| 国产一级不卡视频| 久久xxxx精品视频| a在线观看免费视频| 国产传媒久久文化传媒| av在线网站观看| 日韩一区日韩二区| 国产精品成人久久| 欧美日韩精品一区视频| 成人久久久精品国产乱码一区二区| 日韩精品免费一线在线观看| melody高清在线观看| 久久久久久com| 国产亚洲欧美日韩精品一区二区三区| 99www免费人成精品| 欧洲激情视频| 97在线免费视频观看| 鲁大师成人一区二区三区| 日韩精品视频网址| 91亚洲大成网污www| 亚洲综合视频网站| 色诱视频网站一区| 成人福利小视频| 在线电影av不卡网址| av影视在线| 美女国产精品| 另类小说综合网| 中文字幕亚洲精品乱码| 国产日产欧美视频| 国产福利一区二区三区视频| 国产三级黄色片| 精品日韩中文字幕| 国产黄色免费大片| 日韩在线视频观看| 浪潮色综合久久天堂| 国产精品露出视频| 欧美99久久| wwwwwxxxx日本| 久久久九九九九| 国产精品第9页| 日韩免费在线观看| 国产激情小视频在线| 国产精品稀缺呦系列在线| 亚洲ab电影| 欧美深夜福利视频| 国产精品一区二区三区四区| 波多野结衣家庭教师在线观看 | 欧美综合影院| 欧美日韩一区二区三区在线观看免| 亚洲午夜91| 亚洲国产欧美91| 综合久久给合久久狠狠狠97色 | 欧美一级二级三级九九九| 亚洲小说区图片区| 第一页在线视频| 亚洲精品伦理在线| 国产男男gay网站| 久久在线视频在线| 99久久这里有精品| 日本女人高潮视频| 激情五月婷婷综合| 手机在线免费看片| 日韩一区二区三区视频在线观看| 看女生喷水的网站在线观看| 成人a在线观看| 国产精品毛片久久| √天堂资源在线| 亚洲精品乱码久久久久久黑人| av官网在线观看| 欧美丰满少妇xxxxx做受| 五月亚洲婷婷| 日本福利视频一区| 不卡视频一二三四| 国产91精品一区| 亚洲美女动态图120秒| 欧美xx视频| 午夜精品一区二区三区四区| 免费成人av资源网| 韩国一级黄色录像| 日韩一本二本av| 欧美亚洲天堂| 精品日本一区二区三区| 性色av一区二区怡红| 久久精品视频18| 欧美日韩不卡视频| 在线三级中文| 国产综合第一页| 亚洲一区观看| 国产成人一区二区在线观看| 欧美日韩色综合| fc2ppv国产精品久久| 国产精品久久7| 久久精品毛片| 国产3级在线观看| 欧美成人女星排名| 永久免费毛片在线播放| 亚洲欧洲一区二区在线观看| 国产一区二区在线看| 久久夜靖品2区| 最近2019年手机中文字幕| 久久久久久久久久久久电影| 免费无码毛片一区二三区| 久久精品在线免费观看| 国产精选久久久| 性色av一区二区三区免费| 国产亚洲欧美日韩在线观看一区二区| 91av视频免费观看| 午夜精品aaa| 色综合久久影院| 精品国产一区二区三区免费| 蜜臀av在线播放一区二区三区| 免费一级全黄少妇性色生活片| 国产丝袜一区视频在线观看 | 国产精品久久精品视| 日韩和欧美一区二区三区| 免费视频网站www| 一本色道久久88精品综合| 97人人澡人人爽91综合色| 中文字幕无码不卡免费视频| 亚洲精品午夜久久久| 国产一区二区三区不卡在线| 国产精品区一区| 久久精品国产免费| 国产精品乱子伦| 久久久久久久久久久91|