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

字節(jié)的前端監(jiān)控 SDK 是怎樣設(shè)計的

原創(chuàng) 精選
開發(fā) 前端
一個 SDK 不可能既支持多環(huán)境,又滿足體積小、功能全面的要求,這本身互相矛盾。只要兼容其他環(huán)境,打包進來的代碼會導致體積變大,因此設(shè)計之初的目標就是同一套設(shè)計組裝成不同的 SDK 。
作者|彭莉,火山引擎 APM 研發(fā)工程師,2020 年加入字節(jié),負責前端監(jiān)控 SDK 的開發(fā)維護、平臺數(shù)據(jù)消費的探索和落地

摘要

公司內(nèi)部監(jiān)控環(huán)境多樣( Web 應用、小程序、Electron 應用、跨端應用等等), SDK 如何保證底層邏輯的復用、上層邏輯的解耦。

在業(yè)務(wù)龐雜、監(jiān)控需求多樣的背景下, SDK 如何做到足夠靈活,如何實現(xiàn)插件化,并且支持業(yè)務(wù)自行擴展的。

大型 C 端業(yè)務(wù)非常注重業(yè)務(wù)自身的正確性和性能,監(jiān)控 SDK 如何保證原有業(yè)務(wù)的正確性;如何保持 SDK 自身的性能,減少對業(yè)務(wù)的影響。

接入業(yè)務(wù)眾多,上報量級近千萬 QPS ,在日常需求迭代中, SDK 是如何確保自身穩(wěn)定性的。

邏輯解耦

前端的領(lǐng)域廣闊,所以作為前端監(jiān)控,也不只局限在瀏覽器環(huán)境,需要同時解決小程序、 Electron 、 Nodejs 等等其他環(huán)境的監(jiān)控需求。不同環(huán)境之間差異巨大,從提供的配置項,到監(jiān)控的功能、上報的方式都會不一樣。

一個 SDK 不可能既支持多環(huán)境,又滿足體積小、功能全面的要求,這本身互相矛盾。只要兼容其他環(huán)境,打包進來的代碼會導致體積變大,因此設(shè)計之初的目標就是同一套設(shè)計組裝成不同的 SDK 。此設(shè)計的第一要務(wù)是要邏輯解耦。雖然多環(huán)境下差異很大,但要做的事情是一樣的,比如配置、采集數(shù)據(jù)、組裝數(shù)據(jù)、上報數(shù)據(jù)。

我們設(shè)計了五個角色,每個角色只需要實現(xiàn)約定的接口即可。這樣就保證了不同的環(huán)境下,各個角色合作的方式是相同的,在實現(xiàn)了一套內(nèi)核模版后,不同的監(jiān)控 SDK 就可以快速搭建出來。

圖片

Monitor

收集器,主動或被動地采集特定環(huán)境下的原始數(shù)據(jù),組裝為平臺無關(guān)事件。

Monitor 有若干個,每一個 Monitor 對應一個功能,比如關(guān)于 JS 錯誤的監(jiān)控是一個 Monitor ,關(guān)于請求的監(jiān)控又是另一個 Monitor 。

Builder

組裝器,負責將收集器上報的平臺無關(guān)事件轉(zhuǎn)換為特定平臺的上報格式。

主要負責包裝特定環(huán)境下的上下文信息。在瀏覽器環(huán)境下,上下文信息包括頁面地址、網(wǎng)絡(luò)狀態(tài)、當前時間等等,再結(jié)合收到的 Monitor 的數(shù)據(jù),完成上報格式的組裝。

Sender

發(fā)送器,負責發(fā)送邏輯,比如批量,重試等功能。

監(jiān)控 SDK 的 Sender 都是 BatchSender ,它會負責維護一個緩存隊列,按照一定的隊列長度或者緩存時間間隔來聚合上報數(shù)據(jù),會開放一些方法自定義緩存隊列長度和緩存間隔時間,也支持立即上報和清空隊列等操作。

