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

基于開源方案構建統一的文件在線預覽與office協同編輯平臺的架構與實現歷程

開發 架構
對于人力不是特別充裕、或者項目投入預期規劃不是特別大的公司或者項目而言,通常會選擇基于一些開源方案來實現,但是開源組件選擇之后,如何將其無縫對接融入到自己的業務系統中并完全支持自身訴求的實現,不僅要能用、而且要好用,其實也是一個需要好好思量的問題。

大家好,又見面了。

在構建業務系統的時候,經常會涉及到對附件的支持,繼而又會引申出對附件在線預覽、在線編輯、多人協同編輯等種種能力的訴求。

圖片

對于人力不是特別充裕、或者項目投入預期規劃不是特別大的公司或者項目而言,通常會選擇基于一些開源方案來實現,但是開源組件選擇之后,如何將其無縫對接融入到自己的業務系統中并完全支持自身訴求的實現,不僅要能用、而且要好用,其實也是一個需要好好思量的問題。

此前在項目中就曾遇到過這么個場景,下面一起分享下具體的架構設計調整演進與最終方案落地策略,以及過程中遇到的一些問題。

開源組件的選擇

在正式開始構建在線的文件管理服務前,首先是分析下需要支持的功能訴求:

  • 需要支持office文檔的在線預覽、在線協同編輯能力
  • 需要支持常見的主流文件的在線預覽,比如圖片、視頻、文本文檔、PDF、壓縮包之類的
  • 需要支持文件的存儲管理能力

圖片

對于文件的存儲管理,直接采用了公司內部私有云的OSS文件托管服務進行實現,實現起來比較簡單。文件在線預覽與Office文件在線編輯的能力,則選用相關的開源方案來實現。經過一番對比分析,最終選定了兩個開源組件:

  • OnlyOffice用于支持office文檔的在線協同編輯、預覽等能力。
  • kkFileView用于支持常規文檔的在線預覽能力

選型確定之后,就是如何與現有業務系統進行整合了。因為開源組件往往都是通用邏輯設計的,而業務系統的邏輯又各不相同,所以如何去整合并方便擴展出自己需要的定制化能力,成了下一步擺在眼前需要處理的問題。

整體適配對接策略

為了保證業務系統的穩定,避免業務系統中強耦合文件預覽相關的開源模塊,同時也為了方便業務層的調用,所以規劃構建一個統一的入口代理轉接服務,統一由此服務對業務系統提供預覽與在線編輯相關能力,對業務層屏蔽掉底層具體的開源方案整合邏輯。這樣的好處是,不管預覽與編輯服務這邊如何調整,甚至后面更換實現方案,都不會影響到業務層的調用邏輯。

圖片

系統邊界劃定,對業務系統整體的接入配合而言就簡單了:

  • 業務系統只需要與預覽編輯服務之間進行接口與實現層面的約定對接即可,其實也是系統內部的模塊間規范定義
  • 預覽編輯服務負責完整的業務系統請求的鑒權、與開源組件之間的適配轉換、業務定制化的預覽與編輯能力擴展等等。

預覽編輯服務,作為業務系統的邊緣代理適配器模塊,需要保證提供給左側業務系統的接口的穩定,而右側具體對接的開源方案、內部處理邏輯等,則可以隨意調整。

整合OnlyOffice實現Office文檔在線預覽與編輯

讓業務代碼無耦合的方式使用預覽能力

OnlyOffice作為一個負責office在線預覽的功能組件,其提供了一個JS API方法。具體使用的時候,需要在HTML頁面中引用其提供的JS文件并調用對應API方法將請求參數傳遞給OnlyOffice進行處理。這些請求參數里面,既含有對文檔在線顯示相關的一些屬性約定,還包含一個重要的參數,也即需要操作的目標Office文件的獲取地址url。在OnlyOffice收到請求之后,需要去給定的地址下載目標Office文件,然后內部解析處理之后,按照請求參數的指定信息,渲染展示到界面上。

圖片

在實際的系統規劃中,為了便于后續版本升級維護,以及避免OnlyOffice強耦合到各個業務系統中,所以不太傾向于讓前端界面直接去集成與調用OnlyOffice相關的JS文件。

所以在實施的時候,在服務端的文件預覽編輯服務中進行了封裝,對外提供服務端API接口,服務端自帶一個簡單HTML界面(基于SpringBoot + Thymeleaf實現),業務請求對應服務端提供的獨立html界面,并在界面中完成使用OnlyOffice的JS api請求的操作。

具體步驟說明如下:

  • 對外提供服務端HttpGet?接口,借助Thymeleaf?框架,界面跳轉出現對應html界面

