久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

WebSocket集群方案詳解:從Sticky Session到MQ推送架構(gòu)的演進(jìn)與實(shí)踐

WebSocket集群方案詳解:從Sticky Session到MQ推送架構(gòu)的演進(jìn)與實(shí)踐 前陣子有個(gè)朋友的公司做在線客服系統(tǒng)單機(jī)跑了一年多相安無(wú)事。結(jié)果有次渠道推廣爆量WebSocket 在線連接數(shù)直接沖上五位數(shù)服務(wù)開始頻繁卡頓、內(nèi)存飆高。他們第一反應(yīng)是加機(jī)器結(jié)果加了機(jī)器不但沒(méi)緩解反而冒出更詭異的 bug用戶明明在線消息卻經(jīng)常推送不到發(fā)一條消息別人要隔好幾秒才收到甚至干脆收不到。問(wèn)題就出在 WebSocket 的本質(zhì)上——它是一條有狀態(tài)的 TCP 長(zhǎng)連接。HTTP 請(qǐng)求處理完就斷開了隨便負(fù)載均衡到哪臺(tái)機(jī)器都行WebSocket 一旦握手成功這個(gè)連接就長(zhǎng)在了某一臺(tái)節(jié)點(diǎn)上后續(xù)所有消息都只能由那臺(tái)節(jié)點(diǎn)轉(zhuǎn)發(fā)。你可以在 Redis 里存用戶的 session 數(shù)據(jù)但沒(méi)法把一條已經(jīng)建立的 TCP 連接瞬移到另一臺(tái)機(jī)器上。這就是所有 WebSocket 集群方案的出發(fā)點(diǎn)。這篇文章我會(huì)從單機(jī)服務(wù)的容量邊界講起再逐步拆解三種主流的集群方案Sticky Session 粘連、Redis Pub/Sub 消息路由、MQ 推送服務(wù)化架構(gòu)最后給出一套可以直接落地的代碼骨架和我在生產(chǎn)環(huán)境踩過(guò)的坑。不管你是做在線客服、消息推送、聊天室還是實(shí)時(shí)協(xié)作這套思路都能直接套用。1. WebSocket 的有狀態(tài)本質(zhì)所有集群麻煩的根源1.1 一條 TCP 長(zhǎng)連接不是一份可以隨意路由的報(bào)文WebSocket 的握手過(guò)程和 HTTP 很像本質(zhì)是借助 HTTP Upgrade 機(jī)制完成協(xié)議升級(jí)GET /ws/chat HTTP/1.1 Host: im.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw Sec-WebSocket-Version: 13關(guān)鍵是這次握手發(fā)生在哪臺(tái)機(jī)器上后續(xù)一整條雙向通道就跟死在哪臺(tái)機(jī)器上。因?yàn)?WebSocket 是長(zhǎng)連接服務(wù)端內(nèi)存里保存著這個(gè)連接的 session 對(duì)象、讀寫緩沖區(qū)、各種狀態(tài)標(biāo)記這些都不是 Redis 里存一個(gè)字符串就能搬走的東西。TCP socket 四元組綁定的是某一臺(tái)機(jī)器的某個(gè)端口數(shù)據(jù)報(bào)文只會(huì)被投遞到那個(gè) socket 上其他節(jié)點(diǎn)根本沒(méi)有這個(gè)連接的任何信息。這就導(dǎo)致了一個(gè)很尷尬的現(xiàn)狀你可以在 Redis 里存用戶的登錄態(tài)沒(méi)法把連接本身同步給所有節(jié)點(diǎn)。負(fù)載均衡可以把 HTTP 請(qǐng)求均勻分發(fā)到每臺(tái)機(jī)器但對(duì) WebSocket 來(lái)說(shuō)連接一旦建立它的歸屬就固定了。1.2 HTTP 無(wú)狀態(tài)與 WebSocket 有狀態(tài)的對(duì)比HTTP 的每個(gè)請(qǐng)求都是獨(dú)立的服務(wù)端處理完就丟不存任何客戶端的狀態(tài)。所以 Nginx 后面掛 10 臺(tái)機(jī)器和掛 1 臺(tái)機(jī)器對(duì)業(yè)務(wù)代碼來(lái)說(shuō)沒(méi)有區(qū)別隨便怎么輪詢都行。WebSocket 完全不同它在一次 TCP 連接上建立了全雙工通道而且這個(gè)通道是長(zhǎng)久的。服務(wù)端必須要記住這個(gè) userId 對(duì)應(yīng)哪個(gè) session這個(gè) session 連在哪個(gè) socket 上否則收到消息不知道往哪里發(fā)。這就是狀態(tài)而狀態(tài)是分布式系統(tǒng)最棘手的敵人。對(duì)比維度HTTP 短連接WebSocket 長(zhǎng)連接連接生命周期請(qǐng)求結(jié)束即斷開一直保持直到雙方關(guān)閉服務(wù)端是否保存連接狀態(tài)一般不保存必須保存 session 引用負(fù)載均衡策略隨便輪詢、隨機(jī)、加權(quán)連接一旦建立就不能遷移故障轉(zhuǎn)移請(qǐng)求重發(fā)即可連接斷開需要客戶端重連集群復(fù)雜度低天然橫向擴(kuò)展高需要額外的路由機(jī)制很多人第一次做 WebSocket 集群時(shí)會(huì)下意識(shí)地按 HTTP 的思路去設(shè)計(jì)前邊掛 Nginx后邊掛一堆應(yīng)用節(jié)點(diǎn)結(jié)果一上線就發(fā)現(xiàn)消息發(fā)不出去然后才開始理解有狀態(tài)意味著什么。1.3 先定義業(yè)務(wù)場(chǎng)景再選后續(xù)方案做技術(shù)選型前我建議先想清楚業(yè)務(wù)場(chǎng)景因?yàn)椴煌膱?chǎng)景對(duì)集群方案的要求差別很大。我見(jiàn)過(guò)最典型的幾類服務(wù)端主動(dòng)推送比如庫(kù)存變動(dòng)通知、訂單狀態(tài)推送數(shù)據(jù)源在服務(wù)端客戶端被動(dòng)接收。這類場(chǎng)景廣播和點(diǎn)對(duì)點(diǎn)都要用但對(duì)消息可靠性要求相對(duì)寬松。在線客服 / IM 聊天消息是雙向的用戶和客服之間的消息要準(zhǔn)確投遞不能丟順序還不能亂。這類場(chǎng)景對(duì)點(diǎn)對(duì)點(diǎn)路由要求很高通常要配套離線消息。聊天室 / 直播彈幕重點(diǎn)是廣播能力一個(gè)房間的消息要推給房間內(nèi)所有人而且量大、實(shí)時(shí)性要求高。這類場(chǎng)景要特別注意廣播風(fēng)暴問(wèn)題。實(shí)時(shí)協(xié)同編輯比如白板、在線文檔消息頻率高、延遲敏感而且要求多端狀態(tài)一致。不同場(chǎng)景決定了你后面是用 Redis Pub/Sub 就夠了還是必須上 MQ甚至需要單獨(dú)做一個(gè)推送網(wǎng)關(guān)。這些決策在單機(jī)階段看不出來(lái)但等到集群階段就全是債。2. 單機(jī)服務(wù)先把容量邊界和連接管理做扎實(shí)2.1 一臺(tái)機(jī)器到底能扛多少連接很多人的第一個(gè)誤區(qū)是WebSocket 很重一臺(tái)機(jī)器扛不了多少連接。其實(shí)恰恰相反WebSocket 的協(xié)議開銷非常小真正吃資源的是每個(gè)連接占用的文件描述符、內(nèi)核 socket 緩沖區(qū)和應(yīng)用層 buffer。Linux 下 WebSocket 服務(wù)底層走的是 epoll 模型百萬(wàn)并發(fā)連接在理論上是可以做到的但實(shí)際業(yè)務(wù)環(huán)境遠(yuǎn)達(dá)不到。我通常這樣估算每個(gè)空閑連接在應(yīng)用層大約占用 20KB50KB 內(nèi)存包括 session 對(duì)象、讀緩沖區(qū)、寫緩沖區(qū)。10 萬(wàn)在線連接大約需要 2GB5GB 內(nèi)存這是純連接的消耗還不算業(yè)務(wù)對(duì)象。CPU 消耗主要來(lái)自心跳包的編解碼和消息的序列化空閑連接幾乎不占 CPU。所以一臺(tái) 8C16G 的機(jī)器跑 5 萬(wàn)在線連接、每秒幾千條消息一般綽綽有余跑到 20 萬(wàn)以上就要認(rèn)真調(diào)優(yōu)了。單機(jī)部署前一定要改幾個(gè) Linux 內(nèi)核參數(shù)這是最容易被忽略的# 調(diào)整文件描述符上限 ulimit -n 1048576 # 內(nèi)核層面提升連接隊(duì)列長(zhǎng)度 net.core.somaxconn 65535 net.ipv4.tcp_max_syn_backlog 65535 # 加大本地端口范圍防止大量短連接耗盡端口 net.ipv4.ip_local_port_range 1024 65535 # 加快 TIME_WAIT 回收 net.ipv4.tcp_fin_timeout 15不調(diào)文件描述符上限的話默認(rèn) 1024 的 ulimit 會(huì)直接卡死在連接數(shù)上業(yè)務(wù)代碼寫得再漂亮也沒(méi)用。2.2 連接管理的核心數(shù)據(jù)結(jié)構(gòu)單機(jī)模式下連接管理的核心就是在內(nèi)存里維護(hù)一張用戶 ID 到 WebSocketSession的映射表。Java 里用 ConcurrentHashMapGo 里用 sync.Map本質(zhì)都一樣Component public class SessionRegistry { // userId - WebSocketSession private final ConcurrentHashMapString, WebSocketSession sessions new ConcurrentHashMap(); public void register(String userId, WebSocketSession session) { sessions.put(userId, session); } public void unregister(String userId) { sessions.remove(userId); } public WebSocketSession get(String userId) { return sessions.get(userId); } public int count() { return sessions.size(); } }注意這里有個(gè)細(xì)節(jié)注冊(cè)的 key 是業(yè)務(wù)用戶 ID不是 session ID。因?yàn)槟愕南⑼哆f是面向用戶的而不是面向連接的。如果同一個(gè)用戶開多個(gè)標(biāo)簽頁(yè)、多臺(tái)設(shè)備那就需要建立 userId 到一組 session 的映射也就是 MapString, Set 廣播給這個(gè)用戶所有端。這個(gè)在 IM 場(chǎng)景下屬于剛需做單機(jī)的時(shí)候就要留好這個(gè)設(shè)計(jì)余地。2.3 心跳與死連接清理單機(jī)模式最容易踩的坑是連接泄漏??蛻舳藬嗑W(wǎng)、拔網(wǎng)線、電腦休眠TCP 層不一定能及時(shí)感知尤其是有中間 NAT 設(shè)備的情況下連接會(huì)一直掛在那里變成半開連接half-open。如果不做處理這些死連接會(huì)一直占著內(nèi)存和文件描述符最終把服務(wù)拖垮。解決方式就是應(yīng)用層心跳。我常用的方案是服務(wù)端每 30 秒下發(fā)一個(gè) Ping 幀客戶端收到后回 Pong 幀服務(wù)端如果連續(xù) 3 次90 秒沒(méi)收到某個(gè)連接的 Pong就判定它已死亡主動(dòng)關(guān)閉并清理 session。public void startHeartbeatCheck() { scheduledExecutor.scheduleAtFixedRate(() - { long now System.currentTimeMillis(); sessionRegistry.getAll().forEach((userId, session) - { long idleTime now - lastPongTime(userId); if (idleTime 90_000) { session.close(CloseStatus.SESSION_NOT_RELIABLE); sessionRegistry.unregister(userId); } else if (idleTime 30_000) { session.sendMessage(new PingMessage()); } }); }, 10, 10, TimeUnit.SECONDS); }這里間隔不是隨便定的。間隔太短比如 5 秒心跳包會(huì)占用大量帶寬和 CPU10 萬(wàn)連接每秒光心跳就是幾萬(wàn)條消息間隔太長(zhǎng)比如 5 分鐘死連接清理不及時(shí)連接數(shù)虛高。30 秒心跳、90 秒判定死亡是我在多個(gè)項(xiàng)目里驗(yàn)證過(guò)比較穩(wěn)的參數(shù)。2.4 單機(jī)模式最常見(jiàn)的坑除了心跳單機(jī)還會(huì)遇到幾個(gè)高頻問(wèn)題Nginx 默認(rèn)超時(shí)如果前面掛了 Nginx 做反向代理默認(rèn) proxy_read_timeout 是 60 秒WebSocket 連接空閑超過(guò) 60 秒就會(huì)被 Nginx 掐斷。解決方式是顯式設(shè)置較大的超時(shí)時(shí)間proxy_read_timeout 3600s。在事件循環(huán)里做阻塞操作很多 WebSocket 框架是基于 Netty 或類似的事件循環(huán)模型如果你在消息處理器里直接調(diào)用遠(yuǎn)程 API、查數(shù)據(jù)庫(kù)會(huì)阻塞事件線程導(dǎo)致整個(gè)服務(wù)吞吐暴跌。正確做法是把耗時(shí)的操作丟到業(yè)務(wù)線程池或者用異步方式處理。單機(jī)依賴單點(diǎn)連接全在一臺(tái)機(jī)器上進(jìn)程崩潰、機(jī)器重啟所有連接瞬間全部斷開。這個(gè)無(wú)解只能靠集群解決。單機(jī)做扎實(shí)的意義在于它幫你把連接管理的細(xì)節(jié)注冊(cè)、心跳、清理、投遞都理清楚了這些邏輯在集群模式下會(huì)被復(fù)用而不會(huì)白白浪費(fèi)。3. 集群第一板斧Sticky Session 粘滯與網(wǎng)關(guān)層配置3.1 ip_hash 與 cookie 粘滯的原理先說(shuō)說(shuō)最簡(jiǎn)單的一種集群思路讓同一個(gè)用戶的連接總是被負(fù)載均衡到同一臺(tái)后端節(jié)點(diǎn)。Nginx 的 ip_hash 算法會(huì)根據(jù)客戶端 IP 做哈希同一個(gè) IP 的請(qǐng)求會(huì)被分配到同一個(gè) upstream 節(jié)點(diǎn)upstream ws_backend { ip_hash; server 192.168.1.10:8080; server 192.168.1.11:8080; server 192.168.1.12:8080; } server { listen 80; location /ws { proxy_pass http://ws_backend; # WebSocket 升級(jí)必需 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; # 長(zhǎng)連接超時(shí)放寬 proxy_read_timeout 3600s; proxy_send_timeout 3600s; } }這樣同一個(gè)客戶端 IP 的所有 WebSocket 連接都會(huì)落在同一臺(tái)節(jié)點(diǎn)上。對(duì)于用戶量不大、節(jié)點(diǎn)不多的場(chǎng)景這個(gè)方案能解決大部分問(wèn)題而且改動(dòng)量最小。還有一個(gè)變體是基于 cookie 的粘滯Nginx 會(huì)下發(fā)一個(gè)帶后端節(jié)點(diǎn)標(biāo)識(shí)的 cookie后續(xù)請(qǐng)求根據(jù) cookie 直接路由到指定節(jié)點(diǎn)。相比之下 cookie 方案比 ip_hash 更精確因?yàn)橥粋€(gè) NAT 后面的多個(gè)用戶 IP 相同ip_hash 會(huì)把他們都砸到同一臺(tái)節(jié)點(diǎn)上而 cookie 方案能區(qū)分開。3.2 粘滯方案的優(yōu)勢(shì)與天花板Sticky Session 的優(yōu)勢(shì)非常明顯零業(yè)務(wù)改造不需要額外引入 Redis 或 MQ連接在哪個(gè)節(jié)點(diǎn)就是哪個(gè)節(jié)點(diǎn)點(diǎn)對(duì)點(diǎn)消息直接查本地 session 表就能發(fā)。但它的天花板也很低節(jié)點(diǎn)故障就是災(zāi)難如果一臺(tái)節(jié)點(diǎn)宕機(jī)粘滯在這臺(tái)機(jī)器上的所有連接全部斷開客戶端需要重新握手但此時(shí) ip_hash 仍然會(huì)把它們路由到同一臺(tái)已經(jīng)宕機(jī)的節(jié)點(diǎn)直到 Nginx 把該節(jié)點(diǎn)摘除。即使摘除了其它節(jié)點(diǎn)上也沒(méi)有這些用戶的 session必須靠客戶端重新注冊(cè)。負(fù)載不均衡某個(gè) IP 段用戶量大時(shí)ip_hash 可能把大量連接堆在同一臺(tái)節(jié)點(diǎn)上其他節(jié)點(diǎn)空閑。這就是加了機(jī)器反而沒(méi)效果的經(jīng)典原因之一。無(wú)法解決廣播問(wèn)題要向所有用戶廣播消息時(shí)需要遍歷所有節(jié)點(diǎn)上的所有連接。粘滯方案里每個(gè)節(jié)點(diǎn)只知道自己本地的連接你仍然需要一套機(jī)制把廣播消息分發(fā)到每個(gè)節(jié)點(diǎn)。所以我的結(jié)論是Sticky Session 只適合作為最小可用集群方案一般在項(xiàng)目初期、用戶量不大、對(duì)可用性要求不高的場(chǎng)景使用。它不能算真正意義上的集群解決方案只能算負(fù)載均衡策略。3.3 網(wǎng)關(guān)層必須處理的細(xì)節(jié)不管用不用粘滯網(wǎng)關(guān)層Nginx的 WebSocket 配置都有幾個(gè)必須處理的細(xì)節(jié)很多人在這里踩坑location /ws { proxy_pass http://ws_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 60s; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_buffer_size 64k; proxy_buffers 8 64k; }幾個(gè)關(guān)鍵點(diǎn)proxy_http_version 1.1必須設(shè)置WebSocket Upgrade 依賴 HTTP/1.1 的持久連接特性。proxy_set_header Upgrade和Connection upgrade是協(xié)議升級(jí)的關(guān)鍵不設(shè)置的話 Nginx 不會(huì)轉(zhuǎn)發(fā) Upgrade 頭WebSocket 握手直接失敗。proxy_read_timeout和proxy_send_timeout必須調(diào)大否則空閑連接會(huì)被 Nginx 掐掉。proxy_buffer_size關(guān)系到 WebSocket 幀的緩沖區(qū)大小如果消息體比較大比如超過(guò) 64KB需要同步調(diào)大 buffer否則會(huì)出現(xiàn)消息截?cái)嗷驁?bào)錯(cuò)。另外如果集群里走的是 HTTP/2要注意 Nginx 對(duì) WebSocket over HTTP/2 的支持在較老版本里不完善生產(chǎn)環(huán)境建議 WebSocket 走獨(dú)立的 HTTP/1.1 監(jiān)聽端口和普通 HTTPS 業(yè)務(wù)分開。4. 集群第二板斧Redis Pub/Sub 做跨節(jié)點(diǎn)消息路由4.1 核心思路本地注冊(cè)表 全局路由表Sticky Session 解決了連接歸屬問(wèn)題但沒(méi)有解決跨節(jié)點(diǎn)消息路由的問(wèn)題。真正通用的做法是引入一層全局路由信息用 Redis 保存用戶 ID 落在哪個(gè)節(jié)點(diǎn)的映射關(guān)系節(jié)點(diǎn)間通過(guò) Redis Pub/Sub 互相通信。這個(gè)方案的核心思路是每個(gè)節(jié)點(diǎn)在本地內(nèi)存維護(hù)自己的 session 注冊(cè)表只保存連到本節(jié)點(diǎn)的連接。每個(gè)節(jié)點(diǎn)啟動(dòng)時(shí)生成一個(gè)全局唯一的 nodeId并把自己注冊(cè)到 Redis。用戶連接建立時(shí)把 userId - nodeId 的映射寫入 Redis并定期續(xù)期。節(jié)點(diǎn)間消息傳遞走 Redis Pub/Sub發(fā)送節(jié)點(diǎn)把消息發(fā)布到指定節(jié)點(diǎn)的頻道目標(biāo)節(jié)點(diǎn)的訂閱者收到后查本地 session 表并推送。這樣每個(gè)節(jié)點(diǎn)都不需要知道其他節(jié)點(diǎn)的完整連接信息只需要知道目標(biāo)用戶在哪臺(tái)節(jié)點(diǎn)剩下的投遞動(dòng)作由目標(biāo)節(jié)點(diǎn)本地完成。Redis 的 key 設(shè)計(jì)我習(xí)慣這么搞ws:user:{userId} - nodeId # 全局路由表TTL 90 秒心跳續(xù)期 ws:nodes - SetnodeId # 存活節(jié)點(diǎn)列表 ws:msg:{nodeId} - 消息 # 點(diǎn)對(duì)點(diǎn)消息頻道發(fā)往指定節(jié)點(diǎn) ws:broadcast - 消息 # 廣播消息頻道所有節(jié)點(diǎn)訂閱每個(gè)節(jié)點(diǎn)訂閱兩個(gè)頻道ws:msg:{自己的nodeId}和ws:broadcast。這樣點(diǎn)對(duì)點(diǎn)和廣播就用一套機(jī)制統(tǒng)一處理了。4.2 點(diǎn)對(duì)點(diǎn)消息的完整鏈路點(diǎn)對(duì)點(diǎn)消息的完整鏈路是這樣的業(yè)務(wù)服務(wù)想給用戶 U 推送一條消息。查詢 Redisws:user:U得到目標(biāo)節(jié)點(diǎn) nodeId。如果 nodeId 就是本節(jié)點(diǎn)直接從本地 session 表查連接并發(fā)送。如果不是本節(jié)點(diǎn)把消息發(fā)布到 Redis 頻道ws:msg:{nodeId}。目標(biāo)節(jié)點(diǎn)的訂閱者收到消息查詢本地 session 表找到連接后發(fā)送。用 Java 偽代碼表示大概是這個(gè)樣子public void sendToUser(String userId, String payload) { String nodeId stringRedisTemplate.opsForValue().get(ws:user: userId); if (nodeId null) { // 用戶不在線走離線消息邏輯 handleOfflineMessage(userId, payload); return; } if (nodeId.equals(localNodeId)) { // 本節(jié)點(diǎn)直接投遞 WebSocketSession session sessionRegistry.get(userId); if (session ! null session.isOpen()) { session.sendMessage(new TextMessage(payload)); } } else { // 跨節(jié)點(diǎn)路由發(fā)布到目標(biāo)節(jié)點(diǎn)頻道 WsRouteMessage routeMsg new WsRouteMessage(userId, payload); stringRedisTemplate.convertAndSend(ws:msg: nodeId, routeMsg.toJson()); } }訂閱端統(tǒng)一處理Component public class WsMessageSubscriber extends AbstractMessageListener { Override public void onMessage(Message message, byte[] pattern) { WsRouteMessage msg JSON.parseObject(message.getBody(), WsRouteMessage.class); if (msg.isBroadcast()) { // 廣播消息遍歷本地所有連接發(fā)送 sessionRegistry.getAll().forEach((userId, session) - { if (session.isOpen()) { session.sendMessage(new TextMessage(msg.getPayload())); } }); return; } // 點(diǎn)對(duì)點(diǎn)消息查本地 session WebSocketSession session sessionRegistry.get(msg.getTargetUserId()); if (session ! null session.isOpen()) { session.sendMessage(new TextMessage(msg.getPayload())); } } }這套機(jī)制的核心好處是每個(gè)節(jié)點(diǎn)只保存自己的連接路由信息收斂到 Redis 里節(jié)點(diǎn)可以隨時(shí)水平擴(kuò)展新節(jié)點(diǎn)上線只需要訂閱自己的頻道即可。4.3 廣播消息的完整鏈路廣播消息的處理比點(diǎn)對(duì)點(diǎn)簡(jiǎn)單發(fā)送方直接往ws:broadcast頻道發(fā)布消息所有節(jié)點(diǎn)訂閱后各自往本地連接推送。但這里有一個(gè)隱蔽的問(wèn)題如果廣播的接收者是某個(gè)聊天室的所有人而不是所有在線用戶那么每個(gè)節(jié)點(diǎn)在收到廣播后還需要判斷哪些本地連接屬于這個(gè)聊天室。這就需要在本地 session 表之外再維護(hù)一個(gè)聊天室 - 成員連接的映射表。// 房間 - userIds private final ConcurrentHashMapString, SetString roomMembers new ConcurrentHashMap();連接建立時(shí)根據(jù)客戶端帶上來(lái)的參數(shù)比如 URL query 里的 roomId把 userId 加入對(duì)應(yīng)房間連接銷毀時(shí)從所有房間移出。廣播給房間時(shí)節(jié)點(diǎn)拿到房間成員列表再逐個(gè)查 session 表發(fā)送。這樣廣播的范圍就被限制在目標(biāo)房間內(nèi)而不是全量廣播。4.4 Redis Pub/Sub 的邊界消息丟失與不可回溯Redis Pub/Sub 有個(gè)非常重要的特性消息不持久化。發(fā)布者把消息發(fā)出去如果此時(shí)某個(gè)訂閱者恰好不在線節(jié)點(diǎn)宕機(jī)、網(wǎng)絡(luò)抖動(dòng)這條消息就永久丟失了。Redis 不會(huì)像 MQ 那樣幫你把消息存起來(lái)等消費(fèi)者恢復(fù)后再投遞。所以 Redis Pub/Sub 方案只適用于消息實(shí)時(shí)投遞、丟了也無(wú)所謂或可以從業(yè)務(wù)側(cè)補(bǔ)償?shù)膱?chǎng)景。比如在線狀態(tài)推送、心跳類通知、彈幕這類實(shí)時(shí)性消息。如果消息不能丟——比如聊天記錄、訂單通知——就必須在業(yè)務(wù)層做持久化和補(bǔ)償或者直接換用 MQ 方案。另外Redis Pub/Sub 的廣播是 push 模型如果某個(gè)節(jié)點(diǎn)處理消息過(guò)慢會(huì)導(dǎo)致該節(jié)點(diǎn)的訂閱者積壓甚至斷連。如果消息量非常大建議結(jié)合以下做法把廣播消息按業(yè)務(wù)維度切分到多個(gè) channel比如ws:broadcast:room:{roomId}只有需要接收的節(jié)點(diǎn)才訂閱減少無(wú)效消息傳輸。在節(jié)點(diǎn)本地用隊(duì)列緩沖收到的消息再由獨(dú)立線程池發(fā)送避免阻塞 Redis 訂閱線程。這個(gè)是生產(chǎn)環(huán)境很重要的優(yōu)化點(diǎn)后面踩坑部分會(huì)細(xì)說(shuō)。5. 集群第三板斧消息隊(duì)列與推送服務(wù)化架構(gòu)5.1 什么時(shí)候必須上 MQRedis Pub/Sub 有消息丟失的硬傷對(duì)于 IM、客服系統(tǒng)、交易通知這類要求不丟消息的場(chǎng)景就需要引入消息隊(duì)列RabbitMQ、Kafka、RocketMQ 等。我判斷是否需要上 MQ 的幾條標(biāo)準(zhǔn)消息不能丟比如用戶聊天記錄、支付結(jié)果通知丟失會(huì)引發(fā)資損或客訴。需要削峰填谷比如秒殺場(chǎng)景服務(wù)端瞬間產(chǎn)生大量推送消息直接打到 WebSocket 連接上會(huì)把節(jié)點(diǎn)打掛MQ 可以做流量緩沖。需要離線消息用戶不在線時(shí)消息要持久化等用戶上線后再補(bǔ)推。需要消息有序性IM 場(chǎng)景里同一個(gè)聊天窗口的消息必須有序Redis Pub/Sub 做不到精細(xì)化的順序保證而 MQ 可以按 key 分區(qū)保證局部有序。5.2 事件驅(qū)動(dòng)設(shè)計(jì)引入 MQ 之后架構(gòu)從節(jié)點(diǎn)間互相路由演進(jìn)成事件驅(qū)動(dòng) 獨(dú)立的推送層。整個(gè)鏈路變成業(yè)務(wù)服務(wù) --生產(chǎn)-- MQ Exchange --路由-- Queue --消費(fèi)-- WebSocket 節(jié)點(diǎn) --推送-- 客戶端業(yè)務(wù)服務(wù)不再直接關(guān)心目標(biāo)用戶在哪個(gè)節(jié)點(diǎn)它只需要把消息投遞到 MQ 對(duì)應(yīng)的隊(duì)列。WebSocket 節(jié)點(diǎn)作為消費(fèi)者監(jiān)聽隊(duì)列拿到消息后查本地 session 表并推送。這個(gè)設(shè)計(jì)最大的好處是業(yè)務(wù)邏輯和連接管理徹底解耦。訂單服務(wù)不需要關(guān)心用戶當(dāng)前連在哪臺(tái)機(jī)器上它只管發(fā)消息WebSocket 節(jié)點(diǎn)只管消費(fèi)和推送。節(jié)點(diǎn)可以隨時(shí)擴(kuò)縮容對(duì)業(yè)務(wù)方完全透明。從 Redis Pub/Sub 遷移到 MQ 時(shí)之前那套路由表依然有用——節(jié)點(diǎn)消費(fèi)到消息后仍然需要查ws:user:{userId}判斷目標(biāo)用戶是否在本節(jié)點(diǎn)。不過(guò)這里有個(gè)優(yōu)化點(diǎn)可以讓 MQ 按目標(biāo)節(jié)點(diǎn)做分區(qū)比如把消息路由到指定節(jié)點(diǎn)的專用隊(duì)列這樣每個(gè)節(jié)點(diǎn)只消費(fèi)自己需要處理的消息減少無(wú)效消費(fèi)。5.3 離線消息與消息補(bǔ)償有了 MQ離線消息就好處理了。用戶不在線時(shí)消息先落庫(kù)或者存儲(chǔ)在 Redis 里用戶重新建立 WebSocket 連接后服務(wù)端從存儲(chǔ)中拉取該用戶的離線消息補(bǔ)推。這里有一個(gè)我趟過(guò)的坑離線消息的補(bǔ)推不能一股腦全推。用戶斷線十分鐘可能積壓幾百條消息一次性推過(guò)去不僅客戶端渲染卡頓還會(huì)觸發(fā)大量 ACK 回執(zhí)反而把剛剛恢復(fù)的連接打掛。正確做法是分批補(bǔ)推比如每次推 20 條等客戶端確認(rèn)后再推下一批。另外消息補(bǔ)償機(jī)制要考慮冪等。客戶端收到消息后可能會(huì)回執(zhí)服務(wù)端重推時(shí)要有去重邏輯否則用戶會(huì)看到重復(fù)消息。通常用消息 ID 做冪等鍵客戶端按 ID 去重服務(wù)端按 ID 記錄已推送游標(biāo)。MQ 方案也有新的問(wèn)題要處理消費(fèi)者宕機(jī)恢復(fù)后從哪個(gè) offset 開始消費(fèi)超時(shí)未 ACK 的消息是否會(huì)重復(fù)投遞這些屬于 MQ 使用的基礎(chǔ)問(wèn)題這里不展開但一定要在設(shè)計(jì)方案時(shí)提前想好。6. 實(shí)戰(zhàn)拆解一套可落地的 WebSocket 集群骨架6.1 整體架構(gòu)布局把前面的方案結(jié)合起來(lái)一套比較完整的 WebSocket 集群架構(gòu)長(zhǎng)這樣接入層Nginx / SLB 做負(fù)載均衡不配置粘滯WebSocket 握手隨機(jī)分發(fā)到任意節(jié)點(diǎn)。因?yàn)橐肼酚蓪雍筮B接落在哪臺(tái)節(jié)點(diǎn)已經(jīng)無(wú)所謂了。連接層N 個(gè) WebSocket 應(yīng)用節(jié)點(diǎn)每個(gè)節(jié)點(diǎn)維護(hù)自己的本地 session 表并注冊(cè)到 Redis。路由層Redis 保存 userId - nodeId 映射節(jié)點(diǎn)間通過(guò) Pub/Sub 通信。消息層RabbitMQ 承擔(dān)可靠消息投遞業(yè)務(wù)系統(tǒng)通過(guò) MQ 解耦。存儲(chǔ)層MySQL 存聊天記錄等需要持久化的數(shù)據(jù)Redis 同時(shí)承擔(dān)路由表和熱數(shù)據(jù)緩存。這個(gè)架構(gòu)的好處是每一層都可以獨(dú)立擴(kuò)展連接多了加 WebSocket 節(jié)點(diǎn)消息量大了擴(kuò) MQ 分區(qū)路由表性能不夠就升級(jí) Redis 集群。6.2 連接注冊(cè)與注銷流程連接建立時(shí)的完整流程客戶端發(fā)起 WebSocket 握手Nginx 轉(zhuǎn)發(fā)到任意一個(gè)應(yīng)用節(jié)點(diǎn)。節(jié)點(diǎn)在 onOpen 回調(diào)里拿到 userId從 token 或 URL 參數(shù)解析。把 WebSocketSession 注冊(cè)到本地 session 表。把ws:user:{userId}寫入 Redis值為當(dāng)前節(jié)點(diǎn) nodeIdTTL 90 秒。開啟該連接的心跳監(jiān)控。連接斷開時(shí)的清理流程客戶端主動(dòng)關(guān)閉或心跳超時(shí)判定死亡后觸發(fā) onClose 回調(diào)。從本地 session 表移除該 userId。刪除 Redis 里的ws:user:{userId}先比對(duì) nodeId 是否為本節(jié)點(diǎn)防止誤刪。從所有房間成員表里移除該 userId。把離線消息標(biāo)記為待補(bǔ)推狀態(tài)。這里有個(gè)細(xì)節(jié)刪除 Redis 路由表時(shí)要帶上 nodeId 做條件刪除。因?yàn)榭赡苡脩魟倲嗑€又在新節(jié)點(diǎn)上建立了新連接并寫入了新的路由表此時(shí)舊節(jié)點(diǎn)如果直接 del會(huì)把新路由信息也刪掉導(dǎo)致消息路由失敗。用 Lua 腳本或者 compare-and-delete 都能解決。6.3 節(jié)點(diǎn)上下線與故障轉(zhuǎn)移節(jié)點(diǎn)的健康檢查一般在 Redis 里做每個(gè)節(jié)點(diǎn)啟動(dòng)時(shí)把自己的 nodeId 寫進(jìn)一個(gè)有序集合并周期性地更新心跳時(shí)間戳// 節(jié)點(diǎn)心跳上報(bào)每 30 秒一次 stringRedisTemplate.opsForZSet().add( ws:nodes, localNodeId, System.currentTimeMillis() );其他節(jié)點(diǎn)或監(jiān)控服務(wù)定期掃描這個(gè)有序集合把心跳時(shí)間超過(guò) 90 秒的 nodeId 判定為宕機(jī)節(jié)點(diǎn)從集合里移除并幫他做善后工作廣播節(jié)點(diǎn) xxx 已下線的通知各節(jié)點(diǎn)清理本地可能存在的該節(jié)點(diǎn)的關(guān)聯(lián)信息。該節(jié)點(diǎn)持有的所有用戶連接被動(dòng)斷開客戶端通過(guò)重連機(jī)制落到其他節(jié)點(diǎn)。如有必要從存儲(chǔ)層拉取這些用戶的會(huì)話狀態(tài)重新路由。節(jié)點(diǎn)故障時(shí)客戶端重連是不可避免的但一定要做重連保護(hù)否則會(huì)觸發(fā)重連風(fēng)暴。我常用的策略是指數(shù)退避 隨機(jī)抖動(dòng)。客戶端第一次重連等 1 秒之后 2 秒、4 秒、8 秒……最大 30 秒封頂每次重連時(shí)間加一個(gè) 030% 的隨機(jī)抖動(dòng)避免所有客戶端同時(shí)重連壓垮網(wǎng)關(guān)。6.4 關(guān)鍵代碼骨架最后給一個(gè)完整的 WebSocket 連接注冊(cè) 跨節(jié)點(diǎn)路由的最小骨架基于 Spring Boot 和 RedisServerEndpoint(/ws/{userId}) Component public class WsEndpoint { OnOpen public void onOpen(Session session, PathParam(userId) String userId) { // 1. 本地注冊(cè) SessionRegistry.register(userId, session); // 2. 全局路由表注冊(cè)TTL 90s心跳續(xù)期 RedisUtil.set(ws:user: userId, LocalNode.getNodeId(), 90); // 3. 訂閱當(dāng)前節(jié)點(diǎn)的消息頻道只訂閱一次 RedisSubscriber.subscribe(ws:msg: LocalNode.getNodeId()); // 4. 啟動(dòng)心跳任務(wù) HeartbeatManager.start(session, userId); } OnClose public void onClose(PathParam(userId) String userId) { SessionRegistry.unregister(userId); RedisUtil.compareAndDelete(ws:user: userId, LocalNode.getNodeId()); RoomManager.removeFromAllRooms(userId); } OnMessage public void onMessage(String message, PathParam(userId) String userId) { // 業(yè)務(wù)消息處理投遞到 MQ 或直接路由 ChatService.handleUserMessage(userId, message); } OnError public void onError(Session session, Throwable error) { // 記錄日志連接由心跳機(jī)制兜底清理 log.error(ws error, error); } }消息路由服務(wù)Service public class MessageRouter { public void sendToUser(String userId, String payload) { String targetNode RedisUtil.get(ws:user: userId); if (targetNode null) { offlineMessageStore.save(userId, payload); return; } if (targetNode.equals(LocalNode.getNodeId())) { SessionRegistry.sendToUser(userId, payload); } else { RedisUtil.publish(ws:msg: targetNode, payload); } } public void broadcastToRoom(String roomId, String payload) { RedisUtil.publish(ws:broadcast:room: roomId, payload); } }這套骨架可以直接跑通單機(jī)和集群兩種模式單機(jī)運(yùn)行時(shí)所有連接都注冊(cè)到唯一的節(jié)點(diǎn)上sendToUser 直接走本地發(fā)送集群運(yùn)行時(shí)靠 Redis 路由表自動(dòng)切換到跨節(jié)點(diǎn)發(fā)布。業(yè)務(wù)層幾乎不需要改動(dòng)。7. 生產(chǎn)環(huán)境踩坑記心跳、連接泄漏與廣播風(fēng)暴7.1 心跳間隔不當(dāng)引發(fā)的雪崩重連有次我在壓測(cè)環(huán)境發(fā)現(xiàn)一個(gè)詭異現(xiàn)象在線連接數(shù)穩(wěn)定在 5 萬(wàn)左右但每分鐘都有大量連接斷開重連服務(wù)端日志里全是session closed和new connection。排查了很久才發(fā)現(xiàn)問(wèn)題出在心跳參數(shù)上。當(dāng)時(shí)的配置是 10 秒發(fā)一次 Ping、30 秒判定死亡但網(wǎng)關(guān)層 Nginx 的超時(shí)設(shè)置只有 20 秒。Nginx 在超過(guò) 20 秒沒(méi)有收到任何數(shù)據(jù)時(shí)會(huì)主動(dòng)關(guān)閉連接而服務(wù)端的心跳判定周期是 30 秒導(dǎo)致 Nginx 先于服務(wù)端把空閑連接關(guān)掉了。客戶端發(fā)現(xiàn)連接斷開后立刻重連重連風(fēng)暴把負(fù)載打得很高。這個(gè)問(wèn)題的根源是網(wǎng)關(guān)超時(shí)和心跳周期不匹配。后來(lái)我把整套鏈路的心跳節(jié)奏統(tǒng)一了應(yīng)用層 30 秒發(fā)心跳Nginx 超時(shí) 3600 秒服務(wù)端 90 秒判定死亡。至此再?zèng)]出現(xiàn)過(guò)莫名重連。教訓(xùn)很簡(jiǎn)單心跳不是一個(gè)應(yīng)用層參數(shù)而是一條完整鏈路上的協(xié)作參數(shù)??蛻舳?、網(wǎng)關(guān)、應(yīng)用節(jié)點(diǎn)、Redis TTL 四者的超時(shí)時(shí)間必須按防火墻 Nginx 應(yīng)用判定死亡 心跳間隔的層級(jí)關(guān)系設(shè)置好任何一環(huán)不匹配都會(huì)出怪問(wèn)題。7.2 連接泄漏只會(huì)讀不會(huì)關(guān)的客戶端怎么處理還有一次線上問(wèn)題讓我印象很深某個(gè)老版本的 App 客戶端在弱網(wǎng)環(huán)境下不會(huì)正常發(fā)送關(guān)閉幀也不會(huì)響應(yīng) Pong。TCP 連接半死不活服務(wù)端檢測(cè)不到異常連接數(shù)一直漲最終內(nèi)存被打滿。應(yīng)用層心跳只能發(fā)現(xiàn)不響應(yīng) Pong的連接但如果你只是每 30 秒發(fā)一次 Ping且客戶端永遠(yuǎn)不會(huì)回 Pong那你最早也要等 90 秒才能清理掉它。如果 QPS 很高90 秒就能積累大量死連接。后來(lái)我做了兩個(gè)優(yōu)化在心跳檢測(cè)時(shí)除了發(fā) Ping還會(huì)檢查連接最近一次收到任何幀的時(shí)間。只要客戶端還在 TCP 層傳輸數(shù)據(jù)哪怕是垃圾幀就把它標(biāo)記為活躍超過(guò) 90 秒沒(méi)有任何數(shù)據(jù)到達(dá)的直接強(qiáng)殺。對(duì)客戶端主動(dòng)斷開但 TCP 層沒(méi)有 FIN 的情況依賴內(nèi)核的 keepalive 來(lái)做最后兜底應(yīng)用層只負(fù)責(zé)更快的檢測(cè)。另外我要強(qiáng)調(diào)一點(diǎn)清理死連接時(shí)一定要在 finally 塊里執(zhí)行 unregister。否則連接關(guān)閉異常會(huì)導(dǎo)致 session 殘留在注冊(cè)表里造成幽靈連接這是連接泄漏最隱蔽的形態(tài)。7.3 廣播風(fēng)暴與消息重復(fù)最后一個(gè)坑來(lái)自廣播場(chǎng)景。做直播彈幕時(shí)一開始廣播消息直接走ws:broadcast全局頻道所有節(jié)點(diǎn)收到后向本地所有連接推送。等房間人數(shù)上到幾千問(wèn)題就爆發(fā)了每個(gè)節(jié)點(diǎn)推送隊(duì)列積壓Redis 訂閱線程卡死消息延遲從毫秒級(jí)飆升到秒級(jí)。問(wèn)題本質(zhì)是廣播范圍沒(méi)有做細(xì)粒度控制。全局廣播頻道會(huì)讓每個(gè)節(jié)點(diǎn)都收到所有消息但一個(gè)彈幕只屬于一個(gè)房間節(jié)點(diǎn)收到后還要去查這個(gè)房間里有哪些本地連接大部分查詢都是空轉(zhuǎn)。我把廣播頻道從全局切到了房間維度ws:broadcast:room:{roomId}節(jié)點(diǎn)按需訂閱用戶所在房間的頻道。在此基礎(chǔ)上發(fā)送線程也從 Redis 訂閱線程里拆了出來(lái)訂閱線程收到消息后只負(fù)責(zé)放進(jìn)本地隊(duì)列由獨(dú)立的發(fā)送線程池消費(fèi)并推送給客戶端。這樣即使某個(gè)房間的消息量特別大影響的也只是這個(gè)房間的發(fā)送線程不會(huì)拖垮整個(gè)節(jié)點(diǎn)。消息重復(fù)的問(wèn)題也值得一提。Redis Pub/Sub 本身不會(huì)重復(fù)投遞但引入 MQ 后消費(fèi)者如果在發(fā)送推送后、ACK 之前宕機(jī)重啟后會(huì)重新消費(fèi)這條消息導(dǎo)致用戶收到重復(fù)推送。解決方式是給每條消息生成唯一 ID節(jié)點(diǎn)在本地維護(hù)一個(gè)最近處理過(guò)的消息 ID 緩存收到重復(fù) ID 直接丟棄。緩存窗口不用太長(zhǎng)30 秒即可因?yàn)?MQ 的重復(fù)消費(fèi)通常發(fā)生在很短時(shí)間內(nèi)。做 WebSocket 集群這幾年我最大的體會(huì)是不要一上來(lái)就追求最復(fù)雜的架構(gòu)。單機(jī)能把連接管理、心跳、推送這些基本功做扎實(shí)是比上來(lái)就上分布式更重要的能力。集群方案的選擇也遵循這個(gè)原則——用戶量上來(lái)了先做 Sticky Session 頂一陣遇到跨節(jié)點(diǎn)路由需求了再加 Redis Pub/Sub消息可靠性要求高了再引入 MQ 和服務(wù)化改造。每一層方案都解決上一層的痛點(diǎn)但也會(huì)引入新的復(fù)雜度只有在真正需要的時(shí)候才值得接住這份復(fù)雜度。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
东京热av男人的天堂| 中文字幕乱在线伦视频中文字幕乱码在线 | 日韩无码三级影院| 欧美色另类| 人妻一二三区| 午夜精品久久久久久久99热影院| 超碰在线91| 黄色无码高清黄色无码网站| 国产黄片在线免费观看| 亚洲少妇色| 欧美—性—交—色| 五月天开心网| 亚洲无 码A片在线观看麻豆| 大香蕉手机在线视频| 午夜精品人妻二区三区| 麻豆国产精品午夜视频| 操美女高潮抽搐白浆| 麻豆九九九| 丰满人妻一区二区三区免费| 久久无码电影| 日韩欧美久久婷婷网站| 国产熟女完整版中字| 欧美亚洲日韩16色| 亚洲国产ⅴ高清在线观看| 久久99国产综合精品女同| yazhououmeizongya| 婷婷精品视频| 日韩无码一级黄色av片| 亚洲宗合电影| 久久亚洲AV无码专区首页| 久久是精品| 性生活无遮挡纯毛片在线看| 涩涩五月天| 欧美性爱1080p| 欧美高清色| 亚洲欧美综合网站| 国产1727欧美| 国产精品一区二区后入| 超碰 av 女人天堂| 日日干男人的天堂| 国偷自 一区二区| 亚洲视频,小说| 亚州操操穴网| 发朗少妇买婬全视频中文| 播播亚洲小说亚洲| 曰韩无码777| 无码乱人伦中文视频| 家庭乱伦国产精品| 欧美黄色手机在线观看| 欧美福利视频啊啊啊啊| 成人开心网在线视频| 美女骚尻视频| 97超碰香蕉| 国产AV中文| 后入式福利| 尤物视频网 刘玥| 日韩美女,国产传媒,视频一区| 亚洲 欧美都市激情| 超碰亚洲欧美日韩无| av中文在线| 涩五月婷婷| 男人兔费天堂| 中文字幕-区二区三区四区视频中国| 久久黄色网址| 日韩欧美被操黄免费观看| 国产精品视频播放| 久草精品一区| 外国免费性情大片| 国产在线播放成人免费| 午夜电影在线观看无码专区| 大香蕉综合在线| 亚洲色欲天天人妻无码系列专区| 婷婷五月天网| 国产一区麻豆免费观看| 伊人视频| 少妇高潮九九九九| 一类无码操逼视频| 高清无码一区二区三区| 亚洲欧美成人在线| 国产熟女| 啊啊啊啊嗯嗯在线久久久| 久久久日本电影| TS人妖另类精品视频系列| 日产操逼| 日本东京热加勒比久久| 丁香五月综合| 动漫av中文| 亚洲网污污污污| 无套后入双马尾| 秋霞色色影院| 99热9| 9/A片 | 欧美老妇女内射网址| 97超碰久久色| 99re这里只有精品2| 色妺妺AⅤ| 操逼www.| 亚洲AV无码久久精品蜜桃小说| www.成人无码| 久干9操| 日本天天吊| Aa东京男人的天堂| 亚洲精品自拍| 人人爱人人操人人性| 五月婷婷六月激情| 熟女91网站| 大香蕉视频一二三区| 9色在线| 色综合久久夜色精品国产天堂| 欧美姓爱综合网| 奇米四色影视777久久久| 久久人妻视频| 欧美综合1性辶| 91网九色蝌蚪操熟女| 92人人操人人| 欧美资源| 一区二区偷拍拍视频| 男人的天堂久久狠| 伊人久久在线视频观看| 少妇69中文| 人妻丝袜美腿中文字幕| 欧美99热| 亚洲999综合| 超碰97人人cao| 午夜福利免费福利视频| 美女诱惑在线一区| 人妻 丝袜美腿 中文字幕| 爱爱60秒免费视频| 天天cao在线| 99久久久er直播网址| 岛国AV一区二区电影| 校园春色美腿丝袜 | 国产18精品亚洲精品| 东北女人的毛片| 日日骚中文字幕| 欧日a| 夜夜嗷嗷一区二区| 美国aaaaa一级黄片| 一区二区三区蜜桃成人撸久久东京热| 亚洲欧美在线观看无码| 天天内射| 中文字幕aⅴ在线视频| 青青草日本中文字幕| 98人妻精品一区二区色欲| 天天操夜夜操| 欧美热图99| 韩国一级婬片A片AAAAA| 成人五月天丁香激情综合| 可以免费观看的av| 九九九九精品视频| 久久一二三级一一一| 大香蕉欧美| 亚洲成人av色网| 777超碰| 亚洲AV操| 蜜臀久久99精品久久久久久-DVD| 成人女人国产| 国产剧情AV不卡在线观看| 亚欧洲一区二区视频| 404操逼福利视频| 亚洲男人天堂视频| 日韩成人色图| 成人日韩3| 91国精产品| 国产福利av精彩对白| 夜夜高潮夜夜爽夜夜爱爱一区| 五月综合色| 精品久久久久久久| 欧美999999| 国产精品爽爽va在线观看98| 老熟女阿 国产91| 青青草在线成人视频| 情趣丝袜无码操逼视频| 午夜在线播放| 97超碰天天爱天天爱| 免费A片三p视频| 97国产精品在线观看| 丰满人妻-区二区三区免费| 久草成人影片| 久久AV无码1区2区3区| 国产一区二区精品久久99| 天堂网亚洲区手机版| 一区久久久二区| 亚洲国产欧美另类自拍| 亚洲欧美另类激情小说| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | www.高清无码诱惑一区.com | 在线中文字幕极品av| 欧美丝袜中文字幕07在线| 青青草伊人久久| 波多野42部无码喷潮在线观看| 欧洲精品人妻| 丰满少妇一区二区三区专区| 96AV精品| 中文字幕av乱伦| 人妻少妇久久中文字幕一区二区 麻豆| 成人在线视频一区| 欧美日动态视频| 九一综合精品视品av| 图片区小说区| 啪啪视频亚洲第一| 网站A V在线| 无码九九九九| 91久久国产综合精品| 久久超碰爱| 国产免费永久精品无码| 嫩草影院在线观看精品| 无码逼| 色哟哟AⅤ| 亚州性9| 极品人妻少妇综合| 夜夜骑日日| 久久久专区| 久久激情综合| 国产精品老师| 日韩去日本高清在| 防屏蔽在线视频| 色色婷婷五月天| 婷婷色综合| 丁香五月天视频| 亚洲 日本 一 二 三| 欧美99热| 国产乱伦性爱AV| 操我无码| 国模精品娜娜一二三区| 91狠狠综合久久| 嗯嗯嗯啊啊啊在线免费观看| 久久人人爽爽爽人久久久| 日韩一级二级在线| 国产视频大全| 欧美天堂在线| 百度百度日本操逼| 国产精品黄色三级av| 午夜精品五区| 久久久久久中文字幕中文字幕最新| 国产白领连续中出在线观看| 好舒服视频| 青青草AV色| 久久久女人| 日本久久女同性恋视频| 岛园激情| 亚洲欧洲无码97久久精品| 激情黄色五月天| 欧美热图99| 超碰97护士| 天天日天天搞天天干| 免费操逼视频下载| 天天综合网91入口| 欧美美逼| 免费观看国产不卡av| 97碰在线视频| AV丝袜少妇| 少妇大屁屁| 久操操AV电影| 五月激情视频| 日韩色图 一区二区| 97AV在线观看| 欧美丰满熟妇XXXX性ppX人交| 日韩精品区二区三区不卡| 亚洲吊色| 国产又黄又爽| 亚洲av乱伦色图网站| 欧美日韩国产中文精品字幕自在自线,| 午夜精品久久久久久久99热影院| 在线天堂资源亚洲| 日va操| 超碰精品| 日本操逼无码| 久热99| 好吊爽好吊爽在线视频,中文字幕精品一区二区日本,国产良妇出轨视频在线观看, | 天天综合网国产| 91精产一区二区三区| 亚洲精品久久久久久久蜜桃臀| 国产中文大片资源中文字幕| 婷婷情色综合网| 青操影院| 亚洲黄色a级片| 欧美曰韩国产精品| 自拍偷拍第26| 中文字幕天天天天天| 神马午夜久久| av天堂影视中文在字幕在线中文| 亚州五月| 91黑人无码激情在线| 美骚妇av高清在线| 2018天天干在线视频| 熟女日韩| 超碰97久久| 熟女丰满人妻一区| 熟妇熟女一区二区三区| 屌逼麻豆| 国产精品com| 美女刺激久久国产欧美| 欧美天天综合在线| 日本熟妇一区二区三区| 屁股久久久久久| 亚洲欧美成人在线| 婷婷丁香人妻| 精品人妻夜夜草| 老司机深夜18禁污污网站| 中文字幕一区二区三区人妻少妇在线| 啪啪啪综合网| 欧美在线色图| 国产传媒午夜理伦精品| 青青草久草AV| 欧美v亚洲v日韩v最新在线二区| 97精品网站| 丰满人妻大屁一区二区| 天天综合91入口| 成功精品影院| heyZO天然素人无码AⅤ专区| 九九热在线精品视频| 最新无码国产| 伊人991| 自拍偷拍2025在线观看| 美女啊啊啊啊啊啊| 亚洲情色图片区| 久久精品店| 99在线精品观看视频中文 | 伊人操| 啊啊啊在线观看免费视频| 欧美一区二区福利在线| 亚洲综合射| 牛牛aV| 天美传媒精品一区二区| 天天操人人操骚逼网站| 日韩去日本高清在| 亚洲全色网| 91九九九逼| 亚洲色图欧美视频| 国产乱伦性爱区| 无卡一区=区| 久久男人的天堂国产| 精品蜜乳AV免费观看| 1204金沙人妻懂旧版免费| 精品毛片久久久精品毛片| 大香蕉中文在线| 亚洲欧洲无码97久久精品| 亚洲欧美日韩精品久| 精品久久97观看在线视频| 亚洲欧美日韩有码| 中文字幕 国产 精品| 激情小说亚洲| 欧美在线|亚洲| 国语人妻精彩刺激| 欧美色综合影院| 污色区网站| 精品制服美女中文一区二区三区| 精品人妻一区二区免费蜜桃| 五月丁香六月激情| AV无码久久久精品| 99亚洲精品| 亚洲色图欧美色18直播在线| 性九九九九九九| 91人妻丝袜无码| 欧洲熟妇xxXx欧美老妇裸体| 欧美精品一区二区少妇免费A片 | 欧美 亚洲 综合 制服| 国产精品嫩草影院免费| 男女做爰猛烈动高潮A片免费应用 少妇厨房愉情理伦片bd在线观看 不卡中文字幕aⅴ在线 | 欧美激情视频在线一区| 少妇综合| 中文字幕99999| 欧美综合色综合| 日夜干射色啊| 大香蕉欧美伊| 中文字幕少妇色| 日韩AV一区二区三区四四| 91精品伊人久久久大香线蕉91| 日欧操屄| 国内精品a| 久久专区| 婷婷伊人五月| 欧美一级黄色免费专区| aaa亚无码专区| 久操97| 色香av| 600国产精品视频| 一本一道久久综合久久| 9美女超碰在线免费观看| 99国内熟女露脸视频| 一区,二区,三区视频| 老熟女熟妇| 欧美性战999| 99国产在线绯色一区| 精品超碰色| 人妻插插人妻人| 亚洲无992tv| 97伦综合| 不卡日本一区二区| 91亚洲网| 日日噜噜夜夜狠狠视频无| 成人无码在线视频网站| 亚洲AV成人无码一二三久久 | 亚洲欧洲日韩国产自在线| 日本狂喷奶水在线播放212| 高清国产成人无码| 久久性爱城| 清柠毛片| 亚洲欧洲日产国产综合网| 亚洲揄拍网| 欧美日韩中国x| 日本Suv精品一区二区| 97视频免费播放| 91精品国产91久久福利| 亚洲AV秘 精品久久老牛影视| 国产精品亚洲天堂网址| 国产精品爽爽va在线观看98| 夜色五月天| 丝袜狠狠草尤物人妻av91| 久久最新视频免费观看| 五十路熟女在线不卡观看一区二区| www.久久超碰| 伊人一级免费黄片| 国产三区免费在线观看| 亚州色交| 亚洲黄色网址| 91欧美经典| 久久av无码| 亚洲天堂人妻熟妇视频| 亚洲男人天堂Av| 91九九九逼| 熟妇女伦乱视频视频| 天天干18禁| 香伊人在线| 九九无码视频| 色av中文字幕| 色妇综合网| 五月婷网站| 噜噜噜狠狠色综合| 丝袜美女诱惑 91 视频| 香蕉99秘 一区精品蜜桃臀| 亚洲好看强奸乱伦| 国产欧美一区二区| 日日摸日日弄日日拍| 欧美成熟性爱精品| 综合色久| 97欧美色| 国产成人无码啪| 久久人妻丝袜一区二区三| 91 综合 色| 看全色黄大色大片免费视频| 天天天天天天天天天天干美女| 日韩在线视频1234| 亚州男人天堂| 国产精品香蕉热久久新品| 99re6久热只有精品6在线直播| 啊啊啊久久久视频| 先锋激情∨在线视频播放| 人妻啊啊人妻啊| 欧美啪啪天堂| 夜嗨影院| 一本久久精品中文字| 伊人影院日本| 男人天堂.AB| 九热中文字幕| 五月天社区| 欧美91久久久久| 亚洲图片色图欧美另类| 人人爽夜夜操| 日韩肏逼视频| 综合色图,成人综合网| 亚洲天天自拍| 日本超碰在线国产一区| 亚洲午夜精品久久久中文影院| 日韩丰满熟妇| 一区超碰一区| 国内自拍 日韩激情 99| 人人操人人精品影片| 天堂无码精品国产久| 亚洲官网在线| 加勒比在线观看一区二区| 91久久午夜无码鲁丝片久久人妻| 97在线免费| 亚洲 中文 女同| 96久久久| 亚洲欧洲无码97久久精品| 凹凸视频在线一区二区| 97国产亚洲中文在线| 国产无码精品无码| 91热情品| 国产精品一区二区 尿失禁| wuyechaopeng| 五月激情影院| 久久大黄片| 日韩欧美成人大香蕉| 免费看黄片现成| 九九热精彩视频| 久久精品店| 四虎av在线| 五月天色图影视| 精品高潮| 免费成人在线熟妇网| 国产男人又猛又粗又爽| 综合网少妇| 97天天爽| 26uuu性| 天天日熟妇| 人妻少妇视频在线播放| 黑人精品XXX一区一二区| 久久久久ab| 人妻在线视频| 91色综合| 97久久久久久久久久| 国产精品色| 91伊人久| 91日韩网站| 亚洲色图a| 在免费jIzzjIzz在线视频| 国产一二三福利视频网| 午夜精品久久久99| 国产精品麻豆成人AV艾秋| 91精品国产91久久福利| 夜夜春夜夜操| 亚洲AV无码久久精品蜜桃小说| 欧亚性爱视频免费看| 亚洲精品99999| 亚洲污一污二| 亚 欧 美 综合| 3P乱轮视频| 国产精品999aaa| 精久久久| 色偷偷色偷偷欧美日韩| 青青草操逼逼视频| 日日碰狠狠添天天爽超| 最近2018中文字幕在线高清第一页| 天天搞欧美| 99xav| 玖玖人人爱| 欧美性爱视频免费一区一A| 男人的天堂网页| 日韩BBN| 天天看高清麻豆| 日本 成 人 小说 电影 一区二区| 丰满人妻无码一区二区三区| 中文字幕av亚洲精品| 青青草原av| 色综合20p| 91 国产丝袜在线放观看| 日本99久久| 人人爱人人操人人性| 成人小说视频在线精品欧美| 黄片www视频免费| 91精品人妻一区二区三区蜜臀| 伊人96在线| 97天天弄| 丰满精品人妻少妇久久字幕| 久久综合精品一区二区三区| 精品人妻1237| 久久极品一区二区| 亚洲高潮少妇| 综合网欧美在线| 丁香六月婷| av大香蕉| 婷婷五月成人| 伊人成人中文字幕久久网| 亚洲一区日韩| 爱我干综合| 午夜男女爽爽爽在线视频| 欧美日韩国产高清在线一二三区| 国产精品探花视频| Blackedraw视频一区二区| 亚洲精品尤物yw在线影院| 麻豆综合一区av| 在线观看无码三级少妇| 爽极品影院| 99re公开精品免费视频| japan日本高清乱xxxx| 色呦呦呦在线观看视频| 欧美啪啪女女| 人妻熟女字幕一区二区| 91天天日| 亚州日韩97| 国产后入清纯| 亚州一区二区| 嫩呦国产一区二区三区AV| 欧美大香蕉同搞| 婷婷五月天激情网| 99视频精品| 泰国AV在线观看| 超碰97网址| 国桃视频产巨乳精品一区二区在线| 亚洲诱惑天堂| 日本天天干天天操一区| 久久久久亚洲熟妇熟女| 美女极品一区二区三区| 丁香色五月 97干| 超碰97精品在线| 日本999精品视频| 欧美手机在线综合| 亚洲无992tv| 中国一级操逼视频| 强奸乱亚洲| 色爽爽文学| 亚洲色资源| 大粗鳼巴久久久久| 免费观看性欧美一级| 日本一区二区做爱的视频| 中文字幕一区av| 亚洲色图国产另类| 色悠悠伊人网五月天| 日本熟女不卡视频| 噜噜噜无码AV一级一级久久影院| 老熟女91av| 青青草久久| 国产拍偷精品网站| 5月婷婷6月六月丁香| 欧美少妇大量自拍视频在线观看| 97超碰色中文字幕| 亚洲啪啪视频免费| 91色久| 久久夜嗨| 热99这里有精品综合久久 | 98福利在线视频| 99久久99久久免费精品蜜臀| 51一区二区三区| 91在线免费观看处女| 日本幼女18+| 影视综合无码少妇| 四虎 精品 WWW| 老熟女综合网 | 亚洲天天自拍| 老司机射| 九九九影院| 家庭乱伦麻豆| 麻豆人妻精品一区二区| 校园春色 亚洲| 欧美亚洲尤物久久| 麻豆天美传媒在线视频天堂| 野狼福利社区| 999久久久精品国产| 亚洲欧美视| 久操网线| 欧美高潮| 国产精品一级毛片不卡视| 欧美大香蕉97| 人人弄人人摸| 夜夜狼人妻| 九九热AV| 夜夜高潮夜夜爽高清视频一| 久久久97| 青娱乐 成人娱乐在线| 天天综合网~91| 色五月婷婷网| 欧美性性性| 99热在线播放| 91成人无码| 涩五月婷婷| 91欧美网| 亚洲熟妇图片| 欧洲性爱无码区| 亚洲综合网图| 午夜无遮挡男女啪啪视频| 亚洲 se图 欧美电影| 三级日本一区二区三区| 国产欧美一区二区| 国产精品原创巨作?v网站| 国产久久视频| www.黄色在线| 啊啊啊骚| 男人夜色天堂ss| aa片毛片| 久久爽爽精品| 欧美成人黄网色网站| 97jingpin| 六月婷婷五月丁香| 青青操网| 亚州色阁| 五月丁香成人网| 国产亚洲色婷婷久久99精品91 - 百度| JULIA人妻风俗店中出电影| 精品一区二区国产日韩| 九九九九九九九九九九九九九九九女| 欧洲一级性爱视频在线观看| 国产97色在线 | 亚洲| 五月天婷婷欧美三区| 欧美gv在线观看| 国产一区二区精品在线视频| 99这里有精品视频| 欧美日韩大黄片| 伊人在线大香蕉视频久久| 色九区| 日韩字幕一区| 色噜噜人妻av中文字幕| 91人人看| 国产精品午夜高潮呻吟久久av| 久久久夜夜夜| 亚洲有码第一页| 五月婷婷综合在线| 久久黄色视频一区二区三区| 四虎免费在线播放| 国产精品2020| 97色在线| 在线国产福利网址导航 | 精品久久一区二区三区四区五区| 天天视频网站黄| 国产乱码久久久| 亚洲天堂第一页| 狠狠爱综合| 日逼逼免费看| 屁股久久久久久| 超碰在线第一页| GVH-003 母子姦 青木玲-麻豆视频,麻豆视传媒短视频网站入口,麻豆视传媒官网直 | 色丁香五月婷婷| 中文字幕精品一区欧美| 久久久久久综合久久伊人蜜月| 97久久精品国产| 人人操AV| 免费视频a级毛片免费视频| 欧美特大AA级黄片| 丰满人妻一区二区三区免费| 蜜桃狠狠色伊人亚洲综合| 欧美中文字幕男人天堂久久精品 | 激情四射婷婷四五月天| 激情接吻视频久久久久久| 少妇高潮流水av免费| 欧美亚州综合网图片| 九九av| 91色伦综合| 国产怡红院| 亚洲精品色| 欧美黄色片AAAAA| 日本一级婬片试看三分钟| 国产毛片片精品天天看视频| 日韩91网站| 色原狠狠天天天| 亚洲91综合| 欧美在线中M| 操b网站亚洲无码| 福利风月五月天影院| 久久久999日本大片| 99热思思| 色婷婷五月天| av天堂影视中文在字幕在线中文 | 亚洲国产精品久久久久婷婷老年| 亚洲欧洲久久天堂| 热久久99999| 欧亚久久偷拍视频| 日本精品免费一区二区三区四区| 欧美色图片91| 久久偷拍人| 麻豆精品A片免费观看| 密臀在线免费观看| 亚洲淫乱骚妇AV| 国产日韩人人| 91男人天堂网| 青青青草原| 久久99干一本高清| 97久久国产精品女不卡| 天堂男人网| 欧美综合天天| 操人人| 人人操肉肉| 国产福利小视频高清在线观看| 欧美日韩国产高清在线一二三区| 日韩不卡在线一区二区| 亚洲操逼无码| 亚洲第一页色| 久久只有精品一区二区三区| 欧美日韩大陆黑人少妇99| 91爰爱欧美| 久久久9 9 9精品| 99夜夜操| 中文字幕人妻资源在线| 亚洲熟女性高潮久久久| 欧美精品久久久久久久久88| 大香蕉久操| av在线浏览| 中文字幕第23区| 后入综合久久| 欧美夜夜草视频| 中日韩久久久| 综合熟女| 欧美性爱网97| 欧美色图20P| 搡老熟女免费视频| 99久久久er直播网址| 99热这里是精品| 一区 欧美 日韩 麻豆| 青青青草伊人精品| 美女诱惑久久| 久久久久久国产无码精品| 99热综合| 天天综合网AV91| 密臀视频三区免费网站| 国产欧美日本亚洲精品| 欧美一区二区亚洲天堂| 亚洲蜜臀懂色| 日本二三四区| 十八禁成人网站在线观看| 99热成人| 大香蕉色欲AV| 激情小说日韩无码| 日本理论在线| 综合天天网| 无码国产精品96久久久久孕妇| 操B在线观看| 99爱久久视频频| 国产精品一区二区麻豆| 日韩性爱一级片| 婷婷丁香在线| 加勒比av官网在线| 无码久久国产| 96AV精品| 日本三级精品| 国产 无码 一区二区| 日韩欧美成人大香蕉| 欧美性高潮在线| 久久一级无码精品毛片6| 亚洲男人天堂网久久| 久久东京热成人| 熟女字幕| 国产精品久久久九九九| 啪啪视频免费在线观看| 91精品丝袜久久久久久| 99热18这里只有精品| 黄色免费一级在线毛片| 91麻豆天美国产欧美| 夜夜嗨TV| 入口操逼网站| 日本高清加勒比| 欧美日日操| 亚洲高清视频在线观看| 日韩射精| 校园春色制服丝袜中文字亚洲| 女人18精品一区二区三区| 日韩人妻有码免费视频| 安徽熟妇视频| WWW啪啪的com| 国精综合一二三区影视| 老熟女乱伦片| 96AV久久久| 精品无码欧美三级| 亚洲人在线| 无码精品久久| 欧美中文狠| 亚洲春色欧美激情自拍| 夜夜嗷嗷一区二区| 正在播放国产精品一区| 丰满少妇高潮无码| 天天操天天射天天日| baiduhicn.com。| www.99中文字幕| 国桃视频产巨乳精品一区二区在线| 91丨九色丨国产丨人妻在线| 九九成人精品| 性久久| 午夜精品久久久久久久| 日韩欧美俄罗斯A片| 欧美综合777| 97干在线| 久久久亚洲| 麻豆人妻少妇在线免费观看| 精品丝袜无码一区二区三APP| 97中文字幕色| 久久久久久国产无码精品| 91九色丰满高潮| 婷婷中文字幕| 香蕉国产精品麻豆亚洲欧美日韩 | 搡老女人老妇女AAA一VU麻豆| 啊好爽快点-国产一区二区三区撒尿在线-成人AV | 丁香五月偷拍| 91综合色噜噜| 操淫穴亚洲五月丁香 | 日韩婷婷| 激情婷婷综合久久| 伊人991| 高清无码国产亚洲| 欧美天天综合| 日日噜噜夜夜久久亚洲一区二区| 亚洲黄网在哪免费看| 亚洲丝袜综合| 一本一首道人妻少妇免费久久| 性色av网站| 无码国产精品96久久久久孕妇| 蜜臀99999| 狼人久草| 伊人精品久久网站| 天天综合91入口| 日本精品国产视频| 亚洲黄网在哪免费看| 97精| 毛片麻豆91糖心精品毛情片| 另类在线| 隔壁邻居波多野结衣中文字幕| 97国产|免费| 极品后入免费视频| AV 少妇 人妻 偷拍| 大黄片做爱的大的| 精品欧美乱码久| 99只有精品| 日韩有码免费视频| 人人爱人人操人人性| 26UUU欧美日本| 丰满少妇精品一区二区| 欧美亚综合色图| 婷婷五月天丁香花| 日韩亚洲国产视频| 超碰精品日韩欧美国产| 亚洲影视高清三级-草1024榴社区入口-品爱AV| 99999久久久久9国产精品| 国产真实野战在线视频| 视频一区二区免费在线| 国产精品另类| 天美传媒av一区二区| 日韩/97| 久久性爱视频| www.色婷婷色综合| 95自拍视频在线观看| 粉嫩av在线| 欧美性夜| 校园春色美腿丝袜| 欧美激情亚洲情色| 亚洲青色欧美| 2019天天操天天爽天天拍| 人妻久久久| 中文字幕一区日韩精| 亚洲一曲日韩精品| 国产家庭乱伦性爱视频| 国产在线视频午夜精华在| 九九热re99re6在线精品| 男人天堂免费| 人妻少妇精品久久久| 狠狠图片青青草| 欧美综合97www| 天天透伊人| 国产精品久久久亚洲一区| 欧美亚洲日本激情在线| 无码聚合| 蜜乳AV一区二区三区四| 久久激情亚洲精品无码?V| 岛国毛片在线观看免费| 日韩免费看在线黄色片| 欧美精品23| 大香蕉乱级| 被男人吃奶很爽的毛片| 大香蕉乱级| 亚洲好看强奸乱伦| 91深夜夜| 亚洲成人久久一区二区| 五十路三级片| 欧美性爱伊人| 日韩在线观看中文字幕视频| 日本中文字幕在线电影| 99欧美| 日韩素人无码一区二区三区三州| 禁片 高清 在线观看视频网站| 亚洲天堂,男人| 91老熟女逼| 操香逼| 大香蕉男人的天堂| 97天天插| 97亚洲精品超碰| 91天天看| 亚洲小电影免费涩涩成人在线高清 | 屌逼传媒| 四虎AV无码| 91/欧美| 午夜九九| 综合网 欧美| se吧提供国产乱老熟视频胖女人| 欧美1区二区三区公司| 久久久麻豆精品| 久久五月婷| 91在线限制级| 亚洲日本天堂| 91熟女丨91老女人| 日韩激情电影中文字幕| 亚洲图片激情综合另类| 成人国产精品三级A片| 久久一二三四五六七八九区区区| 一区二区三区日韩欧美 | 裸模AV女优| 亚洲在线综合| 69久久| 91香蕉视频在线观看免费| 看一级特黄a大一片| 日韩免费性爱视频在线观看| 久久综合18p| AV99热18这里只有精品| 夜夜久久久| 一级AV性爱| 久热久| 97欧美色资源| 欧美国产婷婷久久| 久久黄色视频一区二区三区 | 九九九久久久久| 性欧美| 黄色视频60分钟| 五月丁香啪啪网| 美美91成人国产精品欧美精品久久久久久久| 一二视频神马久久传媒| 国产精品人妻无码久久久互動交流 | 久久手机视直播| 熟女91网| 日本人妻伦在线中文字幕| 伊人五月天| 欧美日韩青操| 亚洲乱码精品一区二区| 免费一级毛片在线视频观看| 91最新综合| 97超碰精品图片| 综合久久六月久久婷婷| 一区二区首页| 男人天堂新在线| 天天视频综合在线观看视频| 欧美日日夜夜| 人人妻人人爽一区二区三区| 亚洲五码一区二区三区| 日韩伦理视频| 国产熟女无套内射| 伊人久久大香大香线蕉中文 | 欧美久久伊人| 久久久久ab| 亚洲中文字幕在现观看| 五月激情影院| 久久久青草青青国产亚洲免观精品高清完整版_97久久综合区小说区图片区,国精品 | 精品欧美老熟女一二区| 97啪啪| 亚洲日韩97| 黑人狂躁日本妞一区二区三区| 色九九九| 一起草三级AV电影在线观看 | 天天欧美色| 久久女人| 久久综合五月天| 欧美线天码中字| 中文字幕一区二区韩| 亚洲熟女乱熟乱熟妇综合网二区| av黄图片在线观看| 91黑丝在线播放| 人妻第一页| 99精品无码| 9丨久久九九九| 丁香六月婷婷| 夜夜爽夜夜高潮夜夜爽| 久热无码| 熟妇女伦乱视频| 精品夜夜澡人妻无码| 激情一区二区| 精品国产嫩穴视频| 黑人娇小av在线播放| 日韩 人妻 精品| 欧差乱伦二三| 麻豆婷婷成人一二三| 激情五月综合开心五月| 天天看高清麻豆| 人人操人人搞人人草| 亚洲精品人伦一区二区| 特级丰满少妇一级AAAA爱毛片| 肉丝无码中文高清| 久久男女激情视频网站| 欧美色91| 天天综合色电影| a片 xxxx受爽视频| 丝袜综合| 国产www色在线观看| 久久9精品网站| 丁香五月AV| 国产无码成人无码| 亚州 综合 色图| 男人的天堂一区三区| 97在线/亚洲| 亚洲国产欧美日韩精品一区二区三区,国产一区二区三区在线看片,欧美性猛交 XXX | 亚洲成人妻日韩在线| 另类 日韩 熟女| 操熟女91| 超碰午夜在线| 国产精品久久久久中文字幕| 中文字幕国产| 精品福利视频| 熟女五十路一区二区三| 97中文综合| 日本天天吊| 岛国黄色短视频| 欧美一级二级三级| 老熟女熟妇| 亚洲乱码尤物193YW| 亚洲日韩国产精品| 色网1| 91视频国品一二三区| 欧美性爱免费短视频| 亚洲欧美激情小说| 欧美日韩淫加| 全球成人中文在线| 麻豆久久一区二区三区| 欧美熟女丝袜| 精品女人999| 亚洲精美粉嫩嫩泬在线观看 | 伊人色综合超碰| 人人射人人操人人摸| 国产毛片毛片4p懂色| 九九九九97| 色老汉色| 久久综合激情| 操逼片国产| 狠狠操狠狠操操| 99热国产| 丁香五月天久久精品视频一区二区三区| 黄片免费看黄片免费看| 26UUU欧美日本| 欧美图片校园春色| 色婷婷久久综合超碰| 欧美另类色图片| 在线观看黄色电话| 国产精品一区二区亚洲人成毛片| 高清无码91| 丝袜狠狠草尤物 91| 国产精品熟女AV中文字幕在线播放| 日韩av影片在线观看| 国产多人在线观看视频| 91 丝袜在线播放| 日韩欧美蜜桃精品久久中文字幕久久| 天天干天天日天天射黄色大片| 久久精品99| 日韩欧美中文| 国内偷自视频区视频综合| www国产精品| 国产精品另类| 青青青草伊人精品| 欧美午夜视频| 日本一天色道久久久精品视频| 久久人人妻| 久久国产三区| 五月婷色| 大香蕉婷婷| 国产亚洲禁久一区二区| 中文字幕一区二区韩| 国产精品亚洲天堂网址| 色欲久久久久综合网| 天天日天天操天天射河南省| 亚洲高清综合网| 欧美东京热青青草| 大香蕉中文网| 四虎影视国产精品| avav青青草久久夜| 超碰偷拍| 伊人性在线视频| 另类图片五月天| 97伊人超碰| 999国产精品999久久久久久| 伊人嫩草| 怡春院久久| 美女好片色日本| 91A欧美电影网站| 久久久久久9| 91精片| 超碰在线欧美性爱激情| 精品无码一区二区三区色欲| 一级做受视频免费是看美女| 久热9| 九九九久| 黄色工厂这里只有精品| 日韩精品人妻中文字幕不卡乱码| 玖玖资源视频一区二区三区| 国产日韩中文字幕欧美| 成人草草视频| 超碰诱惑| 最新日本中文字幕| 男女猛烈无遮掩视频免费软件|