特定環(huán)境下的 Sender 也需要負責處理一些邊緣 case ,比如瀏覽器環(huán)境下的 Sender 在頁面關(guān)閉時,需要使用 sendBeacon 立即上報所有隊列數(shù)據(jù),以免漏報。

在實際實踐中,我們對 Sender 進行了進一步抽象, Sender 不會內(nèi)置發(fā)送的能力,關(guān)于如何發(fā)送數(shù)據(jù),不同環(huán)境依賴的 API 不同,因此會由 Client 在創(chuàng)建 Sender 時將具體的發(fā)送能力傳入 Sender 中。

ConfigManager

配置管理器,負責配置邏輯,比如合并初始配置和用戶配置、拉取遠端配置等功能。

一般需要傳入默認配置,支持用戶手動配置,當配置完成時, ConfigManager 會變更 ready 狀態(tài),所以它也支持被訂閱,以便當 ready 時或者配置變更時通知到訂閱方。

export interface ConfigManager<Config> {
setConfig: (c: Partial<Config>) => Config
getConfig: () => Config
onChange: (fn: () => void) => void
onReady: (fn: () => void) => void
}

Client

實例主體,負責串聯(lián)配置管理器、收集器、組裝器和發(fā)送器,串通整個流程,同時提供生命周期監(jiān)聽以供擴展 SDK 功能。

下面是一段方便理解串聯(lián)過程的偽代碼,僅作參考。

export const createClient = ({ configManager, builder, sender }) => {
let inited = false
let started = false
let preStartQueue = []
const client = {
init: (config) => {
configManager.setConfig(config)
configManager.onReady(() => {
preStartQueue.forEach((e) => { this.report(e) })
started = true
})
inited = true
}
report: (data) => {
if (!started) {
preStartQueue.push(data)
} else {
const builderData = builder.build(data)
builderData && sender.send(builderData)
}
}
}
return client
}

const client = createClient({ configManager, builder, sender })
monitors.forEach((e) => { e(client) })

角色之間足夠抽象,互相獨立、各司其職。比如 Monitor 只負責收集,并不知道最終上報的具體格式;Builder 只做組裝,組裝完成后交給實例主體 Client ,由 Client 交給 Sender ;Sender 不知道收到的具體事件格式,只負責完成發(fā)送。

開放豐富的生命周期

監(jiān)控做的事情就像一條單純的流水線:初始化 => 采集數(shù)據(jù) => 組裝數(shù)據(jù) => 上報數(shù)據(jù),我們希望能在不同階段執(zhí)行各種操作,但又不希望直接將邏輯耦合在代碼,這樣不利于后期的迭代維護,也會導致體積一步步增加,走向重構(gòu)的必然結(jié)果。

于是我們決定讓內(nèi)核模版提供規(guī)范的生命周期,所有的功能都借助生命周期的監(jiān)聽來實現(xiàn),這樣不僅解決了體積不斷膨脹的問題,也讓 SDK 易于擴展。

基于監(jiān)控 SDK 的各個階段,我們明確了六個主要的生命周期,命名也比較貼切,從上到下分別是:初始化 => 開啟上報 =>  Monitor 監(jiān)控到數(shù)據(jù),傳遞給 Client  => 包裝數(shù)據(jù) => 發(fā)送數(shù)據(jù) => 銷毀實例

圖片

基于這些生命周期,我們提供了十個生命周期鉤子,主要分為兩類:

  • 回調(diào)類:只執(zhí)行回調(diào),不影響流程繼續(xù)執(zhí)行,比如 init / start / beforeConfig / config 等等。
  • 處理類:執(zhí)行并返回修改后的有效值,如果返回無效值,將不再往下執(zhí)行,終止上報,比如 report / beforeBuild / build / beforeSend 等等。

如何實現(xiàn)插件化

良好的生命周期是插件化的基礎(chǔ), 基于這些生命周期我們就能實現(xiàn)各種各樣的插件。