圖片

  • 提供簡單的HTML界面,用于引入OnlyOffice JS文件,作為最終顯示界面外殼:

圖片

  • 在獨立的JS?文件中,接收從JAVA?邏輯中傳入的參數信息,然后轉換封裝為OnlyOffice?需要的格式,然后調用OnlyOffice的API接口發送請求

圖片

這樣就實現整體的交互封裝,業務可以代碼無耦合的方式來直接使用預覽能力。具體的office文檔在線預覽與編輯的能力實現,由開源的OnlyOffice來提供。

圖片

具體使用的時候,交互邏輯如下:

  • 向文件預覽服務發送請求,指定要操作某個文檔;
  • 文件預覽服務經過對請求的鑒權以及其他處理邏輯之后,瀏覽器會跳轉出OnlyOffice在線文檔預覽編輯界面,此步驟也會攜帶上具體的文檔操作屬性數據(比如文件下載地址、文件更新保存回調地址等)、以及操作的用戶信息、允許當前用戶執行的具體操作權限等等信息;
  • 在打開的界面上,用戶可以執行查看或者編輯等操作;
  • OnlyOffice?會通過指定的接口地址,獲取要操作的文件的數據,以及編輯之后調用指定的回調接口,將更新后的內容保存。

看似很復雜的邏輯,但是經過封裝之后,對于業務使用而言其實很簡單,只要在發送給文件預覽服務的請求中,給定一個文件下載地址與文件保存回調地址即可。

協同在線編輯能力的關注點

前面有提過,采用OnlyOffice來實現office文檔的在線協同編輯,關于OnlyOffice在線編輯的原理,其官網給出的介紹如下:

圖片

對上述步驟解釋如下:

圖片

也即當用戶關閉文檔編輯界面之后,會觸發文檔的保存事件,回調callback接口,將保存事件推送給服務端,并告知服務端變更后的文檔地址,這樣服務端可以從給定的地址下載變更后的文檔,然后更新到自己的存儲中。

結合到我們具體的項目使用中,其具體的交互過程展開闡述下,就是下圖的過程:

圖片

這里,一個在線編輯操作的回調請求內容示例如下:

{
"actions": [{"type": 0, "userid": "78e1e841"}],
"changesurl": "https://documentserver/url-to-changes.zip",
"history": {
"changes": changes,
"serverVersion": serverVersion
},
"filetype": "docx",
"key": "Khirz6zTPdfd7",
"status": 2,
"url": "https://documentserver/url-to-edited-document.docx",
"users": ["6d5a81d0"]
}

關于回調請求的各個參數的具體含義,可以參見官網介紹,需要特別關注的幾個字段梳理如下:

字段

字段類型

含義說明

actions

??List<Object>??

每個用戶加入或者退出此文檔的編輯的動作信息。其中具體type的取值0表示斷開連接,1表示建立連接

key

??String??

目標文檔在OnlyOffice中處理的唯一標識ID,注意這里的key與業務系統中目標文件實際的唯一ID并非一個概念,不能混為一談,因為業務系統中某個文件的ID需要保持不變,但是在OnlyOffice中編輯的時候,這個key需要不停的變。

status

??Integer??

文檔當前的操作狀態類型,取值說明:

1: 文檔正在被編輯

2:文件已準備好保存

3:文檔保存發生錯誤

4:文件關閉,沒有變化

6:文檔正在被編輯,但是當前狀態已經被保存

7:強制保存文檔時發生錯誤

url

??String??

改動后的文檔的下載地址,可以從這個地址下載到變更后的文件,然后存儲更新業務系統中實際的文檔

實際測試的時候發現,此處的回調接口被調用的情況非常的頻繁,務必要注意當且僅當actions中所有的對象的type都等于0的時候,也即所有用戶均已經退出編輯且文檔已經準備好保存的時候,回調接口被調用的時候才需要去更新key值。

圖片

這里是在實際構建的時候踩坑較久的一個地方,下面章節中展開詳細說下踩坑過程。

OnlyOffice協同編輯踩坑記

在借助OnlyOffice構建在線協同編輯能力的時候,遇到一個很奇怪的問題,打開一篇文檔,在線對其內容進行編輯,然后編輯完成后關閉窗口,過了一段時間嘗試再次打開文檔編輯的時候,卻會報錯:

圖片

看了下官網的問題原因解釋,就是因為文檔編輯之后,原來的key對應的文檔已經被編輯過,已經不能被打開了(可以把key理解為不同的version,文檔被編輯之后,version變更了,原來老的version就不允許操作了)。最后官網還很貼心的提示:別忘了每次編輯之后要重新生成一個新的key!

圖片

