欧美深夜视频_国产精品99视频_国产精品网站一区_亚洲最大av网

企業微信大型Android系統重構之路

2024-9-1 17:44| 發布者: 黃寧| 查看: 456| 評論: 0

作者:yeconglu
企業微信本地部署版(下文簡稱為本地版)是從2017年起,脫胎于企業微信的一款產品。本地版的后臺服務能獨立部署在政府或者大型企業的本地服務器上。在一個已經迭代了7年的大型Android系統中,企業微信本地版不可避免地會暴露出一些遺留系統的特點。本文將探討我們在實踐中采用的一些行之有效的重構案例,以及如何讓一個大型軟件系統持續保持活力。

一、遺留系統的特點

Martin Fowler 曾經說過這樣一句話:
Let’s face it, all we are doing is writing tomorrow’s legacy software today.

你現在所寫的每一行代碼,都是未來的遺留系統。
很多人以為存在時間很長的就是遺留系統,但這其實是個誤區。時間長短并不能作為衡量遺留系統的標準。判斷遺留系統的幾個維度是:代碼、架構、測試、DevOps以及技術和工具。代碼質量差、架構混亂、沒有測試、純手工的 DevOps(或運維)、老舊的技術和工具,才是遺留系統的真正特點。
看看下面這 6 個問題是否在你的項目中也曾經遇到過。



如果你的產品也有類似的一些問題,符合的“癥狀”越多,你的產品就越趨近于一個遺留系統。當遺留系統這個泥球越滾越大時,我們對它投入的改造成本就會越來越高。遺留系統就像一輛老破舊的小汽車,不知道啥時候會出問題,維修成本也越來越高,想快也快不起來。
二、重構的類型和收益

重構(名詞):對軟件內部結構的一種調整,目的是在不改變軟件可觀察行為的前提下,提高其可理解性,降低其修改成本。

小型重構是指對單個類內部的重構優化。通常包括對方法名稱、方法參數數量、方法大小等內容的修改。中型重構是對多個類間的重構優化,通常的一些修改包括提取接口、超類、委托等調整。大型重構是對整個系統的架構進行重構優化,比如組件化、應用中臺架構升級等,通常在做大型重構時也會伴隨中小型的代碼重構。以組件化為例,通過提取公用的基礎組件和業務組件,來提高代碼的可復用性,同時讓業務能獨立演進,就是一種大型重構。重構的目的是在不改變軟件可觀察行為的前提下,重點提高其可理解性,降低其修改成本。因此計算重構收益的方式很簡單,從商業的角度來看,收益 = 軟件價值 - (研發 + 維護成本)。



如果我們只注重業務上的價值而忽略了軟件的研發維護成本,那么長此以往就會來到拐點 1。當研發維護成本超出業務價值,收益就開始負增長了。很多企業往往也是到這個拐點才意識到重構的重要性。
通常來說,重構需要一段時間的投入,來慢慢降低研發維護成本,有的需要幾個月,有的甚至超過一年。但如果能堅持下來,就會來到拐點 3,此時收益開始正向增長。
三、遺留系統重構策略

3.1 絞殺者模式

3.1.1 定義

這個模式是指我們在替換一個軟件系統時,在舊系統旁邊搭建一個新系統,讓它緩慢增長,與舊系統同時存在,逐步地“絞殺”舊系統。這個“逐步”的意思,其實就是增量演進。“同時存在”指的是并行運行。
它有三個優勢:第一,不會遺漏原有需求;第二,可以穩定地提供價值,頻繁地交付版本,更好地監控其改造進展。第三,避免“閉門造車”。
劣勢主要來自迭代的風險和成本,絞殺的時間跨度會很大,存在一定風險,而且還會產生一定的迭代成本。



3.1.2 案例:啟動任務重構

3.1.2.1 問題

最開始時,我們的啟動任務邏輯全部都寫在 ApplicationonCreate中。隨著啟動邏輯越來越復雜,這部分代碼越來越難以維護,而且很難監控每個版本中由于啟動任務邏輯的變化,而帶來的啟動速度變化。
下圖所示是一部分重構前的啟動任務邏輯,各種業務的啟動任務都寫在 initMainProcess()中。



3.1.2.2 方案

重構后我們引入了啟動任務管理框架,不同業務的啟動任務劃分到不同的Task中,按照順序裝載到對應的進程。



每個Task實現一個相對比較內聚的功能:



但是由于啟動任務邏輯的復雜性,我們沒有一次性把所有啟動邏輯都重構成Task的形式,而是新邏輯使用Task的形式,舊邏輯逐步遷移。這種新舊寫法共存的情況維持了相當長的一段時間,直到所有啟動邏輯都最終遷移到了新的啟動框架中,后續 ApplicationonCreate中也不允許再增加新的啟動邏輯。
3.1.2.3 效果




重構后,啟動Task的功能職責單一化,達到了高內聚、低耦合的目標。而且對于新增的啟動任務,以及每個任務的速度劣化,都更方便監控了。
3.2 修繕者模式

3.2.1 定義

絞殺植物模式適合用于新的系統和服務,替換舊的系統或舊系統中的一個模塊。在舊系統內部,也可以使用類似的思想來替換一個模塊,只不過這個模塊依舊位于舊系統中,而不是外部。我們把這種方式叫做修繕者模式。
修繕者模式是對于現有系統新增一層進行封裝,然后在保證新層對外提供功能不變的情況下,對系統內部進行改造。



3.2.2 案例:云服務重構--中間分發層重構

3.2.2.1 問題

本地版客戶端除了能連接到本地版的服務器,還能連接到Saas的云端服務器,實現這部分能力的模塊稱為云服務模塊。



為了在同一個UI頁面,同時支持使用本地版服務和云服務,我們基于這兩個底層服務構建了一個中間分發層。中間分發層能夠根據不同的情況,適當地將請求分發給本地版服務或者云服務。



Android開發中使用maven依賴其他模塊時,有implementation和api兩種方式,它們的區別是:
    implementation關鍵字用于將依賴的庫隱藏在當前模塊內,只能在當前模塊中訪問,不會傳遞給其他依賴該模塊的模塊。api關鍵字用于將依賴的庫的公共接口暴露給其他模塊,可以在其他依賴該模塊的模塊中直接訪問。
但是由于分發層的隔離不夠嚴格,使用了api依賴云服務模塊,導致業務層也可以繞過分發層,直接調用本地版服務或者云服務。業務層開發需要根據具體情況,考慮應該在什么情況調用哪個服務,增加了維護成本和出錯的概率。
3.2.2.2 方案

我們針對分層不夠清晰的問題,重構了一套嚴格編譯隔離的云服務底層:業務層調用者必須通過中間分發層調用本地版服務或者云服務,無法繞過中間層。
具體的做法是改成使用maven的implementation依賴方式,使得云服務底層的maven依賴不會傳遞給業務模塊,保證只有中間層能夠調用云服務底層,而業務層只能依賴中間層。



重構的過程是可以小步進行的:先把一個業務模塊對云服務底層的依賴改成只依賴中間層,然后編譯,接著逐個處理編譯錯誤。處理完一個業務模塊就可以提測這個模塊。
3.2.2.3 效果

在保證新的中間層對外提供功能不變的情況下,我們漸進式地對中間層進行了重構,逐個模塊地把非預期中的跨層依賴都剝離掉。
整個過程修改的Java文件數量超過800+,從此業務層只能通過中間層調用本地版通用底層或者Saas通用底層,跨層調用都會直接報編譯錯誤
3.3 拆遷者模式

3.3.1 定義

基于原有的業務,新寫一套系統,然后一次性將舊系統的數據和功能,遷移到新系統上。
3.3.2 案例:生命周期重構

3.3.2.1 問題

我們本地版原來已經有一套頁面生命周期的監控模塊,后來又引入了一套Saas的頁面生命周期監控模塊。兩個模塊的功能大部分重復又不完全相同,維護的成本很大,比如開發做一個功能可能得同時修改兩個模塊的代碼,而且兩個模塊的修改都是類似的。
3.3.2.2 方案和效果

雖然這個模塊的改動影響很大,但是為了徹底解決遺留代碼帶來的問題,我們在一次迭代中合并了兩個模塊的代碼,一次性切到新的唯一一個生命周期監控模塊中。
四、架構重構

在本節中,我會介紹兩個架構重構的案例:組件化和云服務ProtoBuf定義統一。一般來說,挑戰可以歸納成兩大類。首先是普遍性挑戰,比如組件化重構,我將會展示我們是如何深入理解業務需求,找到量身定制的組件化重構方案。其次,是特有的業務挑戰。以本地版為例,我們面臨的是歷史遺留問題,比如本地版和Saas兩種沖突的PB定義共存的情況。這種獨特的挑戰要求我們不僅要有技術上的廣度,還需要深度和創造性地思考。接下來,我將分享我們如何安全小步地實施架構重構,同時保持系統持續迭代。
4.1 組件化