舉個例子,我們需要為 Monitor 采集到的數(shù)據(jù)包裝事件發(fā)生時的上下文,可以通過這種方式:監(jiān)聽 report ,劫持到數(shù)據(jù),重新包裝,再傳遞給 Client 。

// 一個包裝上下文的插件
export const InjectEnvPlugin = (client: WebClient) => {
client('on', 'report', (ev: WebReportEvent) => {
return addEnvToSendEvent(ev)
})
}

// 應用此插件
InjectEnvPlugin(client)

再舉個例子,我們需要新監(jiān)控一類數(shù)據(jù),可以通過這種方式:監(jiān)聽實例主體 Client 當前的狀態(tài),在 Client ready 的時候(用戶配置完成時),開始收集數(shù)據(jù)。在收集到數(shù)據(jù)時,將數(shù)據(jù)傳回 Client 即可。

// 一個監(jiān)聽數(shù)據(jù)的插件
export const MonitorXXPlugin = (client: WebClient) => {
client('on', 'init', () => {
const data = listenXX();
client('report', data)
})
}

在 SDK 內(nèi),  基本都是插件,常規(guī)的數(shù)據(jù)采集是一個個插件,其他的比如采樣、包裝上下文、異步加載等功能,也都是各自獨立的插件。

業(yè)務(wù)如何自行擴展

簡單的擴展,一般可以靠生命周期鉤子函數(shù)來完成,常見的需求就是在數(shù)據(jù)發(fā)送前做一些手動的過濾、安全脫敏等等。

舉個例子,我們想要在頁面地址包含  '/test'  時不上報任何數(shù)據(jù),可以通過下面的代碼來實現(xiàn)。

import client from '@slardar/web'

client('on', 'beforeSend', (ev) => {
if (ev.common.url.includes('/test')) {
return false
}
return ev
})

但如果有高階的需求,比如想寫一個插件能提供給團隊的其他人用,上面的方式就不再適用。如果插件太復雜,其他人需要復制一大段代碼,用起來不太優(yōu)雅。

基于這個需求, SDK 設(shè)計了一個自定義插件的傳遞協(xié)議,可以在初始化時將自定義插件傳遞給 Client , Client 將會在初始化時執(zhí)行傳入的 setup 方法,在實例銷毀時執(zhí)行傳入的 tearDown 方法來銷毀副作用。

export interface Integration<T extends AnyClient> {
name: string
setup: (client: T) => void
tearDown?: () => void
}

可以注意到,接口約定的實例類型是 AnyClient ,這個協(xié)議并不在意是什么類型的 Client ,實際的 Client 類型由 SDK 來定義,比如 Web SDK 拿到的是 WebClient , Electron SDK 拿到的是 ElectronClient 。

業(yè)務(wù)可以自行發(fā)布一個插件包,插件的實現(xiàn)可以是直接返回一個對象,或一個方法。允許用戶傳入一些配置,返回一個對象,只要這個對象滿足上面的 Integration 類型即可。

import client from '@slardar/web'
import CustomPlugin from 'xxx'

client('init', {
...
integrations: [CustomPlugin({ config: {} })]
...
})

如何按需加載

為了方便使用,默認情況下,我們會集成所有的監(jiān)控功能。但這并不是所有業(yè)務(wù)都需要的,有的業(yè)務(wù)只關(guān)心 JS 錯誤,其他的功能都不想要,這應該怎么解決呢?

為此 SDK 導出了一個最小的實例,這個實例只引入通用的插件,但是不引入數(shù)據(jù)采集類的插件,而具體要采集哪些功能由用戶在 integrations 上按需配置。

import { createMinimalBrowserClient } from '@slardar/web'
import { jsErrorPlugin } from '@slardar/integrations/dist/jsError'

// 創(chuàng)建一個最小的實例
const client = createMinimalBrowserClient()

client('init',{
...
// 按需引入需要采集的監(jiān)控功能
integrations: [jsErrorPlugin()],
...
})