按照官網的介紹,在callback接口被調用的時候,重新為文件生成一個key,后續新的用戶想要加入此文檔的編輯的時候,都是拿到新生成的一個key,這樣不就可以了嗎?

  • Step1: 文檔打開的時候,先嘗試獲取已存在的key值,如果不存在則新生成一個key并緩存起來
try {
// 如果redis里面有緩存此文檔對應的key值,則直接使用
fileUniqueKey = redisCacheOperateService.getFileUniqueKeyDetail(fileId);
} catch (Exception e) {
// 如果redis里面沒有緩存此文檔對應的key值,則生成對應的key并加入緩存中
fileUniqueKey = FileUniqueKey.builder().build();
redisCacheOperateService.saveOrUpdateFileUniqueKeyDetail(fileUniqueKey);
}
//獲取本次在線操作對應的key值
document.setKey(fileUniqueKey.generatekey());
  • Step2: 文件編輯保存回調處理中,重新生成新的key值并更新緩存的key值
// 編輯成功后,重新生成隨機碼,實現key值變化的目的
fileUniqueKey.updateRandomUniqueKey();
redisCacheOperateService.saveOrUpdateFileUniqueKeyDetail(fileUniqueKey);

按照上述思路改完后,再次嘗試,發現:

  • 當用戶A打開文檔未做任何改動的時候,用戶B也去打開文檔,然后兩個用戶A、B都可以加入到同一個文檔的協同編輯中,也可以進行協同編輯了;
  • 當用戶A或B做了改動之后,再有一個新的用戶C加入此文檔編輯的時候,卻沒有辦法和A、B加入到同一個協同編輯會話中,C的改動會覆蓋到A和B的改動,同理A或者B的改動也會覆蓋掉C的改動。

難道只有讓大家都約好了一起加入進去再開始編輯才行嗎?那這個在線編輯功能顯然就是個雞肋了 —— 顯然OnlyOffice也不太可能會是這種實現。再全面復盤了下測試的現象,分析了下可能原因:

因為A、B使用同一個key,所以A和B可以加入到同一個協同編輯會話中

  • A或者B修改了文檔之后,在callback觸發的邏輯中,將此文檔對應的key更新成了一個新的值
  • C嘗試進行同一篇文檔的在線編輯的時候,因為使用的key和A、B使用的key不相同,所以這個時候對于OnlyOffice而言,其實C是在編輯一篇與A、B完全獨立的文檔
  • 所以問題還是出在了key的處理策略上。在網上找了一圈的文檔沒找到答案,受限于時間約束,也沒有去看過OnlyOffice的源碼,只能根據現象分析OnlyOffice內部是基于本地緩存來處理的,而key是能否讓請求打到同一份本地緩存的關鍵,猜測了下OnlyOffice內部的大致處理思路是下面這個樣子:

圖片

基于上述分析:

  • 要想多人參與到同一個協作編輯會話中,必須要保證所有人操作的key都是相同的一個
  • 要想編輯后的文檔能夠下次再被打開,必須保證下次打開的時候key使用新的值
  • key不變更的情況下,用戶A打開編輯的時候,窗口未關閉的情況下,用戶B可以加入,但如果用戶A關閉,用戶B再用同一個key訪問的時候,就會報錯。

所以說,如果每次只要有用戶還在線的時候,這個文檔的key就不應該變,只有等某篇文檔的所有用戶都關閉編輯窗口的時候,再去處理文檔key的變更,這樣不就解決問題了嗎?

那問題就簡單了,按照這個思路修改了下callback的代碼邏輯,判斷下某篇文檔的所有用戶都退出編輯之后,再去重新生成新的key值。

代碼演示如下:

@PostMapping("/callback")
public DocumentEditCallbackResponse saveDocumentFile(@RequestBody DocumentEditCallback callback) throws IOException {
try {
// 當且僅當所有用戶都退出后,才需要將key重新生成一下,否則下次再打開的時候,就打不開了
if (callback.getStatus() == DocumentStatus.READY_FOR_SAVING.getCode()
|| callback.getStatus() == DocumentStatus.BEING_EDITED_STATE_SAVED.getCode()) {
// 保存文件內容
documentService.saveDocumentFile(callback.getKey(), callback.getUrl());
// 如果所有用戶都已退出,則更新此文件對應的預覽key值
boolean allUserExits = callback.getActions()
.stream().anyMatch(actionsBean -> actionsBean.getType() == 0);
if (allUserExits) {
fileUniqueKey.updateRandomUniqueKey();
redisCacheOperateService.saveOrUpdateFileUniqueKeyDetail(fileUniqueKey);
}
}
return DocumentEditCallbackResponse.success();
} catch (Exception e) {
return DocumentEditCallbackResponse.failue();
}
}