4.1.1 意義

單體架構是常見的架構模式之一。通常所有開發人員基于單個模塊進行開發,所有業務功能都集成在一起打包發布。單體架構非常適合團隊規模小、業務復雜度低的產品,在項目起始階段能快速迭代進行驗證。
隨著業務的持續演進,代碼不斷地膨脹和腐壞,所以代碼內部的耦合度很高。在這樣的基礎上修改代碼,非常容易牽一發而動全身:修改一個 Bug,又引起另外一個 Bug;開發一個功能,又引起另外一個功能的異常。
4.1.2 重構過程

4.1.2.1 方案

這里先簡單講述一下企業微信組件化的技術方案,但是不會涉及太多細節。
組件間的通信方案使用接口,即每個模塊各自提供一批對外的api接口,其它模塊只能訪問到這些api,如圖:



工程結構上使用Module這種官方的形式進行工程結構拆分,各組件之間能只能訪問到對方的api,通過只依賴api而不依賴本體的形式來實現的代碼隔離。
組件化方案確定后,解耦遺留代碼的過程是漫長而瑣碎的。這里我更想著重敘述下本地版是如何推進組件化項目的進度,以及提高組件化實施的效率的。
4.1.2.2 進度管理

一個完整的組件化重構步驟如下圖所示:



劃分出不同功能模塊的分界線后,我們把不同模塊的解耦任務分給對應負責的開發。然后我們做了一個網站自動監控每個模塊的解耦進度:



統計每日的解耦類和api數量:



我們通過這種方式持續推進這個維持了一年多的組件化大型重構項目,讓每個模塊的解耦進度和組件化程度都可以一目了然。
4.1.2.3 自動化重構腳本

組件化的過程中,最常見的操作就是把更為內聚的一些類移動到同一個組件內,以及為隔離的組件提供對外的API接口。為了提高組件化的效率,我們開發了許多解耦代碼的腳本,用于抽取組件API、移動類、移動資源,大大提高了全組開發實施組件化的效率。
自動化重構腳本分析和移動基礎庫ui_foundation的執行示例:



4.1.3 效果

    抽取基礎庫40+,類1700+



    抽取業務模塊30+,抽取接口數2200+



4.2 云服務ProtoBuf定義統一

4.2.1 問題:兩套相似又不相同的ProtoBuf定義共存

由于本地版的歷史需求和Saas既有相同也有不同的地方,所以造成了兩者的ProtoBuf有大量相同重合的地方,但是少量字段又并不是完全一樣的。而且在開始沒有開發規范的情況下,產生了沖突的數據字段,也就是在同一個Message結構體的相同位置的字段,在本地版和Saas中的類型或者含義是不一樣的。



雖然后面我們已經意識到這個問題,對本地版需求新增加的ProtoBuf字段索引都增加了1000,以此避免沖突,但是歷史已經放出去的版本也無法再修改。如果沒有一個兼容舊版本的方案,那沖突的字段只能一直保留著。
在本地版的業務層中,本地版的ProtoBuf和Saas的ProtoBuf一起編譯,由于不能存在包名和類名都一樣的類,所以本地版的ProtoBuf包名都從wework修改成了weworklocal。因此業務開發需要關注當前使用的是哪套ProtoBuf,而選擇引入不同的包名,大大增加了代碼的理解成本和開發成本。
4.2.2 方案:統一ProtoBuf定義

4.2.2.1 沖突類型

為了實現兩套通用底層的PB統一,最大的問題是如何兼容兩份PB的沖突字段。本地版PB和SaasPB的字段沖突類型,主要有4種:
    類型相同,但名字不同,實際業務含義不同類型不同,名字不同本地版獨有字段enum值沖突
4.2.2.2 分層設計

為了解決PB字段沖突的問題,我們增加了一個沖突轉換層:



    上層UI統一使用Saas的PB結構本地版通用底層和UI之間,增加一層轉換層,負責把沖突的PB字段重新賦值本地版的底層繼續使用原有的本地版PB
4.2.2.3 自動化重構腳本

針對重復性工作,我們使用腳本對比Proto,找出沖突字段并進行自動化處理,提高效率,流程如下:



自動化重構腳本方案收益如下:
    無需手動對齊Proto文件 Proto文件數量470+,以處理一個文件15分鐘計算,可節省工作量約5人日。自動生成轉換代碼 沖突字段110+,每個沖突需實現3個轉換函數,總計可以少寫6000+行代碼。出現新沖突時,可以重復生成新的轉換代碼。