如何保證原有業(yè)務(wù)的正確性

接入監(jiān)控 SDK 的目的是為了發(fā)現(xiàn)問題,如果監(jiān)控 SDK 的問題導致業(yè)務(wù)受到了影響,不免本末倒置。加上絕大部分前端業(yè)務(wù)都接入了這個 SDK ,如果出現(xiàn)問題,影響范圍和損失都很巨大。因此保證原有業(yè)務(wù)的正確性遠遠比監(jiān)控本身更重要。

SDK 會首先將對業(yè)務(wù)有影響的 敏感代碼 使用 try catch 包裹起來,確保即使發(fā)生了錯誤也不影響業(yè)務(wù),比如 hook 類的操作, hook XHR 和 Fetch 等等。這個操作要膽大心細,同時 try catch 的范圍能小則小。

其次是監(jiān)控 SDK 自身的錯誤。我們也會將 SDK 自身的 關(guān)鍵代碼 包裹 try catch ,確保一個錯誤不會影響整個監(jiān)控流程。單純的 try catch 將錯誤吞掉解決不了問題,這些錯誤可能導致某些監(jiān)控數(shù)據(jù)沒有收集完全,影響監(jiān)控的完整性。因此 SDK 實現(xiàn)了一個 ObserveSelfErrorPlugin ,用于收集 SDK 自身的錯誤并上報。

同時,我們會針對上報所有的上報數(shù)據(jù)進行清洗,帶有 SDK 自身堆棧的數(shù)據(jù)會統(tǒng)一消費一份到另一處,便于從宏觀上觀察 SDK 的出錯情況,及時發(fā)現(xiàn)問題。

這樣既確保了業(yè)務(wù)的正確性,也確保了監(jiān)控 SDK 的正確性。

如何減少對業(yè)務(wù)的影響

絕大部分的業(yè)務(wù)都是使用監(jiān)控 SDK 來自動上報性能數(shù)據(jù)以此來監(jiān)控業(yè)務(wù)的性能,這也隱含著對監(jiān)控 SDK 最基本的要求:不能帶來性能問題。

最重要的就是不能影響業(yè)務(wù)的首屏渲染,為此我們把 Monitor 類的插件分為兩類,一是需要立即監(jiān)聽的,先加載;二是不需要的立即監(jiān)聽的,延后加載。比如路由變化的監(jiān)聽、請求的監(jiān)聽,如果延后會導致數(shù)據(jù)遺漏,就屬于第一類;像靜態(tài)資源性能監(jiān)控這樣晚一點執(zhí)行也并不會遺漏的,就屬于第二類。

除此之外, SDK 本身的性能評估也非常重要。單個插件的執(zhí)行耗時多少,插件帶來的副作用的耗時又是多少,這些都是基本的評估點。基于Maiev,我們編寫了完善的 Benchmark 性能測試,在代碼 MR 的時候會觸發(fā)相應的測試任務(wù),另外也有固定周期來定時執(zhí)行測試任務(wù),任務(wù)異常時不能發(fā)版, SDK 的性能由此保證。

當然盡可能縮小 SDK 的體積也能直接減少對業(yè)務(wù)的影響,這塊內(nèi)容涉及較廣,留作后續(xù)分說。

如何盡早開始監(jiān)聽

監(jiān)聽不遺漏的前提是事件發(fā)生在開始監(jiān)控之后。但是一些超高優(yōu)的事件,比如 JS 錯誤,發(fā)生時機可能超級靠前,等不到監(jiān)控腳本加載完成。所以監(jiān)控 SDK 針對 script 的接入方式會提供一個簡短的腳本,讓用戶內(nèi)聯(lián)在頁面中。它的作用是提前開始監(jiān)聽,保證高優(yōu)的事件不被遺漏。

它還有另一個巧用:緩存調(diào)用命令。