代碼改動完成后,再次測試,果然問題消失,在線預覽功能恢復正常。

OnlyOffice集群化部署

為了保障預覽服務的可靠,在生產環境上規劃實施集群化部署。從上一章的闡述中,我們知道OnlyOffice的功能實現嚴重依賴單機本地的緩存數據信息,在集群部署的場景下,過度依賴本地緩存的弊端就顯現出來了。

集群化部署,本以為會很簡單,直接部署多個docker節點,然后使用Nginx做一下反向代理以及負載均衡不就可以了嘛?但是實際實施的時候卻發現在協同編輯場景下出現了預期之外的問題。因為多人在線協同編輯的能力要求所有人對某篇文檔的編輯請求都在同一個OnlyOffice服務節點上才行,而Nginx隨機負載分發,會導致同一篇文檔的編輯請求分發到不同節點上,這樣就會導致編輯的內容相互覆蓋。

圖片

因為用戶的請求并不是直接打到OnlyOffice地址上的,而是先打到文件預覽服務中,然后由文件預覽服務經過某種策略處理后,再將請求重定向到OnlyOffice服務上進行文檔操作的,所以這里我們可以通過增加一個簡單的分發策略,保證對同一個文檔的所有的請求操作,都被分發到固定的一個OnlyOffice服務上處理即可。

這里的分發策略,考慮有2種方案:

  • 根據每個文檔的唯一ID計算hashcode?值,然后與OnlyOffice節點數取余,決定每個文檔分別有哪個OnlyOffice服務處理。此方案實現起來最為簡單,但是存在的問題也不少(比如節點新增或者刪除的時候存在問題,需要上一致性hash算法)。
  • 通過隨機分發+Redis記住文檔與節點映射的方式,先隨機選擇一個節點,然后記錄下此文件與OnlyOffice節點之間的映射關系,然后后面對此文件的請求始終分發到該OnlyOffice節點上。

圖片

這里我們實現的時候采用了第2種方案,借助redis緩存來實現,整體策略如上圖示意。具體實現的時候對緩存數據增加了一定的過期與續期策略,既保證同一文檔請求分發到同一節點,又保證一定時間之后文檔分發緩存消失,可以重新分配空閑的OnlyOffice服務器(因為開源版本OnlyOffice只支持最大20并發量,所以可以在此層級進行分配調整)。

具體代碼邏輯如下:

public NodeServerInfo getOnlyOfficeServer(String fileUniqueId) {
// 從redis中先看下是否有分配過,如果有,繼續使用
NodeServerInfo existServer = redisCacheOperateService.getExistOnlyOfficeServerByFileId(fileUniqueId);
if (existServer != null) {
if (serverAvailable(existServer)) {
// 延長有效期
redisCacheOperateService.renewalOnlyOfficeMapExpireDays(fileUniqueId, onlyOfficeServerCacheDays);
return existServer;
} else {
// 刪除無效的緩存
redisCacheOperateService.deleteExistOnlyOfficeServerMapping(fileUniqueId);
}
}
// 重新選擇一個可用的server
NodeServerInfo nodeServerInfo = chooseAvaliableServer();
// 將文件與服務器之間映射關系存儲redis中
redisCacheOperateService.saveFileAndOnlyOfficeServerMapping(fileUniqueId, nodeServerInfo,
onlyOfficeServerCacheDays);
return nodeServerInfo;
}

至此呢,集群化部署的問題解決,可用性上得到的有效保證。并且通過定期探測機制,及時將不可用的OnlyOffice節點從候選列表中剔除掉,保證了請求始終在可用節點上,有效避免了單點問題的出現,也一定程度上緩解單個節點的壓力(社區版本同時僅支持20并發數、通過一定策略可以分散不同文件的請求到不同節點上)。

圖片

整合kkFileView實現其他文件的在線預覽

kkFileView作為一個基于JAVA構建的可獨立集成部署的文件預覽開源組件,其在各種文件的預覽上表現非常的優異,集成起來也非常的簡單,直接提供下文件下載的地址就可以了。支持Office文檔、圖片、視頻、音頻、壓縮包等各種文檔的預覽。

對于kkFileView的集成,我們采用了與OnlyOffice集成截然不同的處理策略,因為kkFileView基于JAVA SpringBoot技術棧構建,與我們業務系統技術棧一致,所以我們基于kkFileView的源碼進行了深度的定制整改。主要包括幾方面:

  • 已經采用了OnlyOffice來提供Office文檔的預覽與編輯能力,這樣kkFileView就不需要此部分能力,去掉此部分能力之后,整個kkFileView部署包體積縮小300M左右
  • kkFileView打包的時候是打成了zip包,然后通過start.sh?腳本來進行啟動的,我們適配了下公司內CI構建工具的特點,改為了經典的SpringBoot的部署形態,即1個jar搞定
  • 由于我們的文件獲取接口涉及到權限校驗,我們定制了下此部分的邏輯,對接了下統一的鑒權中心。