4.2.3 效果

    對組件化的收益:可以消除約50%云服務需求導致的接口差異。減少了開發的理解和維護成本:后續維護的開發都不需要過多關注當前是需要使用本地版還是Saas的協議。
五、代碼重構

5.1 過大類重構

將大型的單體遺留系統重構為組件化架構后,我們有了更加低耦合、高內聚的組件。但是回到組件內部,代碼質量對開發也非常重要。我相信你在過去的代碼里一定會遇到一種典型的代碼壞味道,那就是“過大類”。在產品迭代的過程中,由于缺少規范和守護,單個類很容易急劇膨脹,有的甚至達到幾萬行的規模。過大的類會導致發散式的修改問題,只要需求有變化,這個類就得做相應修改。
隨著業務需求和代碼規模的不斷膨脹,我們針對過大類的重構策略就是分而治之。通過分層將不同維度的變化控制在獨立的邊界中,使之能夠獨立的演化,從而減少修改代碼時彼此之間產生的影響。
5.2 會話列表重構

5.2.1 業務分析和代碼分析

對于遺留系統來說,比較常見的問題就是需求的上下文中容易存在斷層,所以第一步就是盡可能地了解、分析原有的業務需求。只有更清楚地挖掘原有的需求設計,才不會因為理解上的差異出現錯誤的代碼調整。接下來我們以會話列表頁面為例,講述我們重構過大類的過程。下圖是我們對會話列表涉及的業務功能進行的梳理:



下圖是會話列表頁面的示意圖:



5.2.2 架構設計

分析完之后,接下來就是進行架構設計了。這一步讓我們在開始動手重構前,想清楚重構后的代碼將會是什么樣子,以終為始才能讓我們的目標更加清晰,讓過程更加可度量。
現在主流APP框架都是用一套MVP或者MVVM框架來解耦。企微還是傳統的MVC方案,由于歷史原因修改成MVP或者MVVM都會有非常大的成本。
于是我們創建了一個新的MVCs的框架。MVCs的主要理念是將View和Model的交互,變成一個可插拔的抽象的邏輯。所以一個Controller描述的是一組View與一組Model的關系,從理念上,它應與業務無關。MVCs架構在面對企微這種復雜度的場景下,已經可以較好得支撐實際面臨的業務需求。
5.2.3 小步安全重構

建立一個IController,抽象出和 Activity/Fragment相同的生命周期,然后在Activity/Fragment相同的生命周期執行。同時一個IController可以包含多個IController,先執行本身的邏輯,然后再執行子IController邏輯,同時提供懶加載方案LazyController ,當達到一定條件的時候才會加載,保證性能和效率。



基于MVCs,我們將頁面重構成了各個不同的Controller,把舊頁面超大類中的一個個業務逐步拆分到獨立的Controller中:



每個controller對應一個具體的業務場景,例如:
    ConversationLogController對應日志相關的邏輯。ConversationDataInitController對應數據初始化。ConversationHeaderStatusBarViewInitController對應頭部狀態相關邏輯。
5.2.4 效果




在采用MVCs框架進行重構后,平均每個Controller的代碼行數降低到了約365行。這意味著我們成功地實現了Controller功能職責的單一化,達到了高內聚、低耦合的目標。
通過這些改進,我們的代碼變得更加清晰、易讀,降低了維護成本。同時,由于各個功能模塊之間的耦合度降低,我們可以更加靈活地對現有功能進行修改和擴展,以滿足不斷變化的業務需求。這些成果充分證明了MVCS框架在實際項目中的有效性和可行性,為后續重構其他大型頁面提供了有益的借鑒。
六、DevOps重構

6.1 Bazel編譯

企業微信本地版有大量的網絡通訊、數據庫存儲等底層通用能力是使用C++實現的,之前是以典型的Android.mk作為構建工具來構建動態庫。Bazel則是更為現代化的構建工具:Bazel能夠緩存所有以前完成的工作,并跟蹤對文件內容和構建命令的更改,因此Bazel在構建時只對需要重建的部分進行構建;同時,Bazel支持項目以高度并行和增量的方式構建,能夠進一步加快構建速度。
目前,本地版Android端的底層動態庫已經全量換成使用Bazel構建,下面是其中一個構建腳本的例子:



6.2 分支管理

