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

在 Node.js 中使用 Async Hooks 處理 HTTP 請求上下文實現(xiàn)鏈路追蹤

存儲 存儲軟件
Async Hooks 一個實際的使用場景是存儲請求上下文,在異步調(diào)用之間共享數(shù)據(jù)。上節(jié)對基礎(chǔ)使用做了介紹,還沒看的參見之前的分享 使用 Node.js 的 Async Hooks 模塊追蹤異步資源。

[[378622]]

作者簡介:五月君,Software Designer,公眾號「Nodejs技術(shù)棧」作者。

Async Hooks 一個實際的使用場景是存儲請求上下文,在異步調(diào)用之間共享數(shù)據(jù)。上節(jié)對基礎(chǔ)使用做了介紹,還沒看的參見之前的分享 使用 Node.js 的 Async Hooks 模塊追蹤異步資源。

本節(jié)將會介紹如何基于 Async hooks 提供的 API 從零開始實現(xiàn)一個 AsyncLocalStorage 類(異步本地存儲)及在 HTTP 請求中關(guān)聯(lián)日志的 traceId 實現(xiàn)鏈路追蹤,這也是 Async Hooks 的一個實際應(yīng)用場景了。

何為異步本地存儲?

我們所說的異步本地存儲類似于多線程編程語言中的線程本地存儲。拿之前筆者寫過的 Java 做個舉例,例如 Java 中的 ThreadLocal 類,可以為使用相同變量的不同線程創(chuàng)建一個各自的副本,避免共享資源產(chǎn)生的沖突,在一個線程請求之內(nèi)通過 get()/set() 方法獲取或設(shè)置這個變量在當(dāng)前線程中對應(yīng)的副本值,在多線程并發(fā)訪問時線程之間各自創(chuàng)建的副本互不影響。

在 Node.js 中我們的業(yè)務(wù)通常都工作在主線程(使用 work_threads 除外),是沒有 ThreadLocal 類的。并且以事件驅(qū)動的方式來處理所有的 HTTP 請求,每個請求過來之后又都是異步的,異步之間還很難去追蹤上下文信息,我們想做的是在這個異步事件開始,例如從接收 HTTP 請求到響應(yīng),能夠有一種機(jī)可以讓我們隨時隨地去獲取在這期間的一些共享數(shù)據(jù),也就是我們本節(jié)所提的異步本地存儲技術(shù)。

在接下來我會講解實現(xiàn) AsyncLocalStorage 的四種方式,從最開始的手動實現(xiàn)到官方 v14.x 支持的 AsyncLocalStorage 類,你也可以從中學(xué)習(xí)到其實現(xiàn)原理。

現(xiàn)有業(yè)務(wù)問題

假設(shè),現(xiàn)在有一個需求對現(xiàn)有日志系統(tǒng)做改造,所有記錄日志的地方增加 traceId 實現(xiàn)全鏈路日志追蹤。

一種情況是假設(shè)你使用一些類似 Egg.js 這樣的企業(yè)級框架,可以依賴于框架提供的中間件能力在請求上掛載 traceId,可以看看之前的一篇文章 基于 Egg.js 框架的日志鏈路追蹤實踐 也是可以實現(xiàn)的,不過當(dāng)時是基于 egg 的一個插件自己做了繼承實現(xiàn),現(xiàn)在已經(jīng)不需要這么麻煩,可以通過配置自定義日志格式來實現(xiàn) https://eggjs.org/zh-cn/core/logger.html#自定義日志格式。

另一種情況假設(shè)你是用的 Express、Koa 這些基礎(chǔ)框架,所有業(yè)務(wù)都是模塊加載函數(shù)式調(diào)用,如果每次把請求的 traceId 手動在 Controller -> Service -> Model 之間傳遞,這樣對業(yè)務(wù)代碼的侵入太大了,日志與業(yè)務(wù)的耦合度就太高了。