兩者融合:緩解OnlyOffice加載慢問題

基于前面整體的規劃策略,Office文檔使用OnlyOffice進行預覽操作,非Office文檔則由kkFileView實現預覽操作(業務調用方無感知,都是統一一個url地址)。開發完成部署上線之后,功能也都一切正常。

但是自從上線之后,用戶普遍吐槽在線Office文檔預覽的加載速度太慢,難以忍受。因為首次使用的時候OnlyOffice會在瀏覽器本地加載一個30M左右的緩存數據,而我們的服務部署在公司內網機房里面,通過多層代理開放到公網中,用戶在公司辦公網絡中訪問的時候,相當于繞了多層網絡代理,且由于公司辦公網絡對客戶端單機下行速率有限制,導致這個第一次加載緩存數據的時間需要10-15s左右才能加載出文件。

圖片

雖然僅僅是第一次的打開速度比較慢(如果清理了瀏覽器緩存之后,首次加載還是會慢),但是等待的時間確實也有點久,所以考慮進行優化,提升下用戶的體驗感知。

異步Office轉PDF進行預覽

雖然系統支持了Office文檔的在線預覽與編輯能力,但是統計了下,其實近乎95%的Office文檔操作都是預覽操作,考慮到kkFileView預覽PDF的速度非常的快,因此決定通過kkFileView來支持Office文檔的預覽操作,而OnlyOffice只用來做Office文檔的在線協同編輯,或者用于某些kkFileView預覽效果不夠好的Office文檔的兜底預覽場景。

因為kkFileView預覽Office文檔的策略是先將Office文檔轉換為PDF,然后采用預覽PDF的策略來實現的,為了進一步的提升速度,避免每次都實時去進行Office文檔轉PDF的操作,所以設計采用異步事件的方式進行預處理轉換,異步轉化Office文檔為PDF,然后對于Office文檔只讀場景直接使用PDF預覽即可。

圖片

當業務系統中的文件內容有新增或者變更的時候,具體的異步轉換處理的時序操作邏輯如下:

圖片

在線協同編輯的時候,需要監聽下每個文件的變更,如果編輯后的話,需要異步重新轉換下文檔緩存內容。

預留禁用緩存預覽的接口

到這里呢,對于快速預覽office文檔的邏輯,就算基本完成了。按照當前的策略,對于office文檔預覽的場景,默認都會使用轉換后的緩存PDF文檔進行預覽。在實際驗證的時候,偶爾會遇到一些轉換后PDF預覽效果不佳的情況, 所以為了解決此類問題,又對處理流程的邏輯進行了一點優化,請求參數中,預留了個字段,可以用于調用方設定是否禁用本地轉換緩存結果文件進行預覽:

@ApiModelProperty(value = "是否禁止使用轉換后的格式來預覽文件以提升速度,默認false", required = false)
private boolean notUseConvertedResultForPreview;

這樣呢,在預覽界面上可以提供個切換按鈕。如果預覽效果不滿意,可以直接切換到原始文檔采用OnlyOffice服務進行預覽,雖然速度慢些、但是可以解決預覽效果的問題。

圖片

整體實現全貌

到此呢,整個文檔的在線預覽與編輯能力的構建,就算完成了。在處理具體的文檔的預覽或者在線編輯請求的時候,對應的處理判斷總體邏輯如下:

圖片

回顧下構建之初規劃的功能訴求,也已經全部支持:

功能點

支持情況

常規文檔在線預覽

?

office文檔在線預覽

?

office文檔協同編輯

?

集群部署

?

業務解耦

?

整體系統層面的網元模塊架構情況如下圖所示,整個預覽服務中,所有內部邏輯均封裝在內部,統一由預覽編輯服務對外提供API接口,供業務服務進行調用與交互。后續如果需要對預覽服務的實現策略進行調整,也無需變更外部業務側的邏輯,實現與業務邏輯解耦的效果。

圖片

總結

好啦,關于基于開源方案構建統一的文件在線預覽與Office協同編輯平臺的架構考量與實現過程關鍵點,這里就給大家分享到這里咯。看到這里,不知道你是否也有過此方面的經歷呢?針對文中的實現策略,是否還有什么更好的見解呢?歡迎多多留言切磋交流。

