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

攜程機票前端Web流式通信SSE全鏈路應用實踐

人工智能 新聞
本文介紹了 SSE 在攜程機票前端全鏈路企業級應用實踐,解決了服務向前端實時推送數據的問題。

作者簡介

Chris Xia,攜程前端開發專家,關注新技術革新和研發效率提升。

本文介紹了攜程機票前端基于Server-Sent Events(SSE)實現服務端推送的企業級全鏈路通用技術解決方案。深入探討 SSE 技術在應用過程中包括方案對比、技術選型、鏈路層優化以及實際效果等多維度的技術細節,為類似使用場景提供普適性參考和借鑒。該方案設計目標是實現通用性,適用于各種網絡架構和業務場景。

一、概述

二、SSE介紹

2.1 SSE 是什么?

2.2 SSE 的使用場景

三、應用實踐

四、方案對比

4.1 服務端推送

4.2 內部SSE實踐方案

4.3 SSE 技術選型

五、全鏈路支持

5.1 鏈路層

5.2 框架層

5.3 數據層

六、結語

一、概述

在如今互聯網應用中,實時數據推送已成為很多業務場景的關鍵技術解決方案。攜程機票業務作為在線旅游行業的核心場景,面臨著航班數據實時性要求高、信息維度復雜等挑戰。Server-Sent Events(SSE)技術作為一種基于 HTTP 長連接的服務器推送方案,非常適用于機票業務"服務端主動推送、客戶端實時展示"的需求特點。相較于 WebSocket 等雙向通信協議,SSE 在實現簡單性、協議輕量級和瀏覽器兼容性等方面具有顯著優勢,適合機票列表頁這類以服務端數據為主導的業務場景。

二、SSE介紹

2.1 SSE 是什么?

Server-Sent Events(SSE)服務器發送事件,是一種基于 HTTP 長連接,允許服務器單向實時推送數據到客戶端的技術。

SSE 的工作原理非常簡單直觀。客戶端通過與服務器建立一條持久化的 HTTP 連接,然后服務器使用該連接將數據以事件流(event stream)的形式發送給客戶端。這些事件流由多個事件(event)組成,每個事件包含一個標識符、類型和數據字段。客戶端通過監聽事件流來獲取最新的數據,并在接收到事件后進行處理。

2.2 SSE 的使用場景

SSE 使用場景非常廣泛,大家熟知的 Chatgpt 對話的交互形式使用的就是 SSE 技術。SSE 在服務器單向實時推送數據的場景非常適用:

  • 實時數據流:如股票市場更新、新聞推送、體育比分更新等。
  • 實時通知:如社交媒體消息提醒、新訂單通知等。
  • 儀表盤更新:如系統監控、實時數據統計等。

三、應用實踐

機票前端首次在核心業務中(機票航班列表)使用 SSE 技術,機票列表頁由原先客戶端串行請求獲取多批次航班數據變為一次請求由服務持續推送數據給客戶端。在調研了公司內外各種實現方案,最終聯合攜程框架、SRE、機票前后端團隊共同實現了全公司通用的SSE技術解決方案(詳情見下文中的全鏈路支持部分)。

使用 SSE 前(如下圖)

  • 客戶端需要發起兩次請求獲取完整航班數據
  • 服務端采用預取優化:在響應第一次請求時,提前獲取第二批數據并緩存至 Redis(降低客戶端第二次請求響應的耗時)
  • 客戶端發起第二次請求時,可直接獲取緩存數據

這樣的流程和技術方案無疑會提升前后端的代碼復雜度,服務端需要額外增加一層緩存來提升響應時間,客戶端無法感知服務到底有多少批次數據,需要不斷問詢。

使用 SSE 后(如下圖)

客戶端發送一次 SSE 請求,服務端實時推送數據到客戶端,服務間上下游同樣采用流式傳輸,實現客戶端到服務端全鏈路流式通信。

SSE 為前后端帶來的價值

  • 減少請求傳輸耗時:無需請求多次,減少了多次請求的傳輸耗時。
  • 前后端代碼結構優化:代碼更簡潔且易于理解,減少串行請求的回調監聽/嵌套。
  • 服務邏輯優化:列表數據移除了 redis 的發布訂閱流程,簡化了代碼架構。
  • 資源利用率提升:減少冗余請求(只有一批數據時,客戶端不用再次請求問詢服務)。