因為本地版需要面向很多大型政企用戶,不同的政企可能會有不同的包名、不同的發布分支、不同的發布計劃,而且這些發布計劃還會并行發布。為了讓各個角色的成員都能清晰了解和管理當前正在發布的分支和迭代,我們開發了專門的分支管理頁面,自動化拉取、合并不同的迭代分支,以及管理迭代的生命周期。



6.3 流水線管理

本地版客戶端的模塊眾多,不同的模塊可能是由不同的團隊負責開發的。下面是我們依賴的一些跨倉庫組件的示意圖:



不同的組件由不同團隊維護的流水線構建,最后以maven的形式集成到本地版企業微信APP中。當分支管理工具拉出一條新分支時,就會自動實例化各個業務組件的子流水線。這樣我們可以做到即使在多團隊、多倉庫、多分支開發的情況下,組件編譯和集成編譯都可以全自動進行。



七、總結

冰凍三尺非一日之寒 ,遺留系統不是一天就產生,也不單純因為一次提交就演化而來,而是隨著不斷的版本更迭、人員變換、代碼不斷累積腐化而導致的。
遺留系統的技術債務就像一座冰山,雖然表面平平無奇,但是底下卻是縱橫交錯。可怕的是很多時候我們卻只看到了表面,而卻無法真正發現阻礙產品快速演進的元兇。
主動、持續地改進甚至重構系統,才能適應變化。遺留系統重構的最終目標是構建一個具有可擴展性、高性能、高可用性的系統架構,提高系統的開發效率和產品的迭代速度。
分享到:
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

交流熱線
17501437970 周一至周日:09:00 - 21:00

創贏網-致力于幫助普通人在創業之路上披荊斬棘、走向成功的專業網站,匯聚創新智慧與成功機遇的網絡天地,是創業者開啟贏之征程的首選之地。

Powered by Discuz! X3.5 © 2023-2050 CHUANYING Team.

QQ|Archiver|手機版|小黑屋|創贏網 ( 湘ICP備17022177號-3 )

GMT+8, 2025-10-30 06:05 , Processed in 0.441346 second(s), 30 queries .