需要補充一下:

  • 因為對OnlyOffice的源碼實現或者框架具體實現了解也不是很深入,所以本文闡述的相關方案,主要是基于其社區版本,在使用層面進行額外的封裝,來達到自身訴求。
  • 如有足夠的精力或者能力,也可以考慮直接基于其源碼進行二次開發定制來實現目的 —— 這塊受限于業務交付的急迫性,沒有嘗試。
責任編輯:武曉燕 來源: 架構悟道
相關推薦

2021-06-29 07:14:19

NEXTCLOUDONLYOFFICE協同編輯平臺

2011-10-20 14:02:11

虛擬化基礎架構服務器

2021-12-14 15:35:33

Flink數據分析數據集成平臺

2025-01-10 14:35:23

2018-04-23 12:41:21

云計算政務云平臺架構

2025-01-26 13:27:23

2010-05-21 12:02:07

統一通信解決方案

2010-08-11 18:13:26

SOAIT架構開發管理

2025-08-15 07:10:00

2010-05-13 23:31:54

統一通信平臺

2021-06-01 06:59:58

運維Jira設計

2020-03-06 19:28:23

UOS瀏覽器WPS Office

2025-04-30 08:10:00

Vue文件預覽預覽編輯

2020-09-18 06:00:51

開源Markdown編輯器

2011-06-28 16:40:17

Qt Widget 圖片

2013-12-10 23:06:58

開源云平臺云計算

2012-10-09 09:25:57

2019-12-26 15:37:33

操作系統WindowsUOS

2024-06-06 08:43:44

2012-10-11 10:51:39

開源IaaS云
點贊
收藏

51CTO技術棧公眾號