如下代碼,是我精簡后的一個例子,現(xiàn)在有一個需求,在不更改業(yè)務(wù)代碼的情況下每次日志打印都輸出當(dāng)前 HTTP 請求處理 Headers 中攜帶的 traceId 字段,如果是你會怎么做呢?

  1. // logger.js 
  2. const logger = { 
  3.   info: (...args) => { 
  4.     console.log(...args); 
  5.   } 
  6. module.exports = { logger } 
  7.  
  8. // app.js 
  9. const express = require('express'); 
  10. const app = express(); 
  11. const PORT = 3000; 
  12. const { logger } = require('./logger'); 
  13. global.logger = contextLogger; 
  14.  
  15. app.use((req, res, next) => contextLogger.run(req, next)); 
  16.  
  17. app.get('/logger', async (req, res, next) => { 
  18.   try { 
  19.    const users = await getUsersController(); 
  20.    res.json({ code: 'SUCCESS', message: '', data: users }); 
  21.   } catch (error) { 
  22.     res.json({ code: 'ERROR', message: error.message }) 
  23.   } 
  24. }); 
  25.  
  26. app.listen(PORT, () => console.log(`server is listening on ${PORT}`)); 
  27.  
  28. async function getUsersController() { 
  29.   logger.info('Get user list at controller layer.'); 
  30.   return getUsersService(); 
  31.  
  32. async function getUsersService() { 
  33.   logger.info('Get user list at service layer.'); 
  34.   setTimeout(function() { logger.info('setTimeout 2s at service layer.') }, 3000); 
  35.   return getUsersModel(); 
  36.  
  37. async function getUsersModel() { 
  38.   logger.info('Get user list at model layer.'); 
  39.   return []; 

方式一:動手實現(xiàn)異步本地存儲

解決方案是實現(xiàn)請求上下文本地存儲,在當(dāng)前作用域代碼中能夠獲取上下文信息,待處理完畢清除保存的上下文信息,這些需求可以通過 Async Hooks 提供的 API 實現(xiàn)。

創(chuàng)建 AsyncLocalStorage 類

  • 行 {1} 創(chuàng)建一個 Map 集合存儲上下文信息。
  • 行 {2} 里面的 init 回調(diào)是重點,當(dāng)一個異步事件被觸發(fā)前會先收到 init 回調(diào),其中 triggerAsyncId 是當(dāng)前異步資源的觸發(fā)者,我們則可以在這里獲取上個異步資源的信息存儲至當(dāng)前異步資源中。當(dāng) asyncId 對應(yīng)的異步資源被銷毀時會收到 destroy 回調(diào),所以最后要記得在 destroy 回調(diào)里清除當(dāng)前 asyncId 里存儲的信息。
  • 行 {3} 拿到當(dāng)前請求上下文的 asyncId 做為 Map 集合的 Key 存入傳入的上下文信息。
  • 行 {4} 拿到 asyncId 獲取當(dāng)前代碼的上下文信息。
  1. // AsyncLocalStorage.js 
  2. const asyncHooks = require('async_hooks'); 
  3. const { executionAsyncId } = asyncHooks; 
  4. class AsyncLocalStorage { 
  5.   constructor() { 
  6.     this.storeMap = new Map(); // {1} 
  7.     this.createHook(); // {2} 
  8.   } 
  9.   createHook() { 
  10.     const ctx = this; 
  11.     const hooks = asyncHooks.createHook({ 
  12.       init(asyncId, type, triggerAsyncId) { 
  13.         if (ctx.storeMap.has(triggerAsyncId)) { 
  14.           ctx.storeMap.set(asyncId, ctx.storeMap.get(triggerAsyncId)); 
  15.         } 
  16.       }, 
  17.       destroy(asyncId) { 
  18.         ctx.storeMap.delete(asyncId); 
  19.       } 
  20.     }); 
  21.     hooks.enable(); 
  22.   } 
  23.   run(store, callback) { // {3} 
  24.     this.storeMap.set(executionAsyncId(), store); 
  25.     callback(); 
  26.   } 
  27.   getStore() { // {4} 
  28.     return this.storeMap.get(executionAsyncId()); 
  29.   } 
  30. module.exports = AsyncLocalStorage; 

注意,在我們定義的 createHook() 方法里有 hooks.enable(); 這樣一段代碼,這是因為 Promise 默認(rèn)是沒有開啟的,通過顯示的調(diào)用可以開啟 Promise 的異步追蹤。

改造 logger.js 文件

在我們需要打印日志的地方拿到當(dāng)前代碼所對應(yīng)的上下文信息,取出我們存儲的 traceId, 這種方式只需要改造我們?nèi)罩局虚g即可,不需要去更改我們的業(yè)務(wù)代碼。

  1. const { v4: uuidV4 } = require('uuid'); 
  2. const AsyncLocalStorage = require('./AsyncLocalStorage'); 
  3. const asyncLocalStorage = new AsyncLocalStorage(); 
  4.  
  5. const logger = { 
  6.   info: (...args) => { 
  7.     const traceId = asyncLocalStorage.getStore(); 
  8.     console.log(traceId, ...args); 
  9.   }, 
  10.   run: (req, callback) => { 
  11.     asyncLocalStorage.run(req.headers.requestId || uuidV4(), callback); 
  12.   } 
  13.  
  14. module.exports = { 
  15.   logger, 

改造 app.js 文件

注冊一個中間件,傳遞請求信息。

  1. app.use((req, res, next) => logger.run(req, next)); 

運行后輸出結(jié)果

  1. e82d1a1f-5038-4ac9-a9c8-2aa5abb0f96a Get user list at router layer. 
  2. e82d1a1f-5038-4ac9-a9c8-2aa5abb0f96a Get user list at controller layer. 
  3. e82d1a1f-5038-4ac9-a9c8-2aa5abb0f96a Get user list at service layer. 
  4. e82d1a1f-5038-4ac9-a9c8-2aa5abb0f96a Get user list at model layer. 
  5. e82d1a1f-5038-4ac9-a9c8-2aa5abb0f96a setTimeout 2s at service layer. 

這種方式就是完全基于 Async Hooks 提供的 API 來實現(xiàn),不理解其實現(xiàn)原理的可以在動手實踐下,這種方式需要我們額外維護(hù)維護(hù)一個 Map 對象,還要處理銷毀操作。

方式二:executionAsyncResource() 返回當(dāng)前執(zhí)行的異步資源

executionAsyncResource() 返回當(dāng)前執(zhí)行的異步資源,這對于實現(xiàn)連續(xù)的本地存儲很有幫助,無需像 “方式一” 再創(chuàng)建一個 Map 對象來存儲元數(shù)據(jù)。

  1. const asyncHooks = require('async_hooks'); 
  2. const { executionAsyncId, executionAsyncResource } = asyncHooks; 
  3.  
  4. class AsyncLocalStorage { 
  5.   constructor() { 
  6.     this.createHook(); 
  7.   } 
  8.   createHook() { 
  9.     const hooks = asyncHooks.createHook({ 
  10.       init(asyncId, type, triggerAsyncId, resource) { 
  11.         const cr = executionAsyncResource(); 
  12.         if (cr) { 
  13.           resource[asyncId] = cr[triggerAsyncId]; 
  14.         } 
  15.       } 
  16.     }); 
  17.     hooks.enable(); 
  18.   } 
  19.   run(store, callback) { 
  20.     executionAsyncResource()[executionAsyncId()] = store; 
  21.     callback(); 
  22.   } 
  23.   getStore() { 
  24.     return executionAsyncResource()[executionAsyncId()]; 
  25.   } 
  26.  
  27. module.exports = AsyncLocalStorage; 

方式三:基于 ResourceAsync 創(chuàng)建 AsyncLocalStorage 類

ResourceAysnc 可以用來自定義異步資源,此處的介紹也是參考 Node.js 源碼對 AsyncLocalStorage 的實現(xiàn)。

一個顯著的改變是 run() 方法,每一次的調(diào)用都會創(chuàng)建一個資源,調(diào)用其 runInAsyncScope() 方法,這樣在這個資源的異步作用域下,所執(zhí)行的代碼(傳入的 callback)都是可追蹤我們設(shè)置的 store。

 

  1. const asyncHooks = require('async_hooks'); 
  2. const { executionAsyncResource, AsyncResource } = asyncHooks; 
  3.  
  4. class AsyncLocalStorage { 
  5.   constructor() { 
  6.     this.kResourceStore = Symbol('kResourceStore'); 
  7.     this.enabled = false
  8.     const ctx = this; 
  9.     this.hooks = asyncHooks.createHook({ 
  10.       init(asyncId, type, triggerAsyncId, resource) { 
  11.         const currentResource = executionAsyncResource(); 
  12.         ctx._propagate(resource, currentResource) 
  13.       } 
  14.     }); 
  15.   } 
  16.  
  17.   // Propagate the context from a parent resource to a child one 
  18.   _propagate(resource, triggerResource) { 
  19.     const store = triggerResource[this.kResourceStore]; 
  20.     if (store) { 
  21.       resource[this.kResourceStore] = store; 
  22.     } 
  23.   } 
  24.  
  25.   _enable() { 
  26.     if (!this.enabled) { 
  27.       this.enabled = true
  28.       this.hooks.enable(); 
  29.     } 
  30.   } 
  31.  
  32.   enterWith(store) { 
  33.     this._enable(); 
  34.     const resource = executionAsyncResource(); 
  35.     resource[this.kResourceStore] = store; 
  36.   } 
  37.  
  38.   run(store, callback) { 
  39.     const resource = new AsyncResource('AsyncLocalStorage', { 
  40.       requireManualDestroy: true
  41.     }); 
  42.     return resource.emitDestroy().runInAsyncScope(() => { 
  43.       this.enterWith(store); 
  44.       return callback(); 
  45.     }); 
  46.   } 
  47.  
  48.   getStore() { 
  49.     return executionAsyncResource()[this.kResourceStore]; 
  50.   } 
  51.  
  52. module.exports = AsyncLocalStorage; 

方式四:AsyncLocalStorage 類

Node.js v13.10.0 async_hooks 模塊新加入了 AsyncLocalStorage 類,實例化一個對象調(diào)用 run() 方法實現(xiàn)本地存儲,也是推薦的方式,不需要自己去再額外維護(hù)一個 AsyncLocalStorage 類。

AsyncLocalStorage 類的實現(xiàn)也就是上面講解的方式三,所以也不需要我們在外部顯示的調(diào)用 hooks.enable() 來啟用 Promise 異步追蹤,因為其內(nèi)部已經(jīng)實現(xiàn)了。

  1. const { AsyncLocalStorage } = require('async_hooks'); 

Async Hooks 的性能開銷

這一點是大家最關(guān)心的問題,如果開啟了 Async Hooks(Promise 需要調(diào)用 Async Hooks 實例的 enable() 方法開啟)每一次異步操作或 Promise 類型的操作,包括 console 只要是異步的都會觸發(fā) hooks,也必然是有性能開銷的。

參考 Kuzzle 的性能基準(zhǔn)測試,使用了 AsyncLocalStorage 與未使用之間相差 ~8%。

---- Log with AsyncLocalStorage Log classic difference
req/s 2613 2842 〜8%

當(dāng)然不同的業(yè)務(wù)也有著不同的差異,如果你擔(dān)心會有很大的性能開銷,可以基于自己的業(yè)務(wù)做一些基準(zhǔn)測試。

Reference

[1]

nodejs.org/api/async_hooks.html: https://nodejs.org/api/async_hooks.html

[2]

Node.js 14 & AsyncLocalStorage: Share a context between asynchronous calls: https://blog.kuzzle.io/nodejs-14-asynclocalstorage-asynchronous-calls

[3]

在 Node 中通過 Async Hooks 實現(xiàn)請求作用域: https://mp.weixin.qq.com/s/I22TvmTqCKFClsp0YLDoZw

[4]

Async Hooks 性能影響: https://github.com/nodejs/benchmarking/issues/181

[5]

kuzzle 基準(zhǔn)測試: https://github.com/kuzzleio/kuzzle/pull/1604

本文轉(zhuǎn)載自微信公眾號「Nodejs技術(shù)棧」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Nodejs技術(shù)棧公眾號。

 

責(zé)任編輯:武曉燕 來源: Nodejs技術(shù)棧
相關(guān)推薦

2021-01-26 08:07:44

Node.js模塊 Async

2021-01-18 08:06:38

Node.js 追蹤JSON

2023-01-30 22:34:44

Node.js前端

2021-08-12 01:00:29

NodejsAsync

2021-10-27 07:15:36

NodeLTS異步

2021-04-06 10:15:29

Node.jsHooks前端

2021-07-26 05:24:59

Node.js SO_RESUEPORLibuv

2017-05-11 14:00:02

Flask請求上下文應(yīng)用上下文

2022-05-23 08:23:24

鏈路追蹤SleuthSpring

2021-07-30 11:20:53

JavaScriptNode.jsWeb Develop

2024-03-18 10:15:00

HTTPNode.jsAPI

2022-09-15 08:01:14

繼承基礎(chǔ)設(shè)施基礎(chǔ)服務(wù)

2023-10-04 07:35:03

2020-08-05 08:31:51

SSL TLSNode.js

2014-09-12 10:35:09

Node.jsHTTP 206

2021-10-21 08:59:17

技術(shù)HTTP攻擊

2020-10-26 08:34:13

Node.jsCORS前端

2021-10-03 15:02:50

HTTPNodejs

2021-07-16 04:56:03

NodejsAddon

2017-04-24 08:31:26

Node.jsExpress.jsHTTP
點贊
收藏

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

亚洲日本japanese丝袜| 欧美久久精品一级黑人c片| 国产福利视频在线播放| a天堂在线资源| 国产一区二区视频在线| 69av成年福利视频| 99久久精品久久亚洲精品| 91久久精品无嫩草影院| 91福利社在线观看| 国产在线视频综合| 国产乱理伦片a级在线观看| 韩国v欧美v日本v亚洲v| 欧美在线亚洲一区| 欧美又粗又大又长| 欧美色女视频| 亚洲国产精品久久精品怡红院| 亚洲一二三区av| 黄色漫画在线免费看| 国产精品成人一区二区艾草| 精品乱子伦一区二区三区| 国产伦子伦对白视频| 亚洲欧美日韩专区| 欧美激情免费在线| 91香蕉视频网| 国产欧美日韩免费观看| 亚洲精品一区二区三区99| 亚洲欧美日韩精品一区| 人人鲁人人莫人人爱精品| 午夜视频在线观看一区二区| 日本福利视频导航| 成人在线免费看| av一本久道久久综合久久鬼色| 97伦理在线四区| 亚洲天堂免费av| 日韩电影在线观看电影| 日韩美女激情视频| 在线能看的av| 中文亚洲字幕| 久久免费视频网| 青青草在线观看视频| 亚洲激情五月| 久久深夜福利免费观看| 老司机精品免费视频| 国精一区二区| 国产一区二区三区在线看| 亚洲色图14p| 天堂网av成人| 日韩成人av一区| 少妇一级淫免费观看| 国产91精品入| 亚洲激情视频在线播放| 欧美夫妇交换xxx| 加勒比视频一区| 亚洲国产精品人人爽夜夜爽| 久久精品aⅴ无码中文字字幕重口| 日韩视频在线直播| 日韩一二三区视频| 亚洲图片欧美另类| 欧美巨大xxxx| 亚洲精品在线观看www| av直播在线观看| 国产一区二区三区四区| 中文字幕日韩有码| av最新在线观看| 亚洲综合专区| 久久久久久国产精品三级玉女聊斋| 久草成人在线视频| 亚洲美洲欧洲综合国产一区| 欧美在线一区二区视频| 国内av在线播放| 极品少妇xxxx精品少妇| 成人动漫视频在线观看免费| 日韩一级片免费在线观看| 久久日韩粉嫩一区二区三区| 日韩视频在线观看国产| 超碰caoporn久久| 午夜精品福利一区二区三区蜜桃| 极品美女扒开粉嫩小泬| 日韩一区精品| 欧美一区二区免费视频| 国产伦精品一区三区精东| 自拍视频一区| 精品国产一区二区三区在线观看| 久久艹精品视频| 久久九九电影| 91嫩草在线视频| 色婷婷av一区二区三| 国产精品私人自拍| 国产精品国三级国产av| 婷婷综合六月| 日韩午夜av一区| 91精品人妻一区二区| 五月久久久综合一区二区小说| 国产做受高潮69| 国产天堂第一区| 国产91精品在线观看| 日韩精品不卡| 久草在线资源站资源站| 欧美无人高清视频在线观看| 欧美图片自拍偷拍| 成人在线免费观看网站| 久久久亚洲欧洲日产国码aⅴ| 免费污污视频在线观看| 丁香网亚洲国际| 亚洲一区美女| 在线观看涩涩| 精品国产乱码久久久久久老虎| 黄色三级生活片| 亚洲另类自拍| 亚洲a∨日韩av高清在线观看| 日韩av成人| 亚洲制服欧美中文字幕中文字幕| 成人中文字幕av| 欧美天堂社区| 久久久久久12| av男人天堂网| 国产精品美女久久福利网站| 欧美v在线观看| 99久久人爽人人添人人澡| 久久久精品一区二区三区| jizz国产在线观看| 99久久99久久免费精品蜜臀| 成年人三级视频| 国产精品99| 国产一区二区免费| 国产又大又黄又粗| 成人av网址在线| 欧美这里只有精品| 日韩视频在线直播| 欧美成人免费在线观看| 亚洲天堂狠狠干| 国产精品久久久久一区二区三区 | gogo亚洲高清大胆美女人体| 亚洲护士老师的毛茸茸最新章节 | 米奇精品一区二区三区| 日本高清不卡一区| 亚洲精品视频久久久| 中日韩男男gay无套| 国产精品香蕉视屏| av成人 com a| 日韩精品免费视频| 中文字幕超碰在线| 久久新电视剧免费观看| 看av免费毛片手机播放| 亚洲午夜久久| 国产97色在线|日韩| 久久久久久久久亚洲精品| 懂色av中文一区二区三区天美| 日本不卡视频一区| 99精品国产一区二区青青牛奶| 精品国产_亚洲人成在线| 免费成人在线电影| 亚洲人成77777在线观看网| 日本丰满少妇做爰爽爽| 中文字幕免费不卡在线| 九九热免费在线观看| 欧美在线看片| 国产精品有限公司| jk漫画禁漫成人入口| 国产亚洲精品久久久| 中文无码精品一区二区三区| 成人免费小视频| 少妇欧美激情一区二区三区| 激情成人亚洲| 久久综合一区| 久久天天久久| 久久久久九九九九| 欧洲免费在线视频| 欧美日韩国产在线播放网站| 一起操在线播放| 成人美女视频在线观看| 女性隐私黄www网站视频| 色偷偷综合网| 成人在线看片| 欧美三级网址| 久久久久北条麻妃免费看| 亚洲欧美国产高清va在线播放| 精品av在线播放| 女人十八毛片嫩草av| 国产黄人亚洲片| 国产女大学生av| 日韩精品1区| 国产美女精品在线观看| 亚洲四虎影院| 欧美黑人巨大xxx极品| 国产中文字幕在线视频| 日韩午夜激情视频| 国产精品自拍第一页| 一区二区三区中文字幕| 蜜桃传媒一区二区亚洲| 高清不卡一区二区在线| 国产一线二线三线在线观看| 欧美涩涩网站| 日韩免费电影一区二区| **爰片久久毛片| 国产精品jizz在线观看麻豆| 久久亚洲导航| 色偷偷av亚洲男人的天堂| 亚洲国产精品视频在线| 欧美性大战久久久久久久| 日产精品久久久久久久| 亚洲色图欧美偷拍| 91中文字幕永久在线| 国产69精品久久久久777| 冲田杏梨av在线| 亚洲美女网站| 无码人妻精品一区二区蜜桃网站| 欧美丰满老妇| 品久久久久久久久久96高清| 福利电影一区| 成人毛片网站| 国产精品日本一区二区三区在线| 国产精品成久久久久三级| 川上优av中文字幕一区二区| 欧美国产日韩精品| 黄色成人影院| 中文字幕欧美日韩va免费视频| 日韩有码电影| 亚洲精品国产品国语在线| 亚洲欧美国产高清va在线播放| 91精品国模一区二区三区| 艳妇乳肉豪妇荡乳av无码福利| 一本色道久久综合亚洲aⅴ蜜桃 | 麻豆蜜桃在线观看| 欧美精品videos| а天堂中文在线官网| 色噜噜亚洲精品中文字幕| 精品一二三区视频| 日韩av影片在线观看| 欧美天堂在线视频| 精品国产乱码久久久久久闺蜜| www.国产麻豆| 日韩精品自拍偷拍| 亚洲av无码国产精品永久一区| 91.成人天堂一区| 91免费视频播放| 欧美日本在线视频| 一本色道久久综合无码人妻| 欧美精品丝袜中出| 6—12呦国产精品| 欧美日本在线播放| 国产理论片在线观看| 在线播放视频一区| 99久久精品国产一区色| 日韩一区二区精品| 风流少妇一区二区三区91| 日韩欧美一二三区| 成人午夜视频一区二区播放| 精品av久久707| 日韩电影免费| 永久免费精品影视网站| 日韩av中文| 美日韩丰满少妇在线观看| 污片视频在线免费观看| 久久久免费精品视频| 天天综合av| 国产精品久久久久久久久久小说 | 老牛嫩草一区二区三区日本| www黄色在线| 久久精品二区亚洲w码| 久久精品一卡二卡| 成人一二三区视频| 人妻精品久久久久中文字幕| 国产日韩欧美a| 波多野结衣爱爱视频| 五月综合激情网| 无码人妻久久一区二区三区不卡| 欧美色综合网站| 99久久久国产精品无码网爆| 亚洲国产美女精品久久久久∴| 你懂的好爽在线观看| 色噜噜亚洲精品中文字幕| 日本小视频在线免费观看| 日本不卡免费高清视频| 黄页免费欧美| 成人在线免费观看一区| 国产影视一区| 91大学生片黄在线观看| 亚洲永久在线| 奇米视频888| 91亚洲精品久久久蜜桃网站| 免费成人美女女在线观看| 亚洲1区2区3区4区| 中文字幕在线观看你懂的| 精品久久久久久久久久久久久久久 | 26uuu国产电影一区二区| 日本不卡一区视频| 亚洲国产三级在线| 亚洲天堂自拍偷拍| 亚洲级视频在线观看免费1级| 成人一区二区不卡免费| 欧美激情精品久久久| 亚洲精品555| 国产一区在线观| 亚洲激情久久| youjizzxxxx18| 99国产欧美久久久精品| 亚洲人与黑人屁股眼交| 91福利在线免费观看| 日本国产在线观看| 久久国产精品久久久久| 亚洲播播91| 国产中文一区二区| 牛牛国产精品| 国产3p在线播放| 久久丝袜美腿综合| 国产午夜精品一区二区理论影院 | 黑丝av在线播放| 亚洲欧美日韩在线不卡| 日本成人一级片| 亚洲欧美福利视频| 高清精品在线| 91免费在线观看网站| 欧美hentaied在线观看| 国产 porn| 久久久夜色精品亚洲| 日韩免费一级片| 欧美成人精品3d动漫h| 国产原创在线观看| 国产视频999| 精品国产91久久久久久浪潮蜜月| 免费成人在线视频网站| av中文一区二区三区| 黄色一级视频在线观看| 欧美一区二区三区在线看| 成人在线视频成人| 国产精品美女网站| 精品在线播放| 免费高清在线观看免费| 99精品视频一区二区三区| 国产一级av毛片| 欧美va亚洲va| 男人天堂亚洲| 国产精品成人观看视频免费| 欧美另类综合| 丰满人妻一区二区三区免费视频棣| 亚洲乱码国产乱码精品精可以看| 国产精品伦一区二区三区| www.99久久热国产日韩欧美.com| 欧美一级做a| 蜜臀av.com| 国产69精品久久久久777| 国产性猛交普通话对白| 亚洲国产精彩中文乱码av在线播放| 超级碰碰不卡在线视频| 精品国产乱码久久久久久丨区2区| 一本久道综合久久精品| 精品无码人妻一区| 欧美婷婷六月丁香综合色| 免费在线观看黄| 91成人理论电影| 亚洲人人精品| 日韩精品电影一区二区| 欧美日韩在线播放三区| 高h视频在线观看| 国产精品国模大尺度私拍| 亚洲精品裸体| 久久久久久国产免费a片| 欧美日韩午夜影院| 啦啦啦中文在线观看日本| 精品欧美日韩| 免费在线观看视频一区| 国精品人伦一区二区三区蜜桃| 日韩欧美www| 亚洲黄色中文字幕| 亚洲一区高清| 成人免费观看视频| 久久精品偷拍视频| 欧美xxxx做受欧美.88| 伦理一区二区三区| 午夜欧美福利视频| 亚洲精品免费在线播放| 亚洲av成人精品日韩在线播放| 国产精品久久久久久久久男| 日本系列第一页| 日韩视频免费观看高清完整版在线观看 | 亚洲乱码一区| 亚洲成熟丰满熟妇高潮xxxxx| 成人免费一区二区三区视频 | 欧美激情综合色综合啪啪五月| 亚瑟一区二区三区四区| 亚洲精品自拍网| 亚洲高清免费一级二级三级| 国产资源在线播放| 国产91色在线|亚洲| 天堂精品中文字幕在线| 欧美黄色一级网站| 亚洲三级av在线| **爰片久久毛片| 污污网站在线观看视频| 欧美日韩一区二区三区在线免费观看| 天堂中文8资源在线8| 麻豆蜜桃91| 懂色av噜噜一区二区三区av| 艳妇乳肉豪妇荡乳av无码福利| 97国产在线视频| 亚洲欧美综合久久久| 色综合99久久久无码国产精品| 亚洲第一区在线| 91国产精品|