SSE 對性能有提升嗎?

通過分析請求流程(建立鏈接 -> 發送請求 -> 響應數據傳輸)和其原理,發現 HTTP 1.1 和 2 支持鏈路復用,因此鏈接建立的次數本質上沒有變化。在傳輸通道和數據壓縮方式保持不變的情況下,響應數據傳輸的耗時也不會有明顯變化。

SSE 的核心性能優勢在于減少了請求發送的次數,其性能增益取決于具體的使用場景:

  • 當服務端響應耗時大于網絡傳輸耗時,性能提升有限。

使用 SSE 與傳統串行請求的性能實驗數據對比:

  • 當網絡傳輸耗時大于服務端處理耗時,減少請求次數可以顯著降低整體延遲。

四、方案對比

目前市面上很多服務端推送的技術解決方案:SSE、輪詢/串行、Websocket 等,我們從易用性,資源開銷,使用場景等多維度對比了幾個使用較多的主流方案,最終選擇了 SSE。

4.1 服務端推送(SSE、輪詢、Websocket)

SSE 使用

簡單幾行代碼實現服務端推送

數據傳輸格式

SSE 的數據傳輸規范中有 4 個關鍵字段 event、data、id 和 retry,用于定義和傳輸事件數據。

even:定義消息的事件類型,客戶端可以根據事件類型觸發不同的處理邏輯。

data:消息的主體內容

id:為消息設置一個唯一的 ID,用于客戶端斷線重連時標識最后接收的消息。

retry:服務端指定客戶端在連接斷開后重新連接的時間間隔(單位為毫秒)。

這些字段共同構成了 SSE 消息的基本格式,每條消息以兩個換行符 \n\n 結束,確保客戶端能夠正確解析和處理事件數據。

前端使用樣例

// 創建 EventSource
const evtSource = new EventSource("接口地址");


// 監聽服務端推送的數據
evtSource.onmessage = function (event) {
  console.log("接收到的消息:", event);
};


// 監聽連接建立
evtSource.onopen = function () {
  console.log("連接已建立");
};


// 監聽報錯
evtSource.onerror = function (err) {
  console.error("發生異常:", err);
};

服務使用樣例(以 Nodejs 為例)

const http = require("http");


http
.createServer((req, res) => {
    // 設置Response Header
    res.writeHead(200, {
      "Content-Type": "text/event-stream",
      "Cache-Control": "no-cache",
      Connection: "keep-alive",
    });
    // 不斷推送數據給客戶端
    const pushData = setInterval(() => {
      res.write(data);
    }, 1000);


    req.on("close", () => clearInterval(pushData));
  })
  .listen(3000);

4.2 內部SSE實踐方案

調研發現公司內部有兩套實踐方案:

  • 自定義響應式網關,實現網關輪詢服務批量獲取數據,從而實現流式傳輸。

通用性:繞開公司鏈路層,沒有通用性。

  • 前端輪詢下沉BFF(服務),前端與BFF建立SSE通道,BFF不斷輪詢向上游批量獲取數據。

完整度:輪詢位置發生變化,并未實現全鏈路的流式通信。

在攜程企業級網絡生態架構下,從通用性和完整度分析對比了兩套方案,并沒有真正意義上從前到后打通整條鏈路。僅僅只是簡單接入SSE是遠遠不夠的,離不開全鏈路(SSE技術選型,多層網絡架構的適配,服務間的流式通信等等)的支持,所以最終決定聯合攜程框架、SRE、機票前后端團隊共同來實現對SSE全鏈路的適配,真正意義上實現全公司通用的普適方案。

4.3 SSE 技術選型(原生 SSE vs fetch-event-source)

確定好整體技術方案后,我們在實際測試過程中發現了 2 個 Web 原生 SSE 的局限性問題:

1)僅支持 Get 請求:對需要傳遞一些復雜請求體的場景不友好。

2)不支持自定義 http header:無法支持自定義 header 透傳,鑒權等場景,目前市面大部分解決方案是使用 Cookie 來攜帶自定義參數。

針對上述問題,調研發現微軟開源的 SSE 網絡庫 @microsoft/fetch-event-source(以下簡稱 fes)能夠很好的解決。fes 是基于 Fetch 和 ReadableStream 來實現的 SSE 功能,旨在提供更加靈活便利的調用方式。

原生 SSE 和 fes 的對比