欧美成人69| 亚洲精品555| av不卡一区二区三区| 热久久这里只有| 手机在线中文字幕| 高清欧美性猛交xxxx黑人猛| 在线观看一区不卡| 成年人视频网站免费| 蝌蚪视频在线播放| 国产揄拍国内精品对白| 2019日本中文字幕| 五月天色婷婷丁香| 免费短视频成人日韩| 欧美一区二区三区免费观看视频 | 亚州精品国产精品乱码不99按摩| 久久狠狠一本精品综合网| 不卡中文字幕av| 久操视频免费看| 99精品中文字幕在线不卡| 在线一区二区视频| 人人妻人人澡人人爽欧美一区双 | 国产午夜精品福利| 国产精品一区二区免费| 91超薄丝袜肉丝一区二区| 国产视频久久| 欧美激情视频播放| 搜索黄色一级片| 欧美伦理影院| 国产视频一区在线| 亚洲美女精品视频| 粉嫩av国产一区二区三区| 91福利资源站| 国产xxxxx在线观看| 女人天堂av在线播放| 成人欧美一区二区三区小说 | 好吊成人免视频| 欧美中文字幕在线观看视频 | 一区视频在线播放| 欧美综合激情| 男女视频在线观看免费| 99久久99久久精品国产片果冻| 91观看网站| av男人天堂av| 国产精品一二二区| 91亚洲精品久久久| 国产精品日韩无码| 久草中文综合在线| 国产日韩欧美视频| 91精品人妻一区二区三区果冻| 视频一区二区三区入口| 97精品国产aⅴ7777| 国产在线精品观看| 在线日韩中文| 国模叶桐国产精品一区| 日本免费一二三区| 国产欧美日韩综合一区在线播放 | 欧美视频在线第一页| 黄色视屏免费在线观看| 亚洲私人黄色宅男| 成人黄色片免费| 欧美韩日亚洲| 疯狂做受xxxx欧美肥白少妇 | 波多野结衣亚洲一二三| 日韩欧美成人网| 女人另类性混交zo| av一区在线播放| 69av一区二区三区| 欧美一区二区三区影院| 国产精品xxxav免费视频| 日韩av网站电影| www.av欧美| 色综合咪咪久久网| 欧美另类老女人| 日本熟女一区二区| 天堂成人国产精品一区| 国产一区二区在线播放| 精品久久久久久亚洲综合网站| 国产91在线|亚洲| 精品视频第一区| 高清美女视频一区| 亚洲免费观看高清完整| 男人添女荫道口图片| 春暖花开亚洲一区二区三区| 欧美日韩一区二区三区四区| 中文字幕欧美视频| 卡一精品卡二卡三网站乱码| 一区二区三欧美| 欧产日产国产v| 免费亚洲网站| 成人网中文字幕| 天天综合在线视频| 国产精品麻豆99久久久久久| 成人小视频在线观看免费| 国产精品电影| 欧美精品在线视频| 国产一级二级视频| 日韩1区在线| 韩国三级日本三级少妇99| 波多野结衣mp4| 国产成人精品免费| 色一情一乱一伦一区二区三欧美| 18视频在线观看网站| 色婷婷综合激情| 亚洲熟女一区二区三区| 欧美一区二区性| 午夜精品久久久久久久男人的天堂| 无码久久精品国产亚洲av影片| 国产高清精品网站| 亚洲欧洲一区二区在线观看| 国产美女高潮在线观看| 91精品麻豆日日躁夜夜躁| 插吧插吧综合网| 欧美日韩网址| 国产区亚洲区欧美区| 日本一区视频| 亚洲va欧美va人人爽| 午夜精品中文字幕| 中文精品一区二区| 午夜美女久久久久爽久久| 国产精品一区二区免费视频| 久久久久久夜精品精品免费| 久久99久久久久久| 成人51免费| 中文字幕日韩在线观看| 久久国产黄色片| 菠萝蜜视频在线观看一区| 国产高清免费在线| 91伊人久久| 日韩理论片久久| 国产精品免费av一区二区| 国产精品99久久不卡二区| 亚洲欧洲精品一区二区| av有声小说一区二区三区| 日韩av中文字幕在线播放| 久久艹精品视频| 国产一区二区在线免费观看| 影音先锋亚洲视频| 狠狠久久伊人中文字幕| 在线观看亚洲区| 日韩乱码一区二区三区| 国产欧美综合色| 中文字幕在线观看第三页| 色综合综合网| 国产精品99导航| 国产九九在线| 在线视频国内一区二区| 亚洲区自拍偷拍| 久久字幕精品一区| 日韩欧美亚洲区| 日韩高清成人| 色悠悠久久久久| 国产又粗又长视频| 亚洲美女视频一区| 好吊操视频这里只有精品| 黄色精品网站| 久久精品国产精品青草色艺| 在线能看的av网址| 在线不卡国产精品| 亚洲一级片免费看| 自拍偷拍国产精品| 亚洲欧洲日韩综合| 中文精品在线| 日韩高清专区| 亚洲a成人v| 欧美黑人性猛交| 四虎精品一区二区三区| 日韩欧美成人网| 貂蝉被到爽流白浆在线观看| 国产自产视频一区二区三区| 男人c女人视频| 噜噜噜天天躁狠狠躁夜夜精品| 欧美又大又粗又长| 国产高清自拍视频在线观看| 欧美日韩精品综合在线| 久久久久亚洲av无码专区体验| 成人综合在线网站| 日本精品www| 婷婷色综合网| 精品国产综合久久| 丁香婷婷久久| 久久久久久91| 韩国福利在线| 日韩午夜激情免费电影| 奇米影视第四色777| 国产欧美日韩亚州综合| 欧美性猛交乱大交| 亚洲一级在线| 黄色网址在线免费看| 欧美高清视频看片在线观看| 国产成人精品久久二区二区91| 久草免费在线| 精品亚洲国产成av人片传媒| 一级成人免费视频| 午夜日韩在线观看| 三级影片在线观看| 337p粉嫩大胆噜噜噜噜噜91av| www.日本一区| 国产亚洲网站| 午夜探花在线观看| 奇米狠狠一区二区三区| 懂色av一区二区三区在线播放| 电影天堂国产精品| 久久久久久久久久久91| 亚洲xxxxxx| 亚洲欧美日韩天堂| 国产91久久久| 91精品国产品国语在线不卡| 草莓视频18免费观看| 亚洲综合一区二区精品导航| 欧美精品日韩在线| jiyouzz国产精品久久| 天堂在线中文在线| 日韩影院在线观看| 成人免费观看cn| 欧美精品日韩| 亚洲v国产v在线观看| 欧美日韩导航| 国产亚洲欧美一区二区三区| 电影中文字幕一区二区| 国产精品日韩专区| 欧美成人精品三级网站| 国语对白做受69| 里番在线播放| 欧美成在线视频| 大片免费在线看视频| 中文字幕不卡av| 国产在线自天天| 精品视频—区二区三区免费| 黄色aaa大片| 精品欧美乱码久久久久久1区2区| 国产精品主播一区二区| 欧美色图片你懂的| 久久久精品毛片| 色综合久久综合网欧美综合网 | 亚洲国产一区二区三区a毛片| 小说区视频区图片区| 日韩精品水蜜桃| 一区二区日本| 久久精品欧美一区| 精品一区二区成人免费视频| 999国产精品| 91免费视频黄| 亚洲国产不卡| av在线免费观看国产| 欧美精选一区| 搞av.com| 国产亚洲在线| 日韩av资源在线| 日日摸夜夜添夜夜添国产精品| 久久久999视频| 久久国产福利| 人人爽人人av| 另类欧美日韩国产在线| 天天干天天玩天天操| 国产在线精品一区在线观看麻豆| 拔插拔插华人永久免费| 国产美女在线精品| 国产成人av片| 久久一区二区三区四区| 夜夜春很很躁夜夜躁| 国产精品美女久久久久aⅴ| 免费成人美女女在线观看| 亚洲婷婷在线视频| 18精品爽视频在线观看| 亚洲国产日韩a在线播放性色| 日韩av在线电影| 在线视频欧美区| 国产精品探花视频| 精品欧美乱码久久久久久1区2区| 日韩精品系列| 日日摸夜夜添一区| 男插女视频久久久| 青青草一区二区| 亚洲tv在线| 激情小说网站亚洲综合网| 国产欧美日韩精品高清二区综合区| 丝袜足脚交91精品| 综合久久亚洲| 波多野结衣50连登视频| 麻豆专区一区二区三区四区五区| 亚洲美女高潮久久久| 久久精品在线免费观看| 极品颜值美女露脸啪啪| 欧美视频在线观看免费| 国产精品视频在线观看免费| 精品国产髙清在线看国产毛片| 日韩电影网址| 久久亚洲精品小早川怜子66| 国产不卡123| 国产欧美日韩最新| 九九热hot精品视频在线播放| 视频二区一区| 伊人成人在线| 亚洲综合婷婷久久| 2024国产精品| 国产一二三四在线| 欧美色视频在线观看| 欧美一区二区在线观看视频| 在线观看亚洲视频| 毛片电影在线| 亚洲自拍偷拍一区| 第四色成人网| 欧美性大战久久久久xxx| 激情欧美一区二区| 精品人妻一区二区三区视频| 亚洲精品日韩综合观看成人91| 中文字幕69页| 精品国产乱码久久久久久久久| 秋霞影院午夜丰满少妇在线视频| 5566成人精品视频免费| 免费精品一区| 中日韩在线视频| 首页欧美精品中文字幕| 少妇性l交大片7724com| 国产精品视频免费| 波多野结衣啪啪| 亚洲成在人线av| 污污网站在线观看| 国产日韩综合一区二区性色av| 色综合中文网| 夫妻免费无码v看片| 国产成人av福利| 91嫩草|国产丨精品入口| 欧美这里有精品| 狠狠v欧美ⅴ日韩v亚洲v大胸 | 国产欧美自拍| 日本一区高清不卡| 久久aⅴ国产紧身牛仔裤| 国产精品无码专区| 亚洲小说欧美激情另类| www.麻豆av| 欧美乱妇高清无乱码| 成人豆花视频| 日本丰满大乳奶| 国产一级精品在线| 欧美性x x x| 欧美另类变人与禽xxxxx| √新版天堂资源在线资源| 国产精品欧美一区二区三区奶水| 亚洲电影男人天堂| 欧美日韩一区二区在线免费观看| 99re这里只有精品6| 天天综合网久久综合网| 日韩精品视频在线观看网址| 香蕉伊大人中文在线观看| 久久国产一区二区| 香蕉久久久久久久av网站| 成人网站免费观看| 色猫猫国产区一区二在线视频| 欧美老女人性开放| 国产高清在线不卡| 欧美激情国产在线| 91丝袜超薄交口足| 亚洲黄色av一区| 在线观看国产精品网站| 久久久久久国产精品无码| 舔着乳尖日韩一区| 香蕉视频黄色片| 欧洲日韩成人av| 欧美日韩中文字幕一区二区三区| 成年人小视频网站| 国产精品全国免费观看高清| 一级全黄裸体免费视频| 久久亚洲精品成人| 国内精品偷拍| 好男人www社区| 中文字幕日韩欧美一区二区三区| 99草在线视频| 97av在线视频| 日韩国产欧美| 被黑人猛躁10次高潮视频| 亚洲午夜免费视频| 日韩私人影院| 亚洲iv一区二区三区| 激情欧美日韩| jizz中文字幕| 日韩一二三区不卡| 亚洲校园激情春色| 中日韩在线视频| 91亚洲永久精品| 亚洲影视一区二区| 国产最新精品视频| 日本久久综合| 91九色蝌蚪porny| 在线视频中文字幕一区二区| 成人免费观看视频大全| 精品国产区在线| 免费成人在线观看视频| 久久网一区二区| 中文字幕不卡在线视频极品| caoporn成人| 在线免费观看视频黄| 性做久久久久久免费观看欧美| 嫩草研究院在线| 官网99热精品| 水野朝阳av一区二区三区| 久草网在线观看| 中文字幕精品av| 神马日本精品| 亚洲天堂小视频|