快速回復 返回頂部 返回列表
欧美深夜视频_国产精品99视频_国产精品网站一区_亚洲最大av网
午夜精品久久久久久久蜜桃app| 国产一区视频网站| 轻轻草成人在线| 538prom精品视频线放| 亚洲成人精品影院| 日韩欧美在线一区二区三区| 秋霞成人午夜伦在线观看| 精品久久久网站| 成人激情图片网| 调教+趴+乳夹+国产+精品| 欧美第一区第二区| 91免费看片在线观看| 天堂va蜜桃一区二区三区 | 色哟哟国产精品免费观看| 亚洲综合色网站| 精品人在线二区三区| 91在线精品一区二区三区| 日韩精品电影在线| 中文字幕一区二区三区在线观看| 欧美猛男超大videosgay| 国产一区二三区| 亚洲高清不卡在线| 亚洲欧洲一区二区三区| 日韩精品一区二区三区在线| 99re热这里只有精品免费视频| 蜜臀av一区二区| 亚洲午夜电影网| 中文字幕高清一区| 日韩一区二区影院| 欧美午夜精品免费| 91日韩在线专区| 国产精品99久久久久久似苏梦涵 | 欧美另类变人与禽xxxxx| 国产成a人无v码亚洲福利| 婷婷开心久久网| 亚洲激情图片一区| 日本一区二区成人在线| 日韩三级伦理片妻子的秘密按摩| 色狠狠综合天天综合综合| 白白色 亚洲乱淫| 国产成人综合视频| 寂寞少妇一区二区三区| 日一区二区三区| 日韩电影免费一区| 日韩在线一二三区| 爽好久久久欧美精品| 亚洲妇熟xx妇色黄| 亚洲成人黄色影院| 亚洲国产乱码最新视频| 亚洲欧美偷拍另类a∨色屁股| 国产婷婷色一区二区三区| 精品国产乱码久久久久久免费 | 久久久欧美精品sm网站| 日韩女同互慰一区二区| 日韩一区二区在线观看视频 | 成人免费的视频| 国产成人免费9x9x人网站视频| 蜜桃传媒麻豆第一区在线观看| 日本午夜精品视频在线观看 | 欧美老肥妇做.爰bbww视频| 精品视频免费看| 欧美剧情片在线观看| 在线成人午夜影院| 日韩欧美亚洲国产精品字幕久久久| 7777精品伊人久久久大香线蕉超级流畅 | 久久不见久久见免费视频7| 麻豆国产一区二区| 国产精品18久久久久久久久| 国产精品 欧美精品| 成人免费看的视频| 在线亚洲+欧美+日本专区| 欧美日本韩国一区二区三区视频 | 国产精品77777| 不卡一区中文字幕| 在线免费视频一区二区| 911国产精品| 久久精品无码一区二区三区| 中文字幕欧美区| 亚洲综合在线电影| 毛片av一区二区三区| 国产99精品国产| 欧美日韩美少妇| 久久综合资源网| 亚洲少妇30p| 免费成人av资源网| 91丨国产丨九色丨pron| 欧美一区二区三区四区高清| 国产欧美一区二区精品性色 | 六月丁香婷婷色狠狠久久| 成人污污视频在线观看| 在线成人高清不卡| 国产精品网站在线播放| 日日噜噜夜夜狠狠视频欧美人| 国产精品一二三在| 欧美精品久久久久久久多人混战 | 欧美国产精品中文字幕| 亚洲午夜久久久久久久久电影院| 蜜臀av在线播放一区二区三区| 懂色av一区二区三区蜜臀| 91精品国产入口| 成人欧美一区二区三区黑人麻豆| 日韩成人免费在线| 欧美在线一二三四区| 欧美激情一区二区三区全黄| 午夜电影网亚洲视频| 91香蕉国产在线观看软件| 欧美精品一区二| 日韩电影免费在线看| 欧美午夜寂寞影院| 一区二区三区在线播| 成人午夜大片免费观看| 欧美精品一区二区三区视频| 日韩和的一区二区| 欧美四级电影在线观看| 亚洲精品成人精品456| 成人va在线观看| 久久综合久久99| 麻豆精品久久久| 欧美大片拔萝卜| 日本一区中文字幕 | 亚洲精品福利视频网站| 国产伦精品一区二区三区视频青涩 | 免费不卡在线视频| 欧美精品在线一区二区| 一区二区三区四区高清精品免费观看| 国产精品影视在线观看| 精品va天堂亚洲国产| 精品一区二区免费| 国产午夜亚洲精品不卡| 激情综合五月天| 精品奇米国产一区二区三区| 韩国精品久久久| 久久午夜羞羞影院免费观看| 紧缚奴在线一区二区三区| 久久综合国产精品| 国产一区二区三区四区五区入口| 日韩免费电影网站| 国内外精品视频| 欧美激情中文字幕| a亚洲天堂av| 亚洲黄色性网站| 欧美色网站导航| 亚洲成人久久影院| 精品久久人人做人人爽| 狠狠狠色丁香婷婷综合久久五月| 久久精品亚洲精品国产欧美kt∨ | 亚洲欧美国产三级| 欧美日韩你懂得| 青草av.久久免费一区| 精品欧美乱码久久久久久| 国产在线视频不卡二| 国产精品久久午夜| 在线亚洲一区观看| 蜜臀久久99精品久久久久宅男 | 久久久不卡影院| 9人人澡人人爽人人精品| 亚洲人吸女人奶水| 777亚洲妇女| 成人av免费在线观看| 亚洲图片自拍偷拍| 国产亚洲欧美日韩日本| 99精品一区二区| 美国欧美日韩国产在线播放| 亚洲国产高清在线| 欧美日韩免费电影| 国产精品一区久久久久| 一区二区高清在线| 久久精品在这里| 欧美日韩国产一级| 国产成a人亚洲| 午夜婷婷国产麻豆精品| 久久久91精品国产一区二区精品| 色呦呦一区二区三区| 国产精品影视天天线| 亚洲制服丝袜在线| 欧美国产视频在线| 日韩欧美在线不卡| 色综合中文字幕| 国产一区二区导航在线播放| 亚洲线精品一区二区三区 | 麻豆传媒一区二区三区| 综合久久国产九一剧情麻豆| 91精品国产品国语在线不卡| 99视频超级精品| 国产精品影视在线观看| 人禽交欧美网站| 亚洲欧美aⅴ...| 久久综合色婷婷| 欧美一级欧美一级在线播放| 91麻豆.com| thepron国产精品| 国产又粗又猛又爽又黄91精品| 午夜精品福利一区二区蜜股av| 国产精品人妖ts系列视频 | 精品国产三级电影在线观看| 欧美日韩精品一区二区三区| 99亚偷拍自图区亚洲| 成人激情开心网| www.综合网.com| 91丨porny丨中文|