fetch-event-source 詳解

fes 的核心原理是通過 Fetch 發送請求,ReadableStream 讀取響應流,在 JS 側實現字節流數據的解析。通過對比原生 SSE(chromium 內核中 EventSource)和 fes 的代碼,發現整體流程與實現方案大致相同,關鍵區別在于流的解析,原生 SSE 在瀏覽器內核由 C++實現,fes 在 JS 側實現。

fes 的流解析

核心方法:getBytes、getLines  和  getMessages

getBytes:通過 ReadableStream 讀取響應字節流,獲取每個字節塊。

getLines :將 getBytes 獲取到的字節塊解析為 EventSource 行緩沖區,處理這些字節塊并解析為行,然后調用  onLine  回調函數處理每一行。

getMessages:創建 EventSourceMessage 對象,將行緩沖區數據解析并進行組裝,處理完成后回調給調用方。

export async function getBytes(stream: ReadableStream<Uint8Array>, onChunk: (arr: Uint8Array) => void) {
    const reader = stream.getReader();
    let result: ReadableStreamDefaultReadResult<Uint8Array>;
    while (!(result = await reader.read()).done) {
        onChunk(result.value);
    }
}
export function getMessages(
    onId: (id: string) => void,
    onRetry: (retry: number) => void,
    onMessage?: (msg: EventSourceMessage) => void
) {
    let message = newMessage();
    const decoder = new TextDecoder();


    // return a function that can process each incoming line buffer:
    return function onLine(line: Uint8Array, fieldLength: number) {
        if (line.length === 0) {
            // empty line denotes end of message. Trigger the callback and start a new message:
            onMessage?.(message);
            message = newMessage();
        } else if (fieldLength > 0) { // exclude comments and lines with no values
            // line is of format "<field>:<value>" or "<field>: <value>"
            // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
            const field = decoder.decode(line.subarray(0, fieldLength));
            const valueOffset = fieldLength + (line[fieldLength + 1] === ControlChars.Space ? 2 : 1);
            const value = decoder.decode(line.subarray(valueOffset));


            switch (field) {
                case 'data':
                    // if this message already has data, append the new value to the old.
                    // otherwise, just set to the new value:
                    message.data = message.data
                        ? message.data + '\n' + value
                        : value;
                    break;
                case 'event':
                    message.event = value;
                    break;
                case 'id':
                    onId(message.id = value);
                    break;
                case 'retry':
                    const retry = parseInt(value, 10);
                    if (!isNaN(retry)) {
                        onRetry(message.retry = retry);
                    }
                    break;
            }
        }
    }
}
export function getLines(onLine: (line: Uint8Array, fieldLength: number) => void) {
    let buffer: Uint8Array | undefined;
    let position: number; // current read position
    let fieldLength: number; // length of the `field` portion of the line
    let discardTrailingNewline = false;


    return function onChunk(arr: Uint8Array) {
        if (buffer === undefined) {
            buffer = arr;
            position = 0;
            fieldLength = -1;
        } else {
            buffer = concat(buffer, arr);
        }


        const bufLength = buffer.length;
        let lineStart = 0; // index where the current line starts
        while (position < bufLength) {
            if (discardTrailingNewline) {
                if (buffer[position] === ControlChars.NewLine) {
                    lineStart = ++position; // skip to next char
                }


                discardTrailingNewline = false;
            }


            let lineEnd = -1; // index of the \r or \n char
            for (; position < bufLength && lineEnd === -1; ++position) {
                switch (buffer[position]) {
                    case ControlChars.Colon:
                        if (fieldLength === -1) { // first colon in line
                            fieldLength = position - lineStart;
                        }
                        break;
                    case ControlChars.CarriageReturn:
                        discardTrailingNewline = true;
                    case ControlChars.NewLine:
                        lineEnd = position;
                        break;
                }
            }


            if (lineEnd === -1) {
                break;
            }


            onLine(buffer.subarray(lineStart, lineEnd), fieldLength);
            lineStart = position; // we're now on the next line
            fieldLength = -1;
        }


        if (lineStart === bufLength) {
            buffer = undefined; // we've finished reading it
        } else if (lineStart !== 0) {
            buffer = buffer.subarray(lineStart);
            position -= lineStart;
        }
    }
}