監(jiān)控腳本是異步加載的,因此會先掛載一個空函數(shù),確保調(diào)用不報錯;同時把對實例主體 Client 的調(diào)用命令緩存下來,記錄下調(diào)用的時間和頁面地址,確保能正確組裝數(shù)據(jù);等到監(jiān)控腳本加載完成時再順序執(zhí)行,以此確保調(diào)用不遺漏。示例如下:

window[globalName] = function (m) {
const onceArguments = [].slice.call(arguments)
onceArguments.push(Date.now(), location.href)
;window[globalName].precolletArguments.push(onceArguments)
}

window[globalName].precolletArguments = []

當然如果使用npm包接入的話,依然會有預收集的邏輯,因為npm包不會掛全局變量,所以邏輯稍微有一些不同,同時受限于引入的順序,執(zhí)行的時機會稍晚一些。

如何保證 SDK 的質(zhì)量

Slardar Web SDK 為絕大部分公司前端業(yè)務(wù)提供監(jiān)控能力,上報數(shù)據(jù)的流量近千萬 QPS ,需要有嚴格的質(zhì)量把控。

SDK 有完善的單元測試,每一個插件,每一個方法,都會單獨編寫測試用例。以及完善的自動化測試,對于整個 SDK 的所有默認行為以及各個配置項對應的行為有完整的用例覆蓋。每次變動都需要補充對應的相關(guān)用例,且每次 MR 都要測試通過才能合入預發(fā)布分支,這樣才能做到心中不慌。此外,會有預發(fā)布驗證環(huán)節(jié),驗證改動的預期效果。如果改動的地方比較敏感,會找站點合作方灰度一段時間后發(fā)布正式版本。發(fā)布后的一段時間內(nèi)我們也會密切的關(guān)注整體的流量情況,確認是否存在異常上漲和下降,是否有新增的 SDK 相關(guān)異常。

由此, SDK 的質(zhì)量得以保證。

責任編輯:未麗燕 來源: 字節(jié)跳動技術(shù)團隊
相關(guān)推薦

2020-04-21 12:09:47

JVM消化字節(jié)碼

2024-08-30 08:59:15

2017-09-12 10:50:55

前端SDK開發(fā)

2022-01-11 14:25:46

前端監(jiān)控SDK

2009-10-19 15:01:22

機房監(jiān)控摩卡

2010-03-24 15:40:39

網(wǎng)管運維管理摩卡軟件

2020-10-27 07:34:41

基站手機蜂窩網(wǎng)絡(luò)

2023-03-03 11:12:34

Kubernetes控制器后端

2019-03-18 10:02:16

緩存更新數(shù)據(jù)

2020-01-02 15:01:27

NginxApache服務(wù)器

2022-10-28 13:41:51

字節(jié)SDK監(jiān)控

2023-11-07 07:21:04

2015-06-30 11:52:30

2014-06-20 10:34:42

開源

2015-09-06 09:09:13

2015-11-10 09:09:23

代碼程序員成長

2024-03-28 08:13:51

GPTsOpenAI人工智能

2013-08-19 16:17:48

CIO

2011-11-25 09:48:04

天線無線

2009-09-02 20:18:17

域名劫持域名安全
點贊
收藏

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

