<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何基于DDD構(gòu)建微服務(wù)架構(gòu)

          共 5967字,需瀏覽 12分鐘

           ·

          2021-08-09 22:37

          微服務(wù)構(gòu)建本質(zhì)上是軟件構(gòu)建過程中長期演進積累的一系列理念、架構(gòu)原則、工具和最佳實踐。

          領(lǐng)域驅(qū)動設(shè)計的軟件思想體系和方法論可以用于指導(dǎo)微服務(wù)建模、微服務(wù)劃分、微服務(wù)架構(gòu)設(shè)計等相關(guān)工作,它可以促使技術(shù)人員與領(lǐng)域?qū)<疫_成共識,構(gòu)建領(lǐng)域邊界合理、具備明確界限上下文、關(guān)注點分離、獨立自治的微服務(wù)。

          01 領(lǐng)域驅(qū)動設(shè)計概述

          領(lǐng)域驅(qū)動設(shè)計(Domain Driven Design)概念的興起可以追溯到1986年,《人月神話》的作者Brooks提出軟件的本質(zhì)復(fù)雜性(Essential Complexity)存在于復(fù)雜的業(yè)務(wù)領(lǐng)域中,技術(shù)僅僅是輔助工具,它解決的問題是幫助業(yè)務(wù)領(lǐng)域從現(xiàn)實問題映射轉(zhuǎn)換成軟件實現(xiàn)。

          領(lǐng)域驅(qū)動設(shè)計在戰(zhàn)略設(shè)計層面,從業(yè)務(wù)視角出發(fā)使技術(shù)人員專注于問題域,從領(lǐng)域?qū)<夷抢铽@得領(lǐng)域見解,通過模塊劃分建立領(lǐng)域服務(wù)邊界,通過界限上下文明確服務(wù)的職責(zé)。

          領(lǐng)域驅(qū)動設(shè)計在戰(zhàn)術(shù)設(shè)計層面,從技術(shù)的視角出發(fā),提煉有效的業(yè)務(wù)模型,實施領(lǐng)域建模、架構(gòu)設(shè)計完成軟件的落地。

          領(lǐng)域驅(qū)動設(shè)計通過隔離業(yè)務(wù)與技術(shù)的復(fù)雜性,成為程式化、標(biāo)準化的軟件架構(gòu)設(shè)計范式。

          軟件復(fù)雜度的來源

          • 業(yè)務(wù)的復(fù)雜性:業(yè)務(wù)的復(fù)雜性體現(xiàn)在業(yè)務(wù)流程不清晰、業(yè)務(wù)參與人員多、業(yè)務(wù)與技術(shù)耦合等方面。在業(yè)務(wù)的早期階段,為了快速滿足功能需求容易形成面條式的代碼風(fēng)格,這樣的代碼風(fēng)格會導(dǎo)致軟件模塊膨脹、開發(fā)效率降低、功能擴展步伐放緩、業(yè)務(wù)模型與代碼脫節(jié)等。
          • 技術(shù)的復(fù)雜性:技術(shù)的復(fù)雜性來源于對項目的質(zhì)量屬性需求,諸如系統(tǒng)的性能、客戶體驗、服務(wù)高可用性等。為解決服務(wù)的響應(yīng)延遲、吞吐、安全等問題,我們會引入緩存、消息隊列、第三方模塊組件,而這些技術(shù)的整合給系統(tǒng)引入了額外的復(fù)雜性和技術(shù)挑戰(zhàn)。

          質(zhì)量屬性需求:系統(tǒng)非功能(也叫非行為)部分的需求。

          領(lǐng)域驅(qū)動解決之道

          解決這種軟件構(gòu)建中面臨的復(fù)雜性問題,我們需要從領(lǐng)域開始著手,與業(yè)務(wù)專家一起獲得領(lǐng)域見解,促使軟件利益干系方在領(lǐng)域內(nèi)建立通用語言。技術(shù)人員通過建模的手段提煉出事物的本質(zhì),以便更好地指導(dǎo)應(yīng)用系統(tǒng)的構(gòu)建和規(guī)劃。

          領(lǐng)域驅(qū)動設(shè)計中包含了大量成熟的理論、概念、模式和架構(gòu),它包含一套解決復(fù)雜領(lǐng)域模型的軟件架構(gòu)方法,思想是圍繞業(yè)務(wù)模型來連接和實現(xiàn)核心業(yè)務(wù)概念。

          領(lǐng)域驅(qū)動設(shè)計可以讓業(yè)務(wù)和技術(shù)的變化產(chǎn)生的不可預(yù)知因素互相分離,將人員變動、團隊規(guī)模、協(xié)作溝通等外界因素變化對產(chǎn)品和項目的影響封裝在一個可控的容器和框架下,從而解決軟件面臨的復(fù)雜性問題,如下圖所示。

          事務(wù)腳本模式與領(lǐng)域建模模式

          • 事務(wù)腳本模式:事物腳本模式常見于單體應(yīng)用中,它將所有邏輯全部組織在一個單一過程方法中,從數(shù)據(jù)庫的調(diào)用到不同業(yè)務(wù)邏輯、策略的執(zhí)行全部集成在一個大的方法塊中。它的好處是簡單、容易實現(xiàn),它的缺點是沒有自己的狀態(tài),也無法擴展,容易將服務(wù)組件與數(shù)據(jù)存儲模型之間的剛性依賴引入業(yè)務(wù)邏輯中。
          • 領(lǐng)域建模模式:領(lǐng)域建模模式將業(yè)務(wù)邏輯轉(zhuǎn)移到了領(lǐng)域?qū)ο螅―omain Object)中,每個領(lǐng)域?qū)ο笸瓿蓪儆谧约旱臉I(yè)務(wù)行為。同時數(shù)據(jù)存儲層的邏輯也變得相對簡單,數(shù)據(jù)庫不再參與領(lǐng)域模型的業(yè)務(wù)邏輯,而是回歸數(shù)據(jù)“持久化”的本質(zhì)。

          使用領(lǐng)域模式可以提升系統(tǒng)的內(nèi)聚性和可重用性,通過不同類之間的協(xié)同完成所有功能。另外,多態(tài)的模式也讓擴展新的策略更加方便,業(yè)務(wù)語義更加通用、顯性化。領(lǐng)域建模過程遵循“SOLID”原則并實現(xiàn)業(yè)務(wù)域的邏輯解決方案。

          說明:SOLID原則

          \1. Single Responsibility Principle:單一職責(zé)原則

          \2. Open Closed Principle:開閉原則

          \3. Liskov Substitution Principle:里氏替換原則

          \4. Interface Segregation Principle:接口隔離原則

          \5. Dependence Inversion Principle:依賴倒置原則

          領(lǐng)域驅(qū)動設(shè)計核心要素

          如下圖所示是領(lǐng)域驅(qū)動設(shè)計的核心要素,包含領(lǐng)域驅(qū)動設(shè)計中的通用模型術(shù)語和重要的戰(zhàn)術(shù)模式。這些模式不僅可以捕獲和傳遞領(lǐng)域中的概念、關(guān)系及邏輯,也能幫助我們管理業(yè)務(wù)的復(fù)雜性并確保領(lǐng)域模型的行為清晰明確。

          • 領(lǐng)域:相對于軟件系統(tǒng)來說就是系統(tǒng)要解決的現(xiàn)實問題。
          • 子域:對于領(lǐng)域進行不同維度切分的相對內(nèi)聚的子系統(tǒng)單元。
          • 分層架構(gòu):通過分層架構(gòu)將業(yè)務(wù)域和技術(shù)邏輯域隔離。
          • 服務(wù):服務(wù)通常是領(lǐng)域?qū)ο蟮恼{(diào)用方,用來協(xié)調(diào)領(lǐng)域?qū)ο笸瓿芍付I(yè)務(wù)邏輯職責(zé)。
          • 實體:實體與面向?qū)ο笾械母拍铑愃疲穷I(lǐng)域模型的基本元素,在領(lǐng)域模型中,實體應(yīng)該具有唯一的標(biāo)識符。
          • 值對象:值對象是沒有唯一標(biāo)識符的實體。值對象在領(lǐng)域模型中是可以被共享的,它們應(yīng)該是不可變的,當(dāng)有其他地方需要用到值對象時,可以將它的副本作為參數(shù)傳遞。
          • 聚合:聚合使用邊界將內(nèi)部和外部的對象劃分開來。每個聚合有一個根,這個根是一個實體作為外部可以訪問的唯一對象。
          • 資源庫:是封裝的所有獲取對象引用所需的邏輯單元。
          • 工廠:工廠用來封裝對象創(chuàng)建所必需的信息,當(dāng)聚合根建立時,所有聚合包含的對象將隨之建立。

          02 專注問題域

          解決一個業(yè)務(wù)場景中的復(fù)雜問題從理解問題域開始,通過專注于問題域并理解復(fù)雜問題背后的實質(zhì),你才能設(shè)計有效的模型來應(yīng)對業(yè)務(wù)的挑戰(zhàn)。

          在項目初期,盡量避免沉溺于技術(shù)實現(xiàn),而要把焦點集中在問題領(lǐng)域,不要忘記技術(shù)服務(wù)業(yè)務(wù)的原則。

          理解問題域

          我們以一個金融場景下的“業(yè)務(wù)運營監(jiān)控系統(tǒng)”為例進行分析。經(jīng)過與運營管理專家和相關(guān)業(yè)務(wù)方的多輪需求探論,我們初步了解了用戶的業(yè)務(wù)訴求和痛點。需要強調(diào)的是對于問題域的充分理解是我們的首要任務(wù)。

          這里整理了一份需求文檔,它詳細地記錄了問題域的具體范圍和詳細需求。這份文檔不僅是業(yè)務(wù)與技術(shù)團隊之間的一份溝通文檔,也可以作為軟件生命周期在需求分析階段的一個清晰的、規(guī)范化的知識協(xié)作產(chǎn)物。

          提煉問題域

          理解復(fù)雜問題并從中識別、提煉出關(guān)鍵的業(yè)務(wù)模型,即提煉問題域是領(lǐng)域驅(qū)動設(shè)計的關(guān)鍵環(huán)節(jié)。團隊可以通過頭腦風(fēng)暴的形式羅列出領(lǐng)域中的所有事件,整合之后形成最終的領(lǐng)域事件集合。

          你需要在關(guān)鍵事件標(biāo)記的范圍里,參照不同利益干系方的業(yè)務(wù)訴求,組織領(lǐng)域事件和模型,同時,你需要整理出與項目關(guān)聯(lián)的上下游系統(tǒng),如下圖所示。

          通過挖掘隱藏在領(lǐng)域事件中的核心領(lǐng)域模型,我們可以找到從問題空間到方案空間的對應(yīng)映射關(guān)系。針對上述業(yè)務(wù)監(jiān)控系統(tǒng)案例,“進件存量”和“進件流量”的概念成為我們發(fā)現(xiàn)的重要領(lǐng)域模型。

          進件存量:是指在某一指定的時間點,過去生產(chǎn)與積累起來的進件的結(jié)存數(shù)量。

          進件流量:單位時間內(nèi)流過某一段管道的進件體積流量。

          作為衡量業(yè)務(wù)系統(tǒng)運轉(zhuǎn)狀態(tài)的重要指標(biāo),業(yè)務(wù)的“存量”狀態(tài)可以表示業(yè)務(wù)的積壓情況,而業(yè)務(wù)的“流量”狀態(tài)可以表示業(yè)務(wù)流轉(zhuǎn)的變化情況。

          如下圖所示是我們總結(jié)的監(jiān)控系統(tǒng)概要視圖,其中實線表示的是城市信貸業(yè)務(wù)工作流中進件在不同系統(tǒng)的流向,而虛線表示的則是業(yè)務(wù)的存量、流量在業(yè)務(wù)監(jiān)控系統(tǒng)的事件記錄。

          03 服務(wù)的拆分

          完成問題域的理解和提煉后,我們需要對整體系統(tǒng)做進一步的服務(wù)拆分。下圖是我們根據(jù)業(yè)務(wù)領(lǐng)域能力對“業(yè)務(wù)運營監(jiān)控系統(tǒng)”進行拆分后的子領(lǐng)域服務(wù)及模塊劃分說明。

          • 業(yè)務(wù)事件收集(如下圖和表所示)

          • 事件過濾聚合(如下圖和表所示)

          • 規(guī)則配置(如下圖和表所示)

          • 監(jiān)控查詢展示(如下圖和表所示)

          為什么要做服務(wù)拆分

          • 降低系統(tǒng)的整體復(fù)雜性:根據(jù)業(yè)務(wù)領(lǐng)域進行合理的服務(wù)拆分是一個有效控制系統(tǒng)復(fù)雜性的方法。
          • 提高效率:服務(wù)拆分后,代碼模塊相互隔離,并發(fā)的開發(fā)模式可以提升開發(fā)人員的效率。
          • 團隊人員各司其職:拆分的項目可分派給擅長相關(guān)方面技術(shù)的人員,讓團隊成員各司其職,降低工作的耦合度。
          • 共享和自治:可以通過定義好的服務(wù)接口進行服務(wù)共享,同時拆分后的服務(wù)也更加自治。
          • 解決依賴問題:通過服務(wù)拆分,可以清晰地了解哪些服務(wù)依賴會對業(yè)務(wù)造成影響,從而準備預(yù)案。

          服務(wù)拆分的依據(jù)

          高內(nèi)聚、低耦合是服務(wù)拆分的主要依據(jù),下面我們列舉一些常用的服務(wù)拆分策略,了解如何對單體架構(gòu)進行拆分。

          • 區(qū)分服務(wù)類型:工具服務(wù)區(qū)別于業(yè)務(wù)服務(wù),它的特點是與業(yè)務(wù)領(lǐng)域無關(guān),根據(jù)其用途可以進一步細分,一般包括的形式有公共工具服務(wù)、資源工具服務(wù)、包裝器服務(wù)等。
          • 根據(jù)功能定義劃分服務(wù):領(lǐng)域驅(qū)動設(shè)計通過分析問題空間和業(yè)務(wù)邏輯,將應(yīng)用程序定義為域,域由多個子域組成,每個子域?qū)?yīng)于業(yè)務(wù)的不同功能部分。
          • 根據(jù)技術(shù)邊界劃分服務(wù):對于產(chǎn)品類型的服務(wù)使用技術(shù)能力劃分服務(wù)邊界,前后端分離架構(gòu)就是通過技術(shù)棧劃分服務(wù)邊界的典型架構(gòu)模式。

          服務(wù)拆分范式

          通過增加服務(wù)實例或者機器來解決服務(wù)的容量和可用性問題是常用的可擴展架構(gòu)解決方案。在《可擴展藝術(shù)》一書中提出了系統(tǒng)的可擴展性模型:AKF可擴展立方,可以作為服務(wù)拆分的范式。

          AKF可擴展立方:描述從單體應(yīng)用到分布式可擴展應(yīng)用的可擴展模型。

          如下圖所示是使用Scale Cube的3D模型實現(xiàn)的一個微服務(wù)架構(gòu)模型,在X軸上通過API網(wǎng)關(guān)進行水平擴展,在Y軸上進行單體拆分后的微服務(wù)構(gòu)建,服務(wù)之間可以通過REST API進行簡單交互,Z軸是數(shù)據(jù)維度的拆分。

          • X軸:服務(wù)擴展,通過克隆的方式水平擴展。一般是負載均衡后運行多個應(yīng)用副本,達到某個服務(wù)的高吞吐量和高可用性。
          • Y軸:功能拆分,通過拆分不同的事務(wù)進行擴展。微服務(wù)對應(yīng)著Y軸,即將單體應(yīng)用拆分為微服務(wù)應(yīng)用。
          • Z軸:數(shù)據(jù)分區(qū),通過分隔相同的事務(wù)進行擴展,例如數(shù)據(jù)庫分庫分表。

          總之,服務(wù)支持水平擴展以提升容量;對功能的拆分體現(xiàn)在對業(yè)務(wù)模型的切入和深入理解上;應(yīng)用數(shù)據(jù)的劃分是微服務(wù)的重要原則,如果數(shù)據(jù)的耦合問題無法解決,那么應(yīng)用服務(wù)的劃分還會有代碼耦合和級聯(lián)影響。

          04 界限上下文

          在找到服務(wù)邊界并把系統(tǒng)拆分后,我們需要使用“界限上下文”的概念明確服務(wù)之間的交互共享模型和行為接口,它不僅可以有效地限定領(lǐng)域的職責(zé)邊界和特性范圍,也可以控制問題域的規(guī)模,進而以化整為零的方式控制整個系統(tǒng)的復(fù)雜性。

          在業(yè)務(wù)運營監(jiān)控項目中,存量項模型作為業(yè)務(wù)過濾聚合服務(wù)和存量查詢統(tǒng)計服務(wù)的共享模型,關(guān)系如下圖所示。

          為了實現(xiàn)捕獲和統(tǒng)計監(jiān)控業(yè)務(wù)運營過程中的不同階段存量的業(yè)務(wù)狀態(tài),我們將存量項作為上述兩個服務(wù)上下文的共享模型,但我們不會暴露“過濾聚合服務(wù)”中的存量明細、Flow、Stream等模塊的實現(xiàn)細節(jié)。

          作為兩個獨立的服務(wù)主體,它們應(yīng)該在邊界上有明確的界線劃分和通信機制。如果服務(wù)邊界與領(lǐng)域的界限上下文能夠保持一致,那么我們已經(jīng)為高內(nèi)聚、低耦合的微服務(wù)架構(gòu)實現(xiàn)了關(guān)鍵的一步。

          05 領(lǐng)域建模

          領(lǐng)域建模是領(lǐng)域驅(qū)動設(shè)計的核心,通過領(lǐng)域模型可以封裝對業(yè)務(wù)的抽象,建立業(yè)務(wù)概念與領(lǐng)域規(guī)則的關(guān)系。領(lǐng)域模型更關(guān)注的是業(yè)務(wù)語義的顯性表達,而不是具體的數(shù)據(jù)存儲及代碼邏輯實現(xiàn)細節(jié),它可以有效地降低業(yè)務(wù)人員和技術(shù)人員之間的溝通成本。

          案例分析

          回到“業(yè)務(wù)運營監(jiān)控系統(tǒng)”中,我們把業(yè)務(wù)監(jiān)控的核心訴求聚焦在“業(yè)務(wù)事件”,以及業(yè)務(wù)的存量和流量領(lǐng)域模型。

          在整理了領(lǐng)域服務(wù)的核心模塊后,我們可以把業(yè)務(wù)方關(guān)注的組織信息、業(yè)務(wù)類型信息、業(yè)務(wù)階段信息進行進一步領(lǐng)域模型細化,如下圖所示。

          • BizEvent:業(yè)務(wù)事件是業(yè)務(wù)監(jiān)控的數(shù)據(jù)源,使用統(tǒng)一的JSON格式記錄消息事件,以日志方式封裝當(dāng)前業(yè)務(wù)系統(tǒng)發(fā)生的事件詳情。
          • Stream:對應(yīng)一個端到端的數(shù)據(jù)流轉(zhuǎn)概念,通常我們會將BizEvent事件發(fā)送到Kafka的一個Topic上,通過建立Stream可以在消費端處理指定Topic上的數(shù)據(jù)流。
          • Flow:Flow對應(yīng)一個監(jiān)控業(yè)務(wù)計算邏輯,存量Flow可以統(tǒng)計對應(yīng)的存量狀態(tài),流量Flow統(tǒng)計當(dāng)前業(yè)務(wù)的流量狀態(tài)。
          • Service:它并非領(lǐng)域?qū)ο螅硎疽粋€通用的服務(wù)層,Service提供業(yè)務(wù)存量和流量的查詢、備份、預(yù)警等業(yè)務(wù)方法。
          • Provision:用戶配置前置通用服務(wù),不對應(yīng)領(lǐng)域?qū)ο螅饕邮沼脩舻呐渲谜埱螅⒈4鏋闃I(yè)務(wù)規(guī)則。
          • Rule:即規(guī)則模型,屬于核心領(lǐng)域模型,業(yè)務(wù)方可以通過它靈活地定制關(guān)心的業(yè)務(wù)狀態(tài)并進行預(yù)警、過濾等。
          • Detail:屬于業(yè)務(wù)的中間監(jiān)控過程詳情,屬于領(lǐng)域?qū)ο螅瑫r包含組織、階段、業(yè)務(wù)類型等明細對象屬性(Org、Phase、BizType)。

          使用領(lǐng)域建模的設(shè)計方法可以進一步將“業(yè)務(wù)監(jiān)控系統(tǒng)”內(nèi)部的領(lǐng)域服務(wù)與領(lǐng)域模型對象關(guān)聯(lián),顯性地表達每個領(lǐng)域模型的具體工作職責(zé)及業(yè)務(wù)行為事件與領(lǐng)域?qū)ο笾g的上下文映射關(guān)系,如下圖所示。

          06 架構(gòu)設(shè)計

          架構(gòu)設(shè)計的本質(zhì)是管理業(yè)務(wù)和技術(shù)復(fù)雜性,使系統(tǒng)易于有序化重構(gòu)及擴展。高質(zhì)量的架構(gòu)一定是高度抽象的、圍繞業(yè)務(wù)的、易于理解的、面向演進的。

          分層架構(gòu)設(shè)計

          領(lǐng)域驅(qū)動設(shè)計遵循“關(guān)注點分離”原則,將技術(shù)實現(xiàn)邏輯封裝在基礎(chǔ)設(shè)施層;將業(yè)務(wù)邏輯封裝在領(lǐng)域?qū)樱M量使領(lǐng)域?qū)哟a與其他層技術(shù)細節(jié)分割開來;將應(yīng)用層作為黏合劑,實現(xiàn)前兩者的協(xié)作;同時UI層可以基于Swagger技術(shù)暴露REST API。分層架構(gòu)如下圖所示。

          六邊形(Hexagonal)架構(gòu)模式

          六邊形架構(gòu)模式又稱為“端口-適配器”模式,它將系統(tǒng)分為內(nèi)部和外部。內(nèi)部代表應(yīng)用的業(yè)務(wù)邏輯,外部代表應(yīng)用的驅(qū)動邏輯、基礎(chǔ)設(shè)施或其他應(yīng)用。內(nèi)部以API接口呈現(xiàn),通過端口和外部系統(tǒng)通信。外部系統(tǒng)需要使用不同的適配器,適配器負責(zé)對協(xié)議進行轉(zhuǎn)換。應(yīng)用程序能夠以一致的方式與實際運行的設(shè)備和數(shù)據(jù)庫相隔離,方便開發(fā)和測試,六邊形架構(gòu)模式如下圖所示。

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

          微服務(wù)架構(gòu)是強調(diào)細粒度、單一職責(zé)的架構(gòu)模式。微服務(wù)架構(gòu)更關(guān)注的是系統(tǒng)的非功能需求:質(zhì)量屬性、演進能力、擴展性、觀測性、軟件交付效率等。微服務(wù)使用CQRS(命令/查詢職責(zé)分離)中的事務(wù)腳本模式應(yīng)對查詢場景,而對于復(fù)雜的業(yè)務(wù)邏輯場景,使用領(lǐng)域驅(qū)動設(shè)計模式。微服務(wù)架構(gòu)模式如下圖所示。

          本文內(nèi)容摘自 《微服務(wù)架構(gòu)深度解析:原理、實踐與進階》 一書,想了解更多微服務(wù)架構(gòu)內(nèi)容,歡迎閱讀此書!

          本書從微服務(wù)架構(gòu)的設(shè)計理念和方法論切入,從不同角度全面介紹微服務(wù)特性、使用場景、組織流程、構(gòu)建交互、部署交付等軟件工程各個關(guān)鍵環(huán)節(jié)和核心要素,既包含了具體微服務(wù)技術(shù)的源碼解讀、原理分析,也加入了作者在電信、金融領(lǐng)域積累的真實案例和實踐經(jīng)驗。

          往期推薦

          程序員加入新團隊必問的20道問題

          只是想虐下春麗,一不小心擼了臺游戲機...

          Spring Boot中使用時序數(shù)據(jù)庫InfluxDB

          萬萬沒想到!logger.info() 還能導(dǎo)致線上故障?

          Java 中的 BigDecimal,你真的會用嗎?



          喜歡本文歡迎轉(zhuǎn)發(fā),關(guān)注我訂閱更多精彩

          關(guān)注我回復(fù)「加群」,加入Spring技術(shù)交流群

          瀏覽 65
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  A3级黄色视频 | 国产综合久久久777777 | 综合网AV | 手机免费看AV片 | 日韩a在线观看 |