關于SSE原生流解析 與 fes流解析是不同語言實現的這一點,我們也思考了語言差異對性能的影響,所以對響應數據的解析耗時做了實驗,在相同機器和網絡環境下,對比了原生 SSE 和 fes 處理數據流的耗時,實驗結論是兩者在耗時上沒有明顯差異(毫秒級)。從后續在機票列表頁大規模應用后的監控數據上看也印證了這一點。

fes 在使用上更適用于現代 Web 應用和 Node.js 環境,解決了原生 EventSource 的局限性,提供了更豐富的功能和更細粒度的控制。

五、全鏈路支持

企業級應用時,在非直連多層網絡架構的環境下,應用SSE不僅需要考慮前后端的使用,還需要考慮鏈路層、框架層、數據層等多環節的支持。通過不同團隊(如框架、SRE、機票前端和后端團隊)的協作,開發出一個在公司范圍內通用的解決方案。

5.1 鏈路層

在攜程海外上云、多地多活服務架構、多層網絡架構的背景下,攜程框架及SRE團隊提供了大力支持,完整打通了各鏈路層之間的流式傳輸。

多層網絡架構

  • 7層加速節點(akamai/aws):提供全球范圍內的快速數據傳輸。
  • 流量接入層(slb):確保高可用性和負載均衡。
  • 中間轉發節點(蟲洞):優化跨Region數據傳輸路徑,減少延遲。
  • sidecar(envoy/nginx):容器流量管理,增強了應用的可維護性和擴展性。

對于絕大部分負載均衡,一般只保證完整報文的交付,并不保證報文的交付形式(流式/聚合),聚合場景下會導致"數據碎片"被聚合再交付,無法實現流式分批傳輸:

以Nginx為例

Nginx 會緩存代理服務器的響應(聚合類型),服務推送的數據被 Nginx 緩存到緩沖區,導致客戶端沒有實時收到數據,而是等到服務所有數據推送完后,客戶端才一次性收到了所有數據。

適配方案:

禁用緩存功能,服務端響應時除了設置 SSE 所必須的 Response Header 外,還需要添加非標 Header:X-Accel-Buffering: no,告知 Nginx 不緩存響應,確保數據實時發送到客戶端。

值得注意的是,在多層網絡架構的環境下 X-Accel-Buffering: no Header 在各層網關之間轉發時會丟失,所以在多層網絡架構下 Nginx 需要添加 proxy_pass_header X-Accel-Buffering,來確保整條鏈路上 Header 的傳遞。

5.2 框架層

前端框架團隊基于fes實現SSE網絡請求,合并到公司基礎網絡框架,共享網絡優化,監控等基建能力,全公司通用。服務端基于Reactor + Dubbo Streaming實現服務間上下游全鏈路響應式流式傳輸。

通過鏈路層的支持,從前端到服務端實現了統一的全鏈路流式傳輸通信,確保數據的高效傳輸和處理。

5.3 數據層

數據傳輸需注意代理服務器或 Web 容器(Nginx、Tomcat)對SSE MIME Type:text/event-stream的支持,未正確配置,服務端推送的數據不會經過任何壓縮,傳輸數據大,導致客戶端響應耗時增加。

適配方案:根據不同的服務器類型進行配置。

1)Nginx

2)Tomcat

六、結語

本文介紹了 SSE 在攜程機票前端全鏈路企業級應用實踐,解決了服務向前端實時推送數據的問題。通過合理的技術選型、流式數據解析和鏈路傳輸層優化,從鏈路層,框架層,數據層全鏈路實現全公司通用的普適方案。降低了前后端代碼復雜度,提升了資源利用率。隨著流式通信技術的不斷發展,SSE 將在更多場景中(覆蓋更多客戶端,支持更多網絡協議)發揮重要作用,為實時數據處理提供更高效的解決方案。

責任編輯:張燕妮 來源: 攜程技術
相關推薦

2022-06-03 09:21:47

Svelte前端攜程

2024-07-25 11:58:35

2022-05-13 09:27:55

Widget機票業務App

2023-05-12 10:14:38

APP開發

2020-12-04 14:32:33

AndroidJetpackKotlin

2023-08-25 09:51:21

前端開發

2022-07-15 12:58:02

鴻蒙攜程華為

2017-04-11 15:11:52

ABtestABT變量法

2022-06-10 08:35:06

項目數據庫攜程機票

2023-11-13 11:27:58

攜程可視化

2024-12-18 10:20:00