日韩在线电影一区| www.久久久久| 成人性视频欧美一区二区三区| 国产小视频免费在线观看| 美女www一区二区| 欧美激情图片区| 黄色aaa视频| 国产免费av国片精品草莓男男| 亚洲一区二区影院| 日本亚洲导航| 亚洲精品国产一区二| 日韩**一区毛片| 欧美激情国产日韩精品一区18| 国产精品815.cc红桃| 91精品国产一区二区在线观看| 亚洲va欧美va人人爽| 亚洲欧洲日韩精品| 日本韩国一区| 国产精品影音先锋| 国产精品福利网站| 日韩久久久久久久久| 久久综合av| 国产视频亚洲精品| 娇妻高潮浓精白浆xxⅹ| 成人看片毛片免费播放器| 亚洲小说欧美激情另类| 一级日韩一区在线观看| 青青国产在线| 国产成人av电影在线观看| 国产精品久久久久99| 国产黄色片免费看| 狠狠色综合网| 欧美成人四级hd版| 大吊一区二区三区| 亚洲免费专区| 亚洲精品国产精品久久清纯直播| 91人妻一区二区三区| 国产极品一区| 欧美午夜不卡在线观看免费| 国产男女在线观看| 国产精品蜜芽在线观看| 夜夜嗨av一区二区三区四季av | 色综合视频一区中文字幕| www.黄色在线| 国产精品三级| 亚洲人成电影网站色| 国产中文字幕一区二区| 精品国产一区二区三区成人影院| 日韩欧美一区在线| 免费人成视频在线播放| 欧洲大片精品免费永久看nba| 欧美人牲a欧美精品| 视色视频在线观看| 日韩av黄色| 欧美丰满高潮xxxx喷水动漫| 亚洲精品手机在线观看| 4438五月综合| 欧美成人在线直播| 亚洲中文字幕无码一区| 国产精品巨作av| 亚洲精品大尺度| 亚洲成人日韩在线| 伊人久久大香线蕉综合网蜜芽| 日韩激情在线视频| 国产手机在线观看| 四虎成人av| 欧美成人h版在线观看| 久操免费在线视频| 一区二区三区高清视频在线观看| 26uuu国产精品视频| 成人免费毛片男人用品| 日本在线不卡视频| 成人性生交xxxxx网站| www.桃色av嫩草.com| 不卡欧美aaaaa| 日本一区二区高清视频| 麻豆传媒视频在线| 亚洲一区在线播放| 男人亚洲天堂网| 成人国产在线| 欧美精品一区二区三区高清aⅴ| free性中国hd国语露脸| 国产日产一区| 久久国产精品影片| 欧美福利视频一区二区| 日韩av一区二区在线影视| 91久久精品国产91性色| 欧美 日韩 国产 成人 在线 91| 久久久久久99久久久精品网站| 亚洲一区精品视频| aaa在线播放视频| 欧美午夜电影一区| 国产精品果冻传媒| 精品国产欧美日韩| 欧美精品18videosex性欧美| 在线永久看片免费的视频| 国产在线日韩欧美| 欧美久久在线| 蜜臀av国内免费精品久久久夜夜| 色婷婷综合中文久久一本| 午夜激情影院在线观看| 天堂成人娱乐在线视频免费播放网站 | 性xxxx视频| 亚洲欧美自拍偷拍| 免费成人午夜视频| 国产精久久久| 亚洲日本欧美日韩高观看| 日本中文字幕免费在线观看| 免费永久网站黄欧美| 亚洲free性xxxx护士hd| 神马电影在线观看| 一区二区三区色| 婷婷免费在线观看| 婷婷综合一区| 欧美国产精品va在线观看| 中文字幕 日韩有码| 99久免费精品视频在线观看| 三年中国中文在线观看免费播放| 婷婷激情一区| 亚洲精品电影在线| 久久免费黄色网址| 青青草91视频| 成人精品水蜜桃| av在线网址观看| 欧美日韩情趣电影| 日本理论中文字幕| 销魂美女一区二区三区视频在线| 操人视频欧美| 污视频网站在线免费| 欧美精品在线视频| 亚洲毛片亚洲毛片亚洲毛片| 久久国产成人| 免费试看一区| 在线天堂资源www在线污| 精品国产91亚洲一区二区三区婷婷| 亚洲色图100p| 九九国产精品视频| 伊人色综合影院| 精品美女一区| 中文字幕免费精品一区| 亚洲午夜无码久久久久| 久久精品无码一区二区三区| 国产91xxx| 国产主播性色av福利精品一区| 久久夜色精品国产| 国产日本精品视频| 悠悠色在线精品| 成年人性生活视频| 国产一区二区三区四区三区四 | 色88888久久久久久影院| 国内精品久久久久| 五月婷婷六月激情| 色婷婷狠狠综合| 亚洲av成人无码久久精品| 欧美综合在线视频| 日本黄网站色大片免费观看| 成人精品一区二区三区电影| 色777狠狠综合秋免鲁丝| 中文字幕一级片| 亚洲欧洲成人精品av97| 欧美丝袜在线观看| 综合av在线| 高清视频在线观看一区| а√在线天堂官网| 亚洲久久久久久久久久| 欧美性猛交xxxx乱大交hd| 丰满少妇xoxoxo视频| 69久成人做爰电影| 日韩精品一二三四区| 亚洲欧美在线观看视频| 99久久er热在这里只有精品66| 日本一道本久久| 精品国产不卡| 91精品免费看| 成人在线高清免费| 日韩精品免费在线观看| 中文字幕在线观看视频免费| 中文字幕av一区二区三区高| 亚洲视频在线不卡| 国产日韩欧美一区二区三区在线观看| 欧美另类视频在线| 国产精久久一区二区| 久久久久国产视频| h视频在线播放| 日韩欧美久久久| 日本韩国欧美中文字幕| 中文字幕一区在线观看| 亚洲熟女一区二区| 奇米精品一区二区三区在线观看| 国产三级中文字幕| 牲欧美videos精品| 国产日韩精品在线播放| av福利导福航大全在线| 这里精品视频免费| 秋霞欧美在线观看| 欧美日韩精品欧美日韩精品| 日韩三级免费看| 自拍偷拍欧美激情| www.自拍偷拍| 国产一区二区三区免费观看| 日本毛片在线免费观看| 88国产精品视频一区二区三区| 久久亚洲综合网| 视频成人永久免费视频| 国产精品日日摸夜夜添夜夜av| 成人性生交大片免费看网站| 日韩在线中文视频| 久久久久久久久亚洲精品| 欧美不卡激情三级在线观看| 做爰无遮挡三级| 狠狠干狠狠久久| 久久久久成人精品无码| 国产精品久久精品日日| 日本高清www| 成人在线视频一区二区| 奇米影视四色在线| 小嫩嫩精品导航| 亚洲第一页在线视频| 精品在线99| av在线一区二区| 亚洲男人天堂色| 国产欧美三级| 97中文字幕在线| 欧美一区二区三区另类| 一区二区在线高清视频| 精品久久影视| 欧美二区在线| 欧美电影免费网站| 国产亚洲情侣一区二区无| 欧美第一在线视频| 91性高湖久久久久久久久_久久99| 国精产品一区二区三区有限公司| 久久久久亚洲精品成人网小说| 超碰在线无需免费| 精品国偷自产在线视频| 日本视频不卡| www.国产精品一二区| 日p在线观看| 日韩亚洲成人av在线| 国产尤物视频在线| 亚洲欧美制服综合另类| 欧美日韩激情视频一区二区三区| 日韩成人黄色av| 欧洲亚洲精品视频| 亚洲欧美制服丝袜| 高清中文字幕一区二区三区| 夜夜嗨av一区二区三区免费区 | 中文字幕不卡每日更新1区2区| 日韩精品欧美激情一区二区| 亚洲狠狠婷婷综合久久久| av伊人久久| 特级毛片在线免费观看| 欧美~级网站不卡| 免费视频爱爱太爽了| 亚洲国产一区二区三区a毛片| 免费看欧美一级片| 在线成人黄色| 亚洲国产精品久久久久爰色欲| 麻豆91精品| 天天爽夜夜爽一区二区三区| 国精产品一区一区三区mba视频| 人妻精油按摩bd高清中文字幕| 成人午夜激情片| 精品无码一区二区三区| 国产精品卡一卡二卡三| 成熟的女同志hd| 精品成人国产在线观看男人呻吟| 久久久久久少妇| 欧美亚洲动漫精品| av av片在线看| 亚洲第一精品久久忘忧草社区| 久久免费看视频| 精品国产一区二区三区四区在线观看 | 中文字幕在线播出| 欧美一卡二卡三卡| 色欲av永久无码精品无码蜜桃 | 日韩一区二区三区观看| 手机看片一区二区| 在线观看国产欧美| 在线看一级片| 1769国内精品视频在线播放| 欧美日韩尤物久久| 99超碰麻豆| 国产一区二区三区四区五区| 国产资源第一页| 久久九九电影| wwwww在线观看| 国产欧美精品区一区二区三区| 福利所第一导航| 色婷婷精品久久二区二区蜜臂av| 国产福利资源在线| 亚洲欧美成人网| 日韩精品分区| 国产精品青青在线观看爽香蕉| 国产色噜噜噜91在线精品| 日韩av电影免费在线| 伊人成人在线| www.夜夜爽| 久久五月婷婷丁香社区| 成人免费视频网站入口::| 在线视频你懂得一区| 亚洲毛片在线播放| 色婷婷成人综合| 中文字幕乱码中文乱码51精品| 成人网页在线免费观看| 视频国产一区| 国产精品va在线观看无码| 精品一区二区免费看| 国产三级视频网站| 亚洲综合精品自拍| 中文字幕欧美在线观看| 亚洲精品自拍视频| 第四色日韩影片| 97人人澡人人爽| 婷婷中文字幕一区| 在线免费观看av的网站| 91亚洲精品久久久蜜桃| 国产在线拍揄自揄拍| 在线成人午夜影院| www亚洲人| 国产99在线|中文| 奇米影视777在线欧美电影观看| 在线观看17c| 国产又粗又猛又爽又黄91精品| 五月天精品在线| 色伊人久久综合中文字幕| 香蕉视频911| 午夜精品www| 国产精品xxx在线观看| 欧美在线观看视频免费| 国产一区欧美日韩| 黄色录像免费观看| 欧美主播一区二区三区| 久久久久国产精品嫩草影院| 欧美亚州一区二区三区| 欧美深夜视频| 色欲av无码一区二区人妻| 99久久久久久| 国产www在线| 国产亚洲精品日韩| 成人软件在线观看| 日韩欧美亚洲区| 蜜桃av一区二区三区电影| 四虎国产成人精品免费一女五男| 在线观看精品一区| 91porn在线观看| 国产在线高清精品| 这里只有精品在线| 苍井空张开腿实干12次| 亚洲一区二区三区四区在线| 欧美性猛交 xxxx| 97国产精品视频人人做人人爱| 日韩免费高清视频网站| www插插插无码免费视频网站| 成人性生交大片| www.日本精品| 国产香蕉一区二区三区在线视频| 日本综合视频| 美女黄色片网站| 国产suv精品一区二区883| 日韩女同强女同hd| 亚洲摸下面视频| 亚洲欧美一级| 日产精品久久久久久久蜜臀| 99精品久久只有精品| 成人免费一级片| 久久综合免费视频| 大型av综合网站| 99视频在线免费| 亚洲男人的天堂在线aⅴ视频| 黄频网站在线观看| 国产999精品久久久| 天天影视欧美综合在线观看| 波多野吉衣在线视频| 精品欧美一区二区三区| 91涩漫在线观看| 国产富婆一区二区三区| 鲁大师影院一区二区三区| 91香蕉一区二区三区在线观看| 欧美一区二区三区的| 欧美久久天堂| 韩国黄色一级大片| 91丨porny丨最新| 一本久道久久综合无码中文| 久久久中文字幕| 成人在线免费视频观看| 肉色超薄丝袜脚交| 色综合天天做天天爱| 黄网站免费在线观看| 国产亚洲精品自在久久| 美女一区二区三区在线观看| 国产性70yerg老太| 一夜七次郎国产精品亚洲| 中文字幕一区二区三区四区久久| 超碰影院在线观看| 亚洲最大成人综合| 日本免费在线视频| 麻豆传媒一区二区| 国产成人一区在线| 中文字幕日日夜夜|