攜程鴻蒙開發

2024-09-10 16:09:58

2022-08-06 08:27:41

Trace系統機票前臺微服務架構

2025-06-24 09:44:41

2023-01-30 22:34:44

Node.js前端

2023-06-06 16:01:00

Web優化

2022-06-27 09:36:29

攜程度假GraphQL多端開發

2022-04-27 10:53:34

web優化性能

2017-04-11 15:34:41

機票前臺埋點

2025-07-11 09:09:00

點贊
收藏

51CTO技術棧公眾號

精品国产91| 韩国av网站在线| 亚洲影视综合| 国产亚洲精品综合一区91| 色婷婷成人在线| 亚洲91av| 久久精品亚洲一区二区三区浴池 | 黄色美女视频在线观看| 2021中文字幕一区亚洲| 91在线观看免费观看| 可以免费在线观看的av| 国产精品二区不卡| 亚洲裸体xxxx| 9191在线视频| 国产成人免费精品| 欧美日韩激情网| 在线亚洲美日韩| 日本视频在线观看一区二区三区| 国精产品一区一区三区mba桃花| 欧美最猛性xxxx| 久久高清内射无套| 精品日本12videosex| 亚洲第一精品久久忘忧草社区| 一区二区三区 日韩| 久热在线观看视频| 亚洲午夜精品网| 一区二区三区四区久久| 国产黄色免费在线观看| 成人av先锋影音| 91黄在线观看| 91精品人妻一区二区三区果冻| 国产精品入口66mio| 欧美日本高清一区| 青花影视在线观看免费高清| 日韩免费久久| 亚洲一级片在线看| 国产精品无码在线| 亚洲成人偷拍| 欧美一区二区精美| 色噜噜狠狠一区二区| 搜成人激情视频| 色一区在线观看| 亚洲熟妇av日韩熟妇在线| 天堂成人av| 亚洲综合男人的天堂| 中文字幕第一页亚洲| 蜜桃av在线免费观看| 国产精品无人区| 日韩精品大片| 高清在线观看av| 久久精品人人做| 日韩精品无码一区二区三区| 黄色在线小视频| 久久久久久久久久久电影| 欧美日韩在线精品| 国产福利片在线| 欧美激情中文字幕| 一区不卡视频| 巨大荫蒂视频欧美另类大| 亚洲视频资源在线| 免费的一级黄色片| 麻豆成全视频免费观看在线看| 欧美日韩国产色视频| 精品一卡二卡三卡| 午夜av成人| 欧美精品高清视频| 不许穿内裤随时挨c调教h苏绵| 成人性生交大片免费看中文视频| 亚洲经典中文字幕| 亚洲色成人网站www永久四虎| 欧美日韩精品一区二区视频| 日韩一中文字幕| 久久高清无码视频| 午夜亚洲影视| 成人黄色短视频在线观看| aaa一区二区三区| 99视频精品全部免费在线| 欧美日韩在线高清| 高清免费电影在线观看| 亚洲成av人影院| 久久精品免费网站| 久久久久久久久成人| 亚洲第一国产精品| 三级黄色片在线观看| 欧美日韩久久| 国产激情视频一区| 99免费在线视频| 久久这里都是精品| 椎名由奈jux491在线播放| av美女在线观看| 欧美影视一区二区三区| 伊人影院在线观看视频| 狠狠做六月爱婷婷综合aⅴ| 欧美xxxx做受欧美.88| 久久久久久久黄色片| 九色综合狠狠综合久久| 久久国产精品久久| 国产原创视频在线观看| 欧美三级免费观看| 国产成人av免费观看| 国产欧美一区| 久久免费观看视频| 一级特黄aaa大片在线观看| 成人久久久精品乱码一区二区三区 | 中文字幕亚洲在线观看| 国产一区二区三区在线观看视频| 国产精品白嫩白嫩大学美女| 丝袜美腿亚洲综合| 国产欧美日韩亚洲| 成人在线免费看黄| 欧美视频一区二区三区在线观看 | 国产欧美日韩精品高清二区综合区| 久久精品国产亚洲一区二区| 日本中文字幕久久| av一区二区三区黑人| 穿情趣内衣被c到高潮视频| 成人日韩精品| 亚洲精品一区av在线播放| 日本青青草视频| 美女性感视频久久| 欧美一区二区三区四区在线观看地址| 欧美卡一卡二| 欧美一二区视频| av在线免费播放网址| 久久中文在线| 久久天天狠狠| www在线观看黄色| 精品动漫一区二区三区在线观看| 欧美a级片免费看| 青青草成人在线观看| 你懂的网址一区二区三区| bl在线肉h视频大尺度| 精品噜噜噜噜久久久久久久久试看 | 97欧美精品一区二区三区| av中文字幕免费在线观看| 国产精品国产三级国产普通话三级| 男女曰b免费视频| 美日韩中文字幕| 26uuu另类亚洲欧美日本一| 四虎永久在线精品免费网址| 亚洲综合999| 成人啪啪18免费游戏链接| 欧美精品首页| 99久久99久久| 国产乱码在线| 亚洲黄色片网站| 九九热在线免费观看| 91在线播放网址| 黑人糟蹋人妻hd中文字幕| 婷婷精品在线| 国产成人精品在线| 国产大片在线免费观看| 欧美蜜桃一区二区三区| 欧美日韩午夜视频| 粉嫩蜜臀av国产精品网站| 欧美日韩福利在线| 日韩大胆成人| 国产精品va在线播放| 在线免费观看黄| 日韩一区二区在线免费观看| 免费在线视频观看| 99re6这里只有精品视频在线观看| 欧美日韩性生活片| 国内黄色精品| 国产日韩视频在线观看| av激情在线| 亚洲国产精久久久久久| 日本久久综合网| 国产精品国产成人国产三级| 少妇愉情理伦片bd| 亚洲国产一区二区精品专区| 欧美18视频| 2020国产精品小视频| 欧美高清视频一区二区| 日韩大胆视频| 欧美精品第一页| 国产一级片久久| 久久久久九九视频| 伊人成人免费视频| 亚洲一区二区三区免费在线观看| 婷婷四房综合激情五月| 日韩中文字幕无砖| 国产aⅴ夜夜欢一区二区三区 | 国产精品久久精品| 中文字幕在线三区| 日韩精品在线免费观看| 99riav国产| 欧美性少妇18aaaa视频| av成人免费网站| 91丨porny丨首页| 国产欧美激情视频| 欧美亚洲一区| 国产91在线亚洲| 国产精品一区二区中文字幕| 国产精品视频自拍| 免费看男女www网站入口在线| 色婷婷av一区二区三区久久| 天天干天天插天天操| 欧美日本一区二区| 免费观看一区二区三区毛片| 亚洲婷婷综合久久一本伊一区| 日韩精品卡通动漫网站| 国产福利一区二区三区视频在线| 黄色av免费在线播放| 亚洲网站啪啪| 综合网五月天| 精品美女视频| 欧美极品一区| 福利电影一区| 91免费看片在线| 欧美大片1688网站| 51精品在线观看| 福利小视频在线| 久久久999精品免费| 久久天堂电影| 亚洲精品国产精品乱码不99按摩| 99久久精品无免国产免费 | 亚洲成a人片77777精品| 精品视频全国免费看| 国产中文字幕视频| 亚洲va天堂va国产va久| 久久久久久久久97| 亚洲色图一区二区三区| 国产黄色片在线| 国产日韩精品一区二区三区| 三级电影在线看| 菠萝蜜视频在线观看一区| 亚洲精品久久久久久| 国内精品国产成人| 日本中文字幕在线不卡| 久久精品国产77777蜜臀| av网站在线不卡| 喷白浆一区二区| 中文字幕永久视频| 奇米四色…亚洲| 另类小说第一页| 奇米影视在线99精品| 免费看a级黄色片| 日韩中文字幕一区二区三区| 国产免费人做人爱午夜视频| 噜噜噜91成人网| 精品99在线视频| 噜噜噜久久亚洲精品国产品小说| 欧美成人xxxxx| 久久久久国产一区二区| 日日碰狠狠躁久久躁婷婷| 日韩综合一区二区| 99热手机在线| 国产在线一区观看| 1314成人网| 成人国产精品视频| 播金莲一级淫片aaaaaaa| 久久久久国色av免费看影院| 国产又粗又硬视频| 亚洲欧洲成人自拍| 午夜免费激情视频| 亚洲国产精品精华液网站| 日韩欧美视频在线免费观看| 福利一区福利二区微拍刺激| 久久国产乱子伦精品| 欧美日韩一二三| 精品国产亚洲一区二区麻豆| 精品国产三级电影在线观看| 三级理论午夜在线观看| 国产一区二区三区在线观看视频| 黄网页在线观看| 国产+人+亚洲| 亚洲第一会所001| 成人网中文字幕| 牛牛影视一区二区三区免费看| 日本一区二区视频| 欧美69视频| 欧美视频第一区| 精品亚洲欧美一区| 精品视频站长推荐| 国产精品网站在线观看| 中文字幕电影av| 亚洲成av人综合在线观看| 中文资源在线播放| 精品国产免费一区二区三区四区| 美女做暖暖视频免费在线观看全部网址91 | 欧美在线免费| 国产精品视频一区二区三区四区五区| 久久99国产精品免费网站| 影音先锋资源av| 亚洲国产精品v| 久久精品久久国产| 欧美性xxxxx极品少妇| 亚洲精品综合久久| 在线观看国产成人av片| 黄色美女视频在线观看| 成人黄色激情网| 亚洲电影男人天堂| 屁屁影院ccyy国产第一页| 日韩—二三区免费观看av| av不卡中文字幕| 国产精品久久久久久久久免费桃花 | 午夜天堂精品久久久久| 久草综合在线观看| 不卡一区中文字幕| 999精品视频在线观看播放| 欧美三级免费观看| 乱精品一区字幕二区| 色婷婷综合久久久久| 欧美18—19sex性hd| 成人精品一二区| 国产精品成久久久久| 乱子伦视频在线看| 99国产精品国产精品毛片| 91嫩草|国产丨精品入口| 日本高清不卡aⅴ免费网站| 老司机午夜福利视频| 久久成人在线视频| 久久久久黄色| 日本免费一区二区三区| 国产日韩一区二区三区在线| 亚洲 自拍 另类 欧美 丝袜| 国产精品少妇自拍| 久久久久久亚洲av无码专区| 亚洲国产一区二区三区在线观看| 性网站在线观看| 96sao精品视频在线观看| 欧美色女视频| 国产淫片av片久久久久久| 不卡欧美aaaaa| 天堂资源在线播放| 日韩精品专区在线| 91亚洲天堂| 亚洲xxx视频| 亚洲电影影音先锋| 亚洲一级片av| 亚洲日本中文字幕区| 国产又大又粗又长| yellow中文字幕久久| 亚洲精品tv| 五月天综合婷婷| 国产麻豆一精品一av一免费| 夫妻性生活毛片| 欧美一区二区福利在线| free性欧美hd另类精品| 91免费版黄色| 亚洲一级网站| 精品久久久久一区二区| 亚洲大片免费看| 午夜视频在线播放| 欧美资源在线观看| 国产亚洲电影| 第四色婷婷基地| 中文字幕一区二区三区视频| 国产美女免费视频| 欧美另类xxx| 91精品啪在线观看国产手机| 青青青在线视频播放| 99久久久久久| 亚洲高清在线看| 色偷偷88888欧美精品久久久| 蜜桃精品一区二区三区| 大陆av在线播放| 久久嫩草精品久久久精品| wwwwww在线观看| 超在线视频97| 精品伊人久久久| 欧美一级黄色片视频| 中文字幕亚洲综合久久菠萝蜜| 999久久久久| 97视频在线观看播放| 精品av一区二区| 中文字幕亚洲影院| 婷婷综合另类小说色区| 福利视频在线导航| 成人国产1314www色视频| 久久不射网站| 国产美女久久久久久| 亚洲成人xxx| yw.尤物在线精品视频| 久久久99精品视频| 2022国产精品视频| 国产乱码一区二区| 欧美中文字幕在线| 99久久亚洲精品蜜臀| 星空大象在线观看免费播放| 欧美综合视频在线观看| 青春草在线免费视频| 热re99久久精品国产99热| 国产乱对白刺激视频不卡| 免费黄色网址在线| 欧美巨乳在线观看| 欧美特黄一级大片| 日本一级片在线播放| 7777精品伊人久久久大香线蕉完整版| 第一中文字幕在线| 在线观看日韩片| 久久综合色天天久久综合图片| 国产精品视频第一页| 欧美影院久久久| 欧美理论在线| 久久视频一区二区三区| 日韩精品一区二区三区第95| 精品一区二区三区视频在线播放| 精品久久久久久久免费人妻|