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

ARTICLE DETAIL

資訊詳情

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

JMS與ActiveMQ實(shí)戰(zhàn)筆記:從消息模型到可靠消息機(jī)制

JMS與ActiveMQ實(shí)戰(zhàn)筆記:從消息模型到可靠消息機(jī)制 我第一次正兒八經(jīng)看 JMS 和 ActiveMQ并不是因?yàn)橐嬖嚤嘲斯啥琼?xiàng)目里兩個(gè)服務(wù)之間的同步調(diào)用把數(shù)據(jù)庫連接池打爆了。上游接口一個(gè)超時(shí)下游跟著雪崩運(yùn)維的告警群半夜響成一片。翻來覆去折騰了幾天之后同事丟給我一句話“用消息中間件把調(diào)用拆開吧先看看 JMS 和 ActiveMQ?!碑?dāng)時(shí)我連 JMS 和 MQ 的關(guān)系都說不清楚硬著頭皮把那套消息模型啃了一遍才有了這篇“JMS、ActiveMQ 學(xué)習(xí)一則”。這篇筆記適合兩類人一是剛開始接觸消息中間件、被一堆 JMS API 術(shù)語搞暈的開發(fā)者二是能把 Demo 跑通但不清楚 Queue、Topic、ACK、持久化到底意味著什么的人。我會把規(guī)范、代碼、踩坑都放在一起講盡量還原當(dāng)時(shí)的學(xué)習(xí)路徑也把網(wǎng)絡(luò)上那些講得含糊的地方補(bǔ)完整。1. 為什么我先啃 JMS 而不是直接學(xué)某個(gè) MQ 客戶端1.1 消息中間件解決的核心問題把“同步等待”變成“異步解耦”先說我當(dāng)時(shí)的場景。有個(gè)訂單創(chuàng)建服務(wù)處理完訂單之后要通知庫存服務(wù)扣庫存、通知積分服務(wù)加積分、通知短信服務(wù)發(fā)通知。最開始寫的代碼很“樸素”——A 服務(wù)直接用 HTTP 調(diào)用 B 服務(wù)同步等返回。看起來邏輯很直白但一壓測就出問題任何一個(gè)下游服務(wù)變慢訂單接口的響應(yīng)時(shí)間立刻被拖垮下游服務(wù)一重啟上游的調(diào)用直接報(bào)超時(shí)訂單雖然建成功了但庫存、積分、短信全部沒執(zhí)行數(shù)據(jù)就錯(cuò)亂了。消息中間件解決的就是這種“你完成你的我完成我的然后把變化告訴別人”的通信問題。訂單服務(wù)把“訂單已創(chuàng)建”這個(gè)事實(shí)寫到消息隊(duì)列里訂單服務(wù)的接口直接返回成功庫存、積分、短信服務(wù)各自從隊(duì)列里取消息按自己的節(jié)奏處理。這樣三個(gè)下游服務(wù)誰慢、誰掛都不影響訂單主流程。這個(gè)模型里有幾個(gè)術(shù)語你得先建立直覺Broker是中間件服務(wù)器負(fù)責(zé)消息的存儲和轉(zhuǎn)發(fā)Producer是消息的生產(chǎn)者Consumer是消息的消費(fèi)者。消息不是直接給某個(gè)消費(fèi)者的而是先放到 Broker 的某個(gè)“容器”里消費(fèi)者自己來取。這個(gè)“容器”就是后來的 Queue 或 Topic。1.2 JMS 是規(guī)范ActiveMQ 是實(shí)現(xiàn)先理解這對關(guān)系JMSJava Message Service是 Java 平臺制定的一套消息服務(wù)接口規(guī)范它規(guī)定了 Java 程序怎么創(chuàng)建連接、怎么發(fā)消息、怎么收消息但 JMS 自己不干活真正干活的是符合這套規(guī)范的 provider比如 Apache ActiveMQ、開源的 OpenMQ 等。這個(gè)關(guān)系有點(diǎn)像 JDBC 和 MySQL 驅(qū)動的關(guān)系——JDBC 規(guī)定了你用什么方法連接數(shù)據(jù)庫MySQL 驅(qū)動負(fù)責(zé)把這些方法翻譯成 MySQL 能懂的協(xié)議。這就解釋了為什么學(xué)習(xí)的時(shí)候要先看 JMS 再看 ActiveMQ如果你只對著 ActiveMQ 的 API 抄一遍換個(gè) MQ 你就廢了如果你把 JMS 的核心模型理解了接觸任何一個(gè)兼容 JMS 的中間件都能很快上手。我當(dāng)初踩過一個(gè)認(rèn)知誤區(qū)以為 ActiveMQ 提供了比 JMS 多得多的高級功能所以直接按 ActiveMQ 的文檔寫就行。實(shí)際上 ActiveMQ 對 JMS 規(guī)范做了很完整的實(shí)現(xiàn)它的核心 API 就是 JMS API你寫代碼時(shí) import 的主要是javax.jms.*這個(gè)包而不是org.apache.activemq.*。后者只在構(gòu)造連接工廠時(shí)才會用到。1.3 什么場景才需要引入消息中間件先潑盆冷水消息中間件不是銀彈學(xué)習(xí)過程中我也遇到過濫用它的團(tuán)隊(duì)。一個(gè)內(nèi)部查詢接口沒有任何瞬時(shí)流量壓力硬是套一層消息隊(duì)列結(jié)果多了一個(gè)運(yùn)維節(jié)點(diǎn)、多了一段延遲、多了一堆消息亂序問題。什么時(shí)候才值得引入我的判斷標(biāo)準(zhǔn)有三條一是上下游節(jié)奏不一致下游來不及同步處理需要用隊(duì)列做緩沖二是下游故障不應(yīng)該影響上游主流程需要隔離故障三是同一份業(yè)務(wù)事件需要被多個(gè)系統(tǒng)各自消費(fèi)比如訂單創(chuàng)建之后庫存、積分、日志都要處理。反過來說如果只是簡單的 A 調(diào) B響應(yīng)時(shí)間敏感且 B 很少故障那直接 HTTP 調(diào)用反而更合適。這部分認(rèn)知雖然當(dāng)時(shí)不成熟但后來回看幫我在選型時(shí)規(guī)避了不少坑。2. JMS 核心模型五個(gè)抽象角色串起全部消息邏輯JMS 1.1 里抽象出的角色其實(shí)就五個(gè)ConnectionFactory、Connection、Session、Destination、MessageProducer/MessageConsumer。剩下的概念比如 Message、AcknowledgeMode 都是在這五者之上附加的。把這五個(gè)角色串成一個(gè)故事你就能看懂 90% 的 JMS 代碼。2.1 ConnectionFactory創(chuàng)建連接的唯一入口ConnectionFactory 是一個(gè)連接工廠接口它封裝了與某個(gè) Broker 建立連接所需的參數(shù)。在 ActiveMQ 中最常見的是ActiveMQConnectionFactory構(gòu)造時(shí)傳入 Broker 的地址典型格式是tcp://127.0.0.1:61616。ActiveMQConnectionFactory factory new ActiveMQConnectionFactory(tcp://127.0.0.1:61616);這個(gè)對象通常是重量級對象創(chuàng)建成本高所以應(yīng)該復(fù)用不要每次發(fā)消息都 new 一個(gè)。我看到不少剛?cè)腴T的同學(xué)把ActiveMQConnectionFactory寫在方法內(nèi)部短時(shí)間大量請求一來連接資源就爆炸了。正確做法是使用連接池或至少是單例持有。2.2 Connection 與 Session消息通信的骨架從工廠拿到Connection之后需要顯式調(diào)用connection.start()這時(shí)候連接才真正建立。然后從 Connection 創(chuàng)建 Session。Session 是一個(gè)非常重要的中間層消息的生產(chǎn)和消費(fèi)都是基于 Session 的Session 的創(chuàng)建方式?jīng)Q定了本次會話的確認(rèn)模式和事務(wù)邊界。Connection connection factory.createConnection(); connection.start(); Session session connection.createSession(false, Session.AUTO_ACKNOWLEDGE);createSession的第一個(gè)參數(shù)是事務(wù)標(biāo)志第二參數(shù)是確認(rèn)模式。在 JMS 1.1 中如果第一個(gè)參數(shù)傳 true第二個(gè)參數(shù)會被忽略因?yàn)槭聞?wù)模式下發(fā)送和接收都通過commit和rollback控制。剛開始不用懵理解成“Session 是一段通信上下文凡是這次會話內(nèi)的消息都可以在這個(gè)上下文里標(biāo)記狀態(tài)”就行。2.3 Destination消息要發(fā)往的地址Destination 是抽象類實(shí)際子類要么是Queue要么是Topic。Queue 對應(yīng)點(diǎn)對點(diǎn)模型Topic 對應(yīng)發(fā)布訂閱模型。在代碼里session.createQueue()或session.createTopic()創(chuàng)建的只是邏輯地址不需要在 Broker 側(cè)預(yù)先建好ActiveMQ 會在第一次使用時(shí)自動創(chuàng)建。Queue queue session.createQueue(DEMO.ORDER); Topic topic session.createTopic(DEMO.NEWS);這里有個(gè)細(xì)節(jié)隊(duì)列名稱建議使用“域名前綴 業(yè)務(wù)名”的格式比如ORDER.CREATED、STOCK.DEDUCTED為了在管理后臺一眼能看出用途。我見過用queue1、test2這樣的名字上生產(chǎn)的后來排查問題差點(diǎn)被隊(duì)友打死。2.4 MessageProducer 與 MessageConsumer實(shí)際干活的兩個(gè)角色生產(chǎn)者和消費(fèi)者都在 Session 上創(chuàng)建。生產(chǎn)者創(chuàng)建時(shí)可以指定默認(rèn)目的地也可以不指定發(fā)送時(shí)再傳目的地。生產(chǎn)者還支持設(shè)置是否持久化、優(yōu)先級、存活時(shí)間等特性這部分會影響消息的存儲行為后面展開。MessageProducer producer session.createProducer(queue); producer.setDeliveryMode(DeliveryMode.PERSISTENT); TextMessage message session.createTextMessage(hello jms); producer.send(message);消費(fèi)者既可以主動拉取消息也可以注冊消息監(jiān)聽器異步接收消息。主動拉取用consumer.receive()它會阻塞等待可以傳入超時(shí)時(shí)間異步監(jiān)聽用MessageListener接口Broker 一有消息就回調(diào)onMessage方法。2.5 Message 結(jié)構(gòu)消息頭、屬性、消息體三層分工JMS 的消息對象由三部分組成。第一個(gè)是消息頭header存放 JMS 規(guī)范定義的固定字段比如JMSDestination、JMSMessageID、JMSPriority、JMSExpiration。第二個(gè)是消息屬性properties可以看成附加的元數(shù)據(jù)支持字符串、數(shù)字、布爾等類型常用在消息篩選和路由上。第三個(gè)是消息體body存放業(yè)務(wù)數(shù)據(jù)本身。消息體有幾種類型TextMessage適合傳輸文本和 JSON 字符串BytesMessage適合二進(jìn)制數(shù)據(jù)MapMessage適合鍵值對結(jié)構(gòu)ObjectMessage適合序列化對象但跨語言不友好StreamMessage用得最少。實(shí)際項(xiàng)目里 80% 的流量都是TextMessage因?yàn)闃I(yè)務(wù)方一般約定用 JSON 傳結(jié)構(gòu)化數(shù)據(jù)不會強(qiáng)行依賴 Java 對象序列化。我自己的習(xí)慣是消息體只放必要的業(yè)務(wù)數(shù)據(jù)別把整個(gè)數(shù)據(jù)庫實(shí)體塞進(jìn)去。因?yàn)橄⒖赡鼙欢鄠€(gè)系統(tǒng)消費(fèi)每個(gè)系統(tǒng)關(guān)心字段不一樣塞整個(gè)實(shí)體不僅體積大而且上游實(shí)體變更會導(dǎo)致下游反序列化失敗。3. ActiveMQ 落地實(shí)操從下載啟動到第一個(gè)消息跑通理論講完了得有真家伙。我當(dāng)時(shí)本地環(huán)境是 JDK 8下載的是 Apache ActiveMQ 的穩(wěn)定發(fā)行版。注意 ActiveMQ 有兩個(gè)分支一個(gè)叫 ActiveMQ Classic一個(gè)叫 ActiveMQ Artemis兩者都是 ActiveMQ但 Artemis 是新一代架構(gòu)API 上對 JMS 規(guī)范的支持更現(xiàn)代。作為學(xué)習(xí) JMS 的入口我建議用 Classic因?yàn)橘Y料多、踩坑記錄全先把規(guī)范玩明白。3.1 啟動 Broker十分鐘確認(rèn)環(huán)境下載解壓后進(jìn)入 bin 目錄Linux/macOS 下執(zhí)行./activemq startWindows 下執(zhí)行activemq.bat start。啟動完成后默認(rèn)監(jiān)聽以下幾個(gè)重要端口端口用途61616JMS 客戶端連接的 OpenWire 端口8161Web 管理控制臺端口5672AMQP 協(xié)議端口默認(rèn)也開啟打開瀏覽器訪問http://127.0.0.1:8161/默認(rèn)登錄賬號是 admin密碼也是 admin進(jìn)去就能看到隊(duì)列列表、Topic 列表、連接數(shù)、消息統(tǒng)計(jì)等。我強(qiáng)烈建議學(xué)習(xí)階段養(yǎng)成盯控制臺的習(xí)慣很多代碼“看起來沒反應(yīng)”的問題在控制臺里一眼就能看出來——消息到底有沒有進(jìn)來、被誰消費(fèi)了、有沒有進(jìn)入死信。3.2 第一個(gè) JMS 生產(chǎn)者發(fā)送一條持久化文本消息下面這端代碼是我當(dāng)時(shí)跑通的第一個(gè)生產(chǎn)者。為了方便閱讀我把異常處理簡化了學(xué)習(xí)階段先跑通生產(chǎn)上請務(wù)必正確封裝資源關(guān)閉邏輯。import javax.jms.*; import org.apache.activemq.ActiveMQConnectionFactory; public class QueueProducer { public static void main(String[] args) throws Exception { // 1. 連接工廠指向本地 Broker ActiveMQConnectionFactory factory new ActiveMQConnectionFactory(tcp://127.0.0.1:61616); // 2. 創(chuàng)建連接并啟動 Connection connection factory.createConnection(); connection.start(); // 3. 創(chuàng)建會話非事務(wù) 自動確認(rèn) Session session connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 4. 創(chuàng)建目的地 Queue queue session.createQueue(DEMO.ORDER); // 5. 創(chuàng)建生產(chǎn)者 MessageProducer producer session.createProducer(queue); producer.setDeliveryMode(DeliveryMode.PERSISTENT); // 6. 發(fā)送一條文本消息 TextMessage textMessage session.createTextMessage(訂單已創(chuàng)建訂單號20250101); producer.send(textMessage); System.out.println(已發(fā)送消息 textMessage.getText()); // 7. 關(guān)閉資源 producer.close(); session.close(); connection.close(); } }這個(gè)例子里最容易忽略的是connection.start()。有的教程會在創(chuàng)建生產(chǎn)者之前就調(diào)用 start有的會在發(fā)送之后才調(diào)用。start()本身不是發(fā)送動作的開關(guān)但它會讓連接進(jìn)入可發(fā)送/接收狀態(tài)。如果你只創(chuàng)建連接不 start消息照樣能發(fā)出去但消費(fèi)者端不 start 的話就一直收不到消息。我當(dāng)初就踩過這個(gè)坑后面專門講。3.3 第一個(gè) JMS 消費(fèi)者同步接收和異步監(jiān)聽兩種方式消費(fèi)者有兩種寫法我建議都試一遍。第一種是主動 receive適合測試和批處理任務(wù)。import javax.jms.*; import org.apache.activemq.ActiveMQConnectionFactory; public class QueueConsumer { public static void main(String[] args) throws Exception { ActiveMQConnectionFactory factory new ActiveMQConnectionFactory(tcp://127.0.0.1:61616); Connection connection factory.createConnection(); connection.start(); Session session connection.createSession(false, Session.AUTO_ACKNOWLEDGE); Queue queue session.createQueue(DEMO.ORDER); MessageConsumer consumer session.createConsumer(queue); // 阻塞 3 秒沒消息會超時(shí)返回 null Message message consumer.receive(3000); if (message instanceof TextMessage) { System.out.println(收到消息 ((TextMessage) message).getText()); } consumer.close(); session.close(); connection.close(); } }第二種是注冊監(jiān)聽器異步接收實(shí)際項(xiàng)目里這種用得更多因?yàn)樗粫枞麡I(yè)務(wù)線程。示例代碼我放在下面consumer.setMessageListener(new MessageListener() { Override public void onMessage(Message message) { if (message instanceof TextMessage) { try { System.out.println(異步收到消息 ((TextMessage) message).getText()); } catch (JMSException e) { e.printStackTrace(); } } } }); Thread.sleep(5000);這里有個(gè)容易翻車的地方Thread.sleep(5000)是必要的。因?yàn)閙ain方法執(zhí)行完后 Java 進(jìn)程就退出了消費(fèi)者監(jiān)聽器注冊完還沒來得及收消息進(jìn)程就沒了。看起來像是“監(jiān)聽器沒生效”其實(shí)只是主線程提前退出。生產(chǎn)環(huán)境一般由應(yīng)用服務(wù)器或 Spring 容器持有消費(fèi)者生命周期不存在這個(gè)問題。3.4 跑完之后去控制臺觀察四個(gè)維度第一個(gè)消息鏈路跑通后我不急著寫第二個(gè) Demo而是去管理控制臺把所有變化對照了一遍。四個(gè)維度最有價(jià)值Number Of Pending Messages隊(duì)列里待消費(fèi)的消息數(shù)量。如果這個(gè)數(shù)字一直漲說明消費(fèi)端有問題。Number Of Consumers當(dāng)前有多少消費(fèi)者掛著。Messages Enqueued / Dequeued入隊(duì)和出隊(duì)的累計(jì)數(shù)能看出積壓到底是多少。Blocked Time連接被阻塞的時(shí)間如果很大說明消費(fèi)者處理不過來。先建立這套觀察手段后面排坑會省很多時(shí)間。空口說“消息丟了”“隊(duì)列卡了”很容易被運(yùn)維懟把控制臺截圖甩過去才是正確的溝通方式。4. 隊(duì)列模式和發(fā)布訂閱模式看起來代碼差不多語義差遠(yuǎn)了JMS 里最繞、也最影響選型的就是兩種消息模型點(diǎn)對點(diǎn)模式Queue和發(fā)布訂閱模式Topic。很多初學(xué)者能分別跑通但沒搞明白為什么需要兩種。4.1 Queue一條消息只被一個(gè)消費(fèi)者取走點(diǎn)對點(diǎn)模型下一條消息只會被一個(gè)消費(fèi)者成功接收。你可以啟動多個(gè)消費(fèi)者實(shí)例同時(shí)消費(fèi)同一個(gè)隊(duì)列ActiveMQ 會自動做負(fù)載均衡把不同消息分發(fā)給不同的消費(fèi)者。這像是一堆快遞包裹放在驛站多個(gè)配送員各自拿走一部分每個(gè)包裹最終只會被一個(gè)配送員取走。這個(gè)模型適合“任務(wù)分發(fā)”場景比如一批待處理文件10 個(gè) worker 搶占處理比如訂單狀態(tài)變更庫存服務(wù)和積分服務(wù)如果都要處理就不能用同一個(gè) Queue因?yàn)橄⒅唤o一個(gè)人。這里我補(bǔ)充一個(gè)容易誤解的點(diǎn)多個(gè)消費(fèi)者消費(fèi)同一個(gè)隊(duì)列和 JMS 1.1 里的 QueueReceiver 概念有細(xì)微差別。如果兩個(gè)消費(fèi)者的selector條件互斥消息可能會按條件被分流但默認(rèn)無 selector 時(shí)就是平均分發(fā)不是廣播。4.2 Topic一條消息廣播給所有訂閱者發(fā)布訂閱模型下一條消息會被所有“當(dāng)前活躍訂閱者”都收到。這像是廣播喇叭誰在聽誰就能聽見。Topic 模式下沒有“競爭消費(fèi)”的概念消費(fèi)者訂閱同一個(gè) Topic各自都能收到全量消息。但 Topic 有一個(gè)關(guān)鍵限制默認(rèn)情況下非持久訂閱者只在連接期間且保持訂閱狀態(tài)時(shí)才能收到消息。如果消費(fèi)者先掛了生產(chǎn)者后發(fā)消息這個(gè)消費(fèi)者重啟之后是收不到“離線期間”的消息的。這讓我當(dāng)初很意外因?yàn)樗?Queue 的行為明顯不一樣——隊(duì)列里消費(fèi)者掛多久都不怕消息會積壓著但 Topic 不會。要解決離線訂閱丟失的問題JMS 提供了持久訂閱Durable Subscription。持久訂閱狀態(tài)下Broker 會為這個(gè)訂閱者保存未消費(fèi)的消息等它上線后再推送。4.3 代碼對比一條線上隊(duì)列一條線上廣播Queue 和 Topic 的代碼結(jié)構(gòu)幾乎一致只有兩行不同——目的地對象和創(chuàng)建方式。// 消費(fèi)者隊(duì)列模式 Queue queue session.createQueue(DEMO.ORDER); MessageConsumer consumer session.createConsumer(queue);// 消費(fèi)者Topic 模式非持久訂閱 Topic topic session.createTopic(DEMO.NEWS); MessageConsumer consumer session.createConsumer(topic);持久訂閱的消費(fèi)者寫法會多一點(diǎn)Topic topic session.createTopic(DEMO.NEWS); // 需要為訂閱者設(shè)置唯一名稱 MessageConsumer consumer session.createDurableSubscriber(topic, news-consumer-1);createDurableSubscriber第二個(gè)參數(shù)是訂閱 IDBroker 用這個(gè) ID 區(qū)分不同的持久訂閱者。如果你用相同的訂閱 ID 連接兩次第二次會替代第一次的訂閱關(guān)系。發(fā)送端完全一樣MessageProducer producer session.createProducer(topic); producer.send(session.createTextMessage(財(cái)經(jīng)早報(bào)));4.4 選型判斷別讓“感覺好用”替你做決定學(xué)習(xí)期間我總結(jié)了一個(gè)很簡單的判斷規(guī)則同一業(yè)務(wù)事件如果多個(gè)系統(tǒng)需要各自獨(dú)立處理用 Topic如果一個(gè)任務(wù)的多個(gè)實(shí)例競爭處理同一批消息用 Queue。舉兩個(gè)對比場景訂單創(chuàng)建后觸發(fā)庫存扣減、積分增加、短信通知這是“一魚多吃”三個(gè)系統(tǒng)各自消費(fèi)同一事件應(yīng)該用 Topic 或給每個(gè)消費(fèi)者建獨(dú)立 Queue。秒殺活動里有 50 萬條搶購請求后面有 10 臺冪等處理服務(wù)實(shí)例消化這是“任務(wù)競爭”應(yīng)該用 Queue。更常見的企業(yè)做法是“混合使用”用 Topic 接收領(lǐng)域事件然后每個(gè)訂閱者內(nèi)部再用 Queue 做異步削峰。初學(xué)階段先別追求花哨能把 Queue 和 Topic 的邊界吃透就超過了大多數(shù)人。5. 可靠消息的底層機(jī)制確認(rèn)、事務(wù)、持久化一次講清消息中間件最常被問的一句話是“消息到底會不會丟”答案取決于三層配置消費(fèi)者的確認(rèn)方式、會話的事務(wù)邊界、Broker 的持久化策略。每一層都直接影響消息的可靠性但要組合起來才有意義。5.1 確認(rèn)模式消費(fèi)者收完之后Broker 才敢刪消息主動和異步監(jiān)聽之外Session 的確認(rèn)模式?jīng)Q定了消息何時(shí)被“算作處理成功”。在 JMS 1.1 里有四種常見模式模式行為適用場景AUTO_ACKNOWLEDGE消費(fèi)者收到消息后自動確認(rèn)receive 返回或 onMessage 返回時(shí)業(yè)務(wù)處理邏輯簡單、處理失敗可以接受消息丟失的場景CLIENT_ACKNOWLEDGE需要手動調(diào)用 message.acknowledge() 確認(rèn)處理流程較復(fù)雜希望確認(rèn)時(shí)機(jī)由業(yè)務(wù)代碼控制的場景DUPS_OK_ACKNOWLEDGE允許重復(fù)消息延遲確認(rèn)性能好可容忍重復(fù)消費(fèi)的統(tǒng)計(jì)類場景SESSION_TRANSACTED配合事務(wù)會話使用需要保證消息收發(fā)與業(yè)務(wù)操作原子一致的場景最常見的坑是使用 AUTO_ACKNOWLEDGE但是消費(fèi)者在onMessage里處理到一半拋異常。此時(shí)消息實(shí)際上已經(jīng)被確認(rèn)了Broker 會把它刪除重啟消費(fèi)者后這條消息不會再出現(xiàn)處理自然就丟失了。正確的做法是——如果處理失敗需要重試要么用 CLIENT_ACKNOWLEDGE 模式收到消息后先不確認(rèn)處理成功再調(diào)用message.acknowledge()要么開啟事務(wù)處理失敗就session.rollback()。CLIENT_ACKNOWLEDGE 模式有一個(gè)細(xì)節(jié)很容易忽略acknowledge()不只是確認(rèn)當(dāng)前這條消息而是確認(rèn)這個(gè) Session 里“已經(jīng)消費(fèi)但尚未確認(rèn)”的所有消息。如果同時(shí)消費(fèi)了多條且逐條處理調(diào)用一次 acknowledge 會把這批全確認(rèn)了。要精確控制單條消息必須結(jié)合事務(wù)會話每個(gè)事務(wù)處理一條就 commit 一次。5.2 事務(wù)會話讓發(fā)送和接收具備原子性connection.createSession(true, Session.SESSION_TRANSACTED)開啟了事務(wù)模式。事務(wù)模式下生產(chǎn)者的發(fā)送動作不會立即生效而是要等session.commit()才真正把消息提交給 Broker消費(fèi)者的接收動作也不會立即被確認(rèn)而是等 commit 時(shí)才確認(rèn)這一批消息。如果業(yè)務(wù)處理失敗調(diào)用session.rollback()消息會被回滾之后可以再次消費(fèi)。事務(wù)會話對“發(fā)送”和“接收”是獨(dú)立的語義。比如在一個(gè)服務(wù)里先接收消息 A處理后發(fā)送消息 B然后 commit。這意味著 A 的消費(fèi)確認(rèn)和 B 的發(fā)送是同時(shí)生效的。這個(gè)組合非常實(shí)用相當(dāng)于把“業(yè)務(wù)成功了才把消息標(biāo)記為已處理”這一個(gè)要求交給中間件來保證。不過事務(wù)也不能濫用。事務(wù)越大、批量越大Broker 的鎖競爭和日志壓力越大。經(jīng)驗(yàn)值是一個(gè)事務(wù)里處理的業(yè)務(wù)消息量控制在幾十條以內(nèi)尤其在高并發(fā)場景下過大的事務(wù)反而會成為瓶頸。5.3 持久化消息存儲到磁盤進(jìn)程重啟才能恢復(fù)ActiveMQ 默認(rèn)將消息保存在內(nèi)存里同時(shí)提供 KahaDB 作為默認(rèn)持久化方案它會將消息寫入本地磁盤。對生產(chǎn)環(huán)境來說強(qiáng)烈建議開啟持久化并且生產(chǎn)者發(fā)送時(shí)設(shè)置DeliveryMode.PERSISTENT??梢赃@樣理解二者的關(guān)系持久化確保 Broker 重啟后消息還在PERSISTENT 發(fā)送模式確保每條消息都走持久化存儲。即使 Broker 配置了 KahaDB如果生產(chǎn)者發(fā)送時(shí)用的是非持久化模式消息還是可能因?yàn)?Broker 崩潰而丟失。ActiveMQ 的主配置文件中persistenceAdapter的部分默認(rèn)就是 KahaDBpersistenceAdapter kahaDB directory${activemq.data}/kahadb/ /persistenceAdapter學(xué)習(xí)階段可以刻意做一次“重啟測試”發(fā)送一條持久化消息但消費(fèi)者不啟動然后重啟 Broker再啟動消費(fèi)者觀察消息是否還在。我第一次測的時(shí)候發(fā)現(xiàn)消息還在其實(shí)很不解——后來意識到這就是持久化在起作用。5.4 組合起來可靠消息的生產(chǎn)端配置怎么開把三層機(jī)制組合起來一個(gè)穩(wěn)妥、可靠的生產(chǎn)者配置看起來是這樣Session session connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer session.createProducer(queue); producer.setDeliveryMode(DeliveryMode.PERSISTENT); producer.setTimeToLive(60000); // 消息有效期為 1 分鐘 producer.send(message);消費(fèi)者側(cè)如果對處理結(jié)果有嚴(yán)格成功要求通常選擇事務(wù)會話Session session connection.createSession(true, Session.SESSION_TRANSACTED); MessageConsumer consumer session.createConsumer(queue); TextMessage msg (TextMessage) consumer.receive(); // 處理業(yè)務(wù)邏輯比如更新數(shù)據(jù)庫、調(diào)用外部接口 // 都成功后提交 session.commit(); // 失敗則回滾 session.rollback();這里涉及一個(gè)進(jìn)階考量如果消費(fèi)者處理到一半進(jìn)程崩了事務(wù)尚未 commitBroker 會重新投遞這條消息。重新投遞可能導(dǎo)致重復(fù)消費(fèi)所以消費(fèi)者的業(yè)務(wù)邏輯必須做冪等。消息中間件本身并不能徹底避免重復(fù)投遞它只能保證“至少一次”不能保證“正好一次”。這句話我建議所有初學(xué)者刻在腦子里。6. 學(xué)習(xí)過程中實(shí)際踩過的四個(gè)坑這部分是我最想寫的。Demo 都能跑通但生產(chǎn)要素一進(jìn)來問題就花樣百出。下面四個(gè)坑都是我真實(shí)遇到過的按照排查鏈路寫出來方便你以后對著復(fù)現(xiàn)。6.1 第一個(gè)坑啟動 Broker 就報(bào)端口占用現(xiàn)象執(zhí)行./activemq start后控制臺報(bào)java.net.BindException: Address already in use: JVM_Bind。排查我把堆棧里暴露的端口號 61616 用lsof -i:61616查了下發(fā)現(xiàn)是本機(jī)之前跑過一個(gè)沒關(guān)干凈的 ActiveMQ 實(shí)例。這提醒我兩個(gè)習(xí)慣一是問題定位要先確認(rèn)端口占用而不是盲目重裝二是啟動前用./activemq stop或jps查看已有 Java 進(jìn)程別把多個(gè) broker 實(shí)例混在一起跑。如果你是在同一臺機(jī)器上跑多個(gè) broker 做集群學(xué)習(xí)必須修改conf/activemq.xml里的 transportConnector 端口還要調(diào)整conf/jetty.xml里的管理端口否則必然沖突。6.2 第二個(gè)坑隊(duì)列里明明有消息消費(fèi)者卻收不到現(xiàn)象生產(chǎn)者發(fā)送成功控制臺里Number Of Pending Messages是 5但消費(fèi)者啟動后一條都沒收到。排查過程我先確認(rèn)消費(fèi)者確實(shí)連接上了 broker——控制臺的 Connections 頁面能看到消費(fèi)者連接。然后檢查消費(fèi)的隊(duì)列名發(fā)現(xiàn)生產(chǎn)者和消費(fèi)者用的隊(duì)列名不一致。這個(gè)屬于低級錯(cuò)誤。但還有一個(gè)更隱蔽的原因困擾了我更久消費(fèi)者連接沒調(diào)用connection.start()。我照著網(wǎng)上某篇文章只創(chuàng)建了 connection 和 session沒有顯式調(diào)用 start。這個(gè)操作在“異步監(jiān)聽 等待”的例子中看起來沒問題但實(shí)際消息分發(fā)一直沒有真正開始。補(bǔ)上connection.start()后一切正常。這個(gè)教訓(xùn)讓我從此養(yǎng)成了一個(gè)習(xí)慣JMS 樣板代碼一定逐行核驗(yàn)別漏掉生命周期方法。6.3 第三個(gè)坑發(fā)布訂閱模式下“先啟動生產(chǎn)者后啟動消費(fèi)者”丟消息現(xiàn)象我用 Topic 建模一個(gè)廣播消息先運(yùn)行生產(chǎn)者發(fā)了兩條消息再啟動消費(fèi)者結(jié)果消息一條都沒收到。排查過程這其實(shí)是 Topic 模型的正常行為不是 bug。非持久訂閱者不會收到訂閱之前的消息。我當(dāng)時(shí)誤以為 Topic 和 Queue 一樣消息會先積壓在 broker 里消費(fèi)者一來就全推給它。搞清楚這個(gè)機(jī)制后我重新設(shè)計(jì)了一版客戶端先啟動消費(fèi)者并保持在線再觸發(fā)生產(chǎn)者發(fā)送消息就正常收到了。如果業(yè)務(wù)上確實(shí)需要“離線訂閱不丟消息”就要在消費(fèi)端使用createDurableSubscriber。注意持久訂閱的訂閱 ID 一旦創(chuàng)建就不能隨意變更否則舊的持久訂閱消息將無法再被消費(fèi)會一直堆積在 broker 中。6.4 第四個(gè)坑重復(fù)消費(fèi)引發(fā)的臟數(shù)據(jù)問題現(xiàn)象消費(fèi)者消費(fèi)消息后更新了數(shù)據(jù)庫但進(jìn)程在數(shù)據(jù)庫事務(wù)提交后、Session 提交前崩潰了重啟后同一消息被再次消費(fèi)數(shù)據(jù)庫被更新了兩次。排查過程當(dāng)時(shí)我用了事務(wù)會話以為有事務(wù)就萬事大吉。實(shí)際上事務(wù)會話保證的是“消息確認(rèn)和業(yè)務(wù)處理的原子性”但“業(yè)務(wù)處理”本身如果不在同一個(gè)數(shù)據(jù)庫事務(wù)里狀態(tài)就無法對賬。后來我用了一個(gè)冪等方案消息體帶業(yè)務(wù)主鍵消費(fèi)者在處理前先查一下數(shù)據(jù)庫是否已有對應(yīng)記錄有就直接返回沒有才執(zhí)行業(yè)務(wù)并落庫且主鍵唯一索引兜底。這樣即使消息重復(fù)投遞也不會產(chǎn)生重復(fù)數(shù)據(jù)。這個(gè)坑給我最大的啟發(fā)是消息中間件只保證傳輸層面的至少一次投遞消費(fèi)端必須自己做好冪等。你以為中間件幫你解決了所有問題它只是幫你把問題限定在了一個(gè)可控范圍內(nèi)剩下的還要靠自己的業(yè)務(wù)設(shè)計(jì)。7. 學(xué)習(xí)收尾時(shí)的一些心得過完前面這六個(gè)章節(jié)后我又重新回頭看了最初促使我開始學(xué)習(xí)的那個(gè)“同步調(diào)用雪崩”場景。用上 ActiveMQ 之后其實(shí)還沒有結(jié)束還配套做了消費(fèi)并發(fā)度控制、數(shù)據(jù)庫連接數(shù)控制、失敗重試隊(duì)列、監(jiān)控告警才敢說這個(gè)鏈路基本可靠了。這個(gè)認(rèn)知我覺得比學(xué)會 API 本身更重要消息中間件解決的是通信模式問題但一個(gè)系統(tǒng)的穩(wěn)定性永遠(yuǎn)要靠整體設(shè)計(jì)不會因?yàn)橐胍粋€(gè)組件就自動變好。如果你正在學(xué) JMS 和 ActiveMQ我給三條很實(shí)在的建議。第一條不要只看著我的代碼抄一定自己把生產(chǎn)者、消費(fèi)者、管理控制臺三樣對起來跑通一個(gè)完整的收發(fā)。第二條把 Queue 和 Topic 的區(qū)別多做幾個(gè)實(shí)驗(yàn)包括離線訂閱、多個(gè)消費(fèi)者消費(fèi)同一個(gè)隊(duì)列、持久訂閱恢復(fù)這些體驗(yàn)比背概念管用太多。第三條第一次接觸消息可靠性的時(shí)候強(qiáng)制自己回答“消息什么時(shí)候會丟、重復(fù)消費(fèi)怎么兜底、中間件重啟后消息還在不在”這三個(gè)問題回答完再繼續(xù)深入事務(wù)和持久化否則知識很容易停留在 API 層面。最后分享一個(gè)小技巧學(xué)習(xí)期間可以在 ActiveMQ 的配置里臨時(shí)把日志級別調(diào)成 DEBUG重點(diǎn)看 messages 相關(guān)日志和 session 相關(guān)日志。以前我一直覺得中間件日志太多不看后來排查那兩次詭異問題時(shí)DEBUG 日志里的 broker 內(nèi)部流轉(zhuǎn)信息幫了大忙。日志是排查問題最早出手的武器不要等到控制臺里消息都詭異了才想起來翻日志。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
久久人妻丝袜一区二区三| 九九九热精品| 热久久99999| 97超碰精品图片| 12一15性XXXX粉嫩国产| 思思热免费视频观看| 丝袜喷水在线| 亚洲欧洲激情卡通另类文学四射小说网站 | 午夜福利 成人 91| 人人干人人操人人..com| 日韩国产品视频中文字| 欧美日韩欧美| 一级特级aaaa毛片免费观看| av无线看| 国产妇女精品视频青青草| 亚洲情色电影网| 亚av顶级裸体一区二区三区四区五区 | 欧美激情一| 大学生美女口爆| 亚洲色图日韩精品| 亚洲无限观看| 国内毛片婷婷六月色| 久久久久13| 国产农村妇女毛片精品久久| 欧美v亚洲v日韩v最新在线二区| 欧美一区二区情色| 好爽视频在线观看视频 | 久操电影网| 久久夜夜| 久久精品天美| 亚洲中文国际强奸字幕| 成熟熟女国产精品一区二区| 91精品女厕偷拍视频| 少妇与黑人高潮在线| 囯产精品久久久久久久久久二区三区| 97超碰美国| 变态综合色| 亚洲色色色| 亚州欧美在线| 狠狠操狠狠插| 激情另类激情| 丁香色婷婷| 人人操人人肉久久精品| 久久婷婷色综合一区二区三区| 欧美激情精品久久久久久| 亚洲男人的天堂在线看| 久操com| 久噜噜| 国产人伦a片信息免费片| 91骚妇| 久久无码一区二区二三区性色| 97久久精品亚洲| 超碰美国| 青青草色情网站视频| 亚洲高清无毛一区二区| 加勒比少妇AV婷婷六月天超碰超碰| 中文字幕97| 久久伊人青青草| 国产成人无码网站在线视频| 欧美亚洲小说| 91超碰碰在线| 亚洲欲| 婷婷激情五月| 女人喷水视频在线观看| 久久熟女嫩草成人片免费| 1769一区二区| 9 1果冻精品视频| 性欧美另类高清| 酒色综合网| 亚洲城人男人的天堂| 久久这里只精品免费福利| 亚洲色图 图片| 亚洲天堂区| 国模精品一区二区三区苹果色戒| 色色无码| 亚洲激情综合另类男同| 黄色片大香蕉| 97激情97激情| 996热| 国产精品操| 日日干夜夜操视频h| 亚洲熟女性高潮久久久| 午夜福利 成人 91| 亚州色图欧美| 精品九九九九九九九| 中文字幕一区日韩精| 超碰95| 中国黄色特级精品一区二区三区片| 亚洲自拍天堂| 婷婷精品久久av影视| 东京热激情视频一二三区| 超碰 另类 欧美| 波多野42部无码喷潮在线观看| 精品丰满熟妇人妻一区| 有码人妻系列| 亚洲人精| 在线观看国产黄色| 亚洲国产91精品一区二区久久| 中文字幕一区二区三区四五区| 日本一区99| 日韩啪啪啪啪啪| www.av在线视频| 爱爱啊啊啊| 亚洲中亚日激情视频| 亚洲最大的黄色电影网站。| 91狠婷| 久久久久国产精品片区无码直播| 国产在线观看一区二区三区| JuliaAnn丝袜熟女系列| 超碰久久.com| av草草在线电影| 99 国产丝袜在线| 日韩AV一区二区三区三州三州| 国产成人久久久精品免费AV| 五月天啪啪| 国产亚洲精品av一区| 精品国模无码| 国产精品直播在线观看直播| 国产传媒日韩| 日韩无码一区二区三区| 97久久久久久久久久| 欧美精品双插| 亭亭在线资源| 亚洲老司机123专区| 国产污视频麻豆传媒一区二区| 亚洲欧美精品一区天堂久久| 色哟哟1区2区| 欧美在线|亚洲| 走光一区92下载| 日韩淫色网| 天天影视射综合网| 久久精品成人一区二区三区蜜臀| 欧美日韩美女精品久草一区二区三区| 青青草原香蕉日本Ap| 色综合 加勒比| 四虎免费在线播放| 东京热毛片177b2viP| 啊啊啊啊无码| 青春草莓视频在线观看网址| 69XX一中文字幕人妻91| 欧洲黄色网| 亚洲国产精品V?在线播放| 国产精品爆乳懂色蜜乳| 影音先锋日本一区二区| 人人摸人人摸人人干| 在线播放成人高清免费视频 | 美女尤物人人操| 亚洲熟女乱色一区二区三区| 日熟女| 国产精品高潮久久久无码| 国产又黄又粗的视频| 欧美偷拍区| 中文字幕精品一区二区精| 日韩无码黄色片| 人人做人人妻人人夜视频| 黄aaaaaaaaaaaaaaaaaa色网站| 国产欧美日韩在线不卡第一页| 欧美黄色大香蕉一区二区| 亚洲国产欧美中日韩成人综合视频| 肉嘟嘟www视频在线观看高清| 一区在线观看中文字幕| 无码国产精品午夜不卡(| 亚洲色图 欧美热图 清纯唯美 另类自拍| 国产夫妻一区二区| 欧美后入式| 大香蕉中文在线| 福利视频香蕉免费一区二区在线| 97摸视频| 日韩99神马视频播放| 日本一久是| 天天综合亚洲综合| 欧美成人性爱视频大全| 一本一首道人妻少妇免费久久| 天天在线91| 人人操人人摸人人骑| 精品一区二区在线针对华人免费观看这里只有精品免费观看 | 一类av片在线看| 97色在线| 欧美韩国你懂得在线 | 北京专精特新企业招聘信息| 日韩78m视频| 日韩91网| 精品一啪| 四虎在线播放| 久久精品一区二区三区四区五区| 亚洲天堂人妻熟妇视频| 三级片大波波| 97久久久久| 国产毛片久久久久久久| 无码9区| 伊人成人情色综合| 又大又大又大又粗爽高潮观看| 久久毛卡| 亚洲一区二区专区-国产丝袜精品丝袜-成人AV| 国产60页| 精品一区二区啪啪啪| 日日嗨AV一区二区夜夜| 自拍视频一区在线观看| 欧美日本天堂| 十八禁的黄污污免费网站| 久久人人爽爽爽人久久久| 中文字幕、久久精品国产2020、久久综合久久自在自线精品自、亚洲 | 天天做天天爱夜夜爽毛片试看| 国产亚洲精品自在线亚洲情侣| 熟女天天干| 好吊色综合| 簧片免费看视频| 亚洲官网在线| 亚洲高清无毛一区二区| 亚洲免费日韩在线一区二区| 精品一区二区三区国产| 亚熟hd视频在线| 国产无码精品久久久久久| 色香蕉影院| 日韩精品系列| 亚洲中文字幕三级在线| 97中文综合| 性爱边摸边日免费AV| 91美女在线看| 日韩丰满熟妇| 97超碰超| av中文字幕在线熟女| 友优传媒精品在线一区二区| 另类小说五月天| 男人的天堂VA| 精品人人| 日日夜夜精品| 亚州色阁| 极品极品色影院| 国产日韩中文字幕欧美| 大香蕉久久| 天天综合网91| 色婷婷五月天| 国产一区二区三区白丝| 操逼999| 国产亚洲欧美每日在线| 欧美色图 人妻| 国产一级特黄大片处女| 天美传媒AV国产在线| 艹精品| 久操视频免费观看| 天天综合91在线| 91老司机精品| 国产精品久久久777| 久久精品福利影院| 亚洲双插| 欧美美女自慰一区二区三区| 樱花蜜乳av| 国产久9| 丁香六月婷| 久久精品国产亚洲AV清纯| 麻豆AV短剧| 午夜福利精品| 久久系列| 人人妻人人色一区二区三区| 97国产色综合| 很黄很色的视频在线观看| 天天综合网1| 日本女人操逼| 天天躁日日躁AAAAXXXX国产| 91欧| 国产中文字幕在线观看| 色999人与兽| 日韩色| 亚洲久久久| 激情四射五月天| 久色网| 精品人妻中文字幕4399| www亚洲欧美| 大香蕉在线86| 亚洲欧美精品一区天堂久久| 亚洲成人久久一区二区| 亚欧无码线免费观看视频| 欧美精品 - 91爱爱| 国产精品久久久无码AV网站| 曰韩中文人妻视频| 大香蕉狠狠爱| 久湿久久| 青草香蕉网| www.91色综合| 日韩一区二区三区四区五区| 级做a爱无码性色永久免费| 久久久精品中文字幕麻豆| 天天摸天天插天天日| 午夜福利成人免费视频| 精品人妻一区二区视频| 久热影视| 日本操逼无码| 国产传媒日韩| 99精品久久| 欧美亚洲色的图| 九九九九日本| 亚洲色堂免费视频| 亚洲操操| 操逼逼无码| 少妇人妻太紧太深av| 欧美色图 色综合图| 日韩 女同 综合| 日日夜夜骚| 天天日天天爽| 91久久久久久| 99自拍视频在线观看| 天堂а√在线最新版在线| 风月影院十八禁| 东北女人高潮视频| 日本男人天堂| 人妻精品一区二区| 九九精品网| 免费99精品国产自在在线| 丰满搜索结果 -第18页- 久久高清无码 | 天堂蜜桃无码视频一区二区| 婷婷五月天激情小说| 青青草丝袜在线视频| 亚洲AV麻豆Aⅴ无码电影一| 国产精品高朝久久久久久久| 啊啊啊快操我视频| 中文字幕88av在线| 97超碰中文| 男人的天堂无码| 99热这里只有是精品10| 久久噜| 91人妻久久久久久久久久久久久| 久操大香蕉超碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰 | 国产精品熟女乱伦| 99在线观看| 日韩啪啪啪啪啪| 久久网亚洲| 久草毛片| 99re98| 国产无码精品成人| 极品美女嘿咻| 久操网线| 乱论91| 超碰69| 爱欲AV| 夜夜夜久久| 男人天堂2019亚洲| 亚洲精品国产精品乱码不卡| 囯产精品强| 精品一区二区三区18| 久久6热精品99视频| AV色图| 亚州,欧美在线| 久操97| 中文字幕一区二区三区字幕| 日韩操人| 欧美色图成人网一区二区 | 国产极品粉嫩馒头一线天av| 欧美天天干| 九九aV| 偷拍欧美激情| 亚洲人综合| 久久无码精品| 日va操| 97香蕉碰碰人妻国产欧美| 超碰亚洲97| 伊人aaa| 欧美国产精品| 国产婷婷综合在线观看| 日韩免费人妻色情网站| 夜夜操天天肏| 国产AV高清AV无码| 狼狼色丁香久久婷婷综合五月 | 久久人妇| 激情五月天社区| 超碰成人公开| 熟妇人妻精品一区二区| 在线日韩日本亚洲国产| 日本一本道A级黄色毛片试看60分钟| 久热超碰| 欧日韩一二三f区| 一级AV性爱| 欧美刺激色黄片免费看| 激情文学 亚洲图片| 色牛aV| 久久精品店| 人妻在线中出视频| 日韩一级二级三级| 国产麻豆一级精品视频| 国产白丝在线| 麻豆国产97在线| 色吧五月| 加勒比性爱成人在线| 日韩av在线精品观看| 91狠狠综合久久久| 超碰精品人妻狠狠干| 国产精品又黄又猛又粗| 日韩一级成人毛片免费观看 | 日韩操啪| 国内精品久久久久影院亚洲| 精品一久久久| 大香蕉2017| 国产东北女人在线视频| 人妻少妇色综合| 无码不卡亚洲成?人片| 国产av尤物| 在线播放欧洲免费av| 十八岁啪啪视频免费看| 欧美大片天天看| 一区二区三区在线美女| 日韩二级| 岛国免费黄色网址| 青青伊人加勒比海| 人人做人人妻人人夜视频| 久草在| av爱爱爱| 亚熟hd视频在线| 免费黄色片。| 成人黄页| 立川理惠无码一区二区| 69久久| 天天天天干| 亚洲欧美情色| 欧美一级色| 97超碰精品图片| av凤凰久久久| 亚洲91射| www.色婷婷| 国产97在线 | 亚洲| 亚洲.欧美.丝袜.中文.综合| 夜草网站| 熟妇高潮精品一区二区三区下载| 色婷婷综合久久久久中文一区二区 | 精品无码久久久久久久杏吧| 日逼逼免费看| 久久久九97| 中文字幕乱妇免费视频| 女同性恋一区二区三区精品视频| 天天日天天搞天天干| 99re这里| www.色婷婷| 成人精品在线免费视频| 亚洲熟女一区| 日本一级一级一级一级| 国产精品白领在线观看| 亚洲综合性网址| 日韩成人网址| 凹凸视频在线一区二区| 东京热熟女亚洲视频网站| 欧美人人AAA| 久久系列| 青青草玖玖爱| 大奶啊啊好爽 | 亚洲丝袜色| 国产精品午夜福利亚洲综合网| 亚洲熟久久| 综合久久99| 啊啊啊好舒服视频| 国产精品第二页| 亚洲另类在线观看| 老熟妇一区二区三区…| 91高潮| 日日嗨AV一区二区夜夜| 91日韩在线| 日韩精品色呦呦| 午夜精品久久久久久久男人的天堂 | 国产乱码精品久久久久久| www.国产高潮精品| 色综合色色| 久久性视频| 国产精品久久久久婷婷二区次| 亚洲91在线| 日欧操屄视频| 欧美亚州综合图片| 怡红院视频在线| 久久精品国产亚洲AV高级北京| 免费视频观看60秒| 97干在线看| 2020国产精品| 丰满翘臀美女影院视频| 亚洲中文字幕熟女少妇一区二区| 欧美国产一区二区三区麻豆传媒| 日本在线不卡123| 日韩精品永久在线观看| 久久久久久亚洲Av无码| 97香蕉网| 人妻丝袜一区二区三区在线| 精品制服美女中文一区二区三区| 乱理日韩中文| 又大又白奶子| 337p大胆噜噜噜噜噜91Av| 国产精品无套内谢| 九九热久久99精品re| 水多多映视AV| 亚洲91在线| 久久粉色| 五十路三区在线| 97超碰精品图片| 精品制服美女中文一区二区三区| 又摸又舔在线观看网站| 97在线免费观看视频| 久久欲| yiqicaoav| 884t在线| 69人妻精品丰满熟女区| 午夜激情床戏激情| 欧美久久九九| 天天欧美色| 欧美嗯啊……在线观看视频免费| 99热官网| 在线中文字幕极品av| 欧美日韩国产另类综合| 日本操逼视频不卡直接放| 亚洲欧洲av影音| 人人模人人看| 国产黄色影片在线观看| 亚洲一级性爱视频免费看| 在线免费观看日韩一区| 免费簧片在线观看| 密乳AV免费观看| 18禁的网站在线| 乱伦AVxx| 超碰免费人人| 超碰久久中文| 亚洲情色一区综合| 国产亚洲日本| 亚洲天堂少妇| 免费视频一二三区| 国产精品久久久吖| 丰满人妻一区二区三区四区| 亚洲高清无码在线桃色| 99性爱| 五月开心网| 加勒比在线视频| 天天做天天爱天天爽AV| 国产乱码久久久久久| 另类图片五月天| 亚洲国产精品无石码久久| 亚洲中字幕日本一区二区三区| 夜夜草我| 91啪啪视频| 97中文天堂| av东京热男人的天堂| 青青操日韩| 天天综合网网欲色| 网页导航五月天免费一二三区| 久久人人爽人人爽人人片Ⅴ| 嗯嗯嗯不要不要免费视频| 中文字幕精品久久久久人妻红杏ⅰ| 天天草AV| 免费a v| 无码久久国产| 亚洲aV无码成人在线观看| 久久久啊啊| 五月开心久久AV官网| 久久啊啊| 亚洲精品中文字幕一区在线视频| 97天天摸天天碰| 91无摭挡| 乱伦日本中文自拍| 人妻av在线| 精品91摸| 欧洲站一级二级三级h| 国产成人精品网站| A级片日韩欧美国产欧美视频精选观看| 一区操逼日比视频| 久久9精品视频| 久操免费电影| 婷婷午夜成人色中色| 九色 人妻 大香蕉| 爱丝福利| 亚洲天堂中文字| 日韩女优中文字幕| 精品国产乱码久久久久久久| 伦伦成年午夜免费视频| 亚洲综合性感在线| 天天久久久久久| www.伪伪| 日韩ab网| 97超碰久久| 午夜婷婷| baiduhicn.com。| 嗯嗯啊啊用力视频免费| 91亚洲色图| 屁股久久久久久| 欧美成人午夜免费福利785| 韩美日操逼| 婷婷五月天成人| 极品五月天噜噜| 人人操人人精品影片| sss视频华人在线| 亚洲欧美另类少妇精品| 日本色日夜干| 人人操人人uiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii | 日曰骚久久精品| 浪人综合网| 99re99视频在线免费观看| 欧美特大AA级黄片| 欧美se亚洲| 日韩啊V| 久久99国产综合精品女同| 三四中文字幕| 久久亚洲不卡| 九热中文字幕| 久久发布国产伦子伦精品| 亚洲情欲| 伊人国产视频| 在线中文字幕极品av| 成人久久久精品| 久久久久9| 国产97在线 | 亚洲| 九九九久千久久激情蜜桃在线看 | 啊啊啊啊啊啊在线| 美女人妻色网站| 91东京热男人的天堂| 1000午夜黄色| 国产大学生高潮在线播放| 婷婷10月天青娱乐| 色情综合网| 中文字幕欧洲有码| Julia在线播放亚洲久久| 超碰人妻久久| www.狠狠| yw尤物av无码点击进入麻豆| 无码人妻丰满熟妇奶水区毛片| 伊人丁香五月婷婷| 99re热| 日本99热| 午夜啪| 欧美91网站| 强奸a片网| 男人天堂网站| 亚洲涩涩| 五月婷在线| 欧美亚洲自拍另类人妻| 国产精品久久久九九九| 女人爽到高潮潮喷18禁网站 | 大肉棒导航| 日本日皮视频逼| 国产路线专区| www.高清无码诱惑一区.com | 日韩精品啪啪啪| 欧美少妇第一页| 欧美性爽xyxOOOO| 97超碰精品成| 97超碰碰碰| 中国一级特黄大片护士| 97国产中文| 中文字幕在在线观看网站| 在线观看AV片| 伊人久久大香线蕉无码| 亚洲AV成人无码一二三久久| 999久久久免费精品国产牛牛| 久热大香蕉| 亚洲婷婷丁香在线| 色偷偷综合91久久噜噜| 久jiu久神马影院| 成人一级性爱| 天天肏视频| 久久久网一区| 午夜精品99久久久久传媒| 久久人人爽爽人人爽人人片αV| 91欧美www| 91久久久老司机| 夜夜操2028| 青青伊人久久| 日本亚洲vr欧美不卡高清专区| 精品亚洲国产成人精品| 91一区二区三区蜜桃| 超碰碰97资源站| 疯操AV| 日产123区精品免费观看| 五十路熟女工口 | 东京热伊久| 好吊色综合| 91n免费处女| 91欧美偷拍| 自拍第一页| 中国少妇啪啪视频| 俺去俺来也在线www| 伊人色综合欧美| 欧美大香蕉97| 97色欧州| 国产传媒1234区| 亚洲精品一二三四区| 欧美制服另类丝袜| 精品妇女一区二区三区| 920日本午夜免费| 91中文在线| www.狠狠操| 欧美夜夜狠| 久热伊人99re| 人妻天天爽夜夜爽爽| 午夜精品99久久久久传媒| 亚洲中文字幕97久久精品少妇 | 91亚洲狠狠色| 国产丝袜啪啪| 日本不卡五区| AV乱伦专区| 天天谢天天干| 激情综合二| 欧美日韩性爱操大逼| 免费人成?大片在线播放| 8050午夜少妇无码| 午夜天堂精品久久久久91| 无码色| 肥臀熟女福利视频一区二区| 狠狠搞 亚洲91| 蜜臀99999| 91青青在线视频| 久9爱精品| 日日爱99| 伦伦成年午夜免费视频| 一级久久性爱视频| 成片免费观看视频大全| 欧美少妇大量自拍视频在线观看| 亚洲宗合电影| 粉嫩久久久久| 色九九久九九| 97久久超碰| 亚州免费啪啪视频| 婷色五月| 求求你操操我| 国产AV天美传媒一区二区三区| 亚洲色图A| 精品日韩人妻视频| 国产小黄片在线免费观看| 色色色网站| 国模不卡一本二本三电影| 超碰一区二区| 久久AV无码AV| 在线观看中文av字幕| 亚洲性爱高潮影院| 综合久久99亚洲人妻中文在线| 欧美另类丝袜熟女| 内射小黄片| 色小视频蜜乳| 久久99手机免费视频| 黄站在线免费观看| 乱伦一二三| 久久色情| 亚av顶级裸体一区二区三区四区五区| 亚洲精品国产拍免费91在线| 国产午夜福利专区综合| 日本三级日本三级99| 亚洲欧美日韩有码| 亚洲人久久久久日| 亚洲最新a在线观看| 精品国产网站| 色综合天天| 欧美最婬乱婬爆婬性视频| 一区二区三区色综合| 亚洲超碰97| 8050午夜少妇无码| 东北女人的毛片| 变态综合色| 久久社区一区二区三区| 炮色五月| 欧美成人精品欧美一级乱黄一区二…| 免费公开人人操| 精品射1999| 东北女人高潮视频| 国产区性爱在线视频秋霞豆| 欧美五区| 日韩兔费看黄片| 婷婷激情五月综合| 久久亚洲天堂| 成人精品一区二区91毛片不卡| 日韩AV电影网站| 男人天堂导航| 激情五月天社区| 欧美日韩天堂| 91精品久久久久五月天精品| 精品无码一区二区| 青青草毛片| www.99热| 日韩人妻无码不卡网站| 亚洲欧美日韩夜夜| 插B在线观看| 久久久久九九九| 亚洲淫色网中文| 国产亚洲在线观看| 国产一区自拍欧美日韩| 男人的天堂VA| 欧美大香蕉97| 五码视频在线观看| 蜜桃久久久久久| 日本一级真人黄色性爱视频| 天天日天天插| 欧美双插| 久久国产精品91| 久久国产成人精品国产成人亚洲| 丁香六月婷婷久久综合| 婷婷性网| 天天插天天干| 91色香| 国产精品天美传媒| 九九九热| 97露脸精品丝袜| 成全在线观看免费观看| 亚洲精品美女操逼| 91三级理论片播放器| 视频在线观看青青99国产| 五月天黄色激情视频| 国产精品午夜精品| 99热这里只有精品99| 超碰在线一区二区三区| 久久9亚洲| 岛国片在线视频网站| 狠狠夜色午夜久久综合在线| 欧美亚洲尤物久久| 欧美激情一| 少妇超碰在线| 亚洲欧美在线观看2021| 亚洲好色人妻| 天天躁狠狠躁av| 中出人妻中文字幕91在线| 学生妹天天看| 极品一区二区三区免费| 9色国产精品一区粉嫩 | 亚洲无线观看久久| 狠狠操一区二区| 99re69| 亚洲图片欧美另类综合免费视频大大香| 在线中文AV| 欧美日本不卡在线| 天天夜夜rb| 国产嫩草精品A88AV| 亚洲熟女一区| 日韩十八禁| 日韩紧密久久| 色成人Www精品永久观看| 日本三级精品| 久久最新视频免费观看| 国产精品亚洲一区二区三区四区| 九九九九精品精| 人妻熟女一区二区三区在线| 久草福利在线资源站| 男人天堂资源| 欧美大色交| 亚洲有薄码区日本系列中文字幕| 久久精品国产99精品亚洲蜜...| 欧美亚洲高清晰| 欧洲Au麻豆| 久久一区二区三区入口| 国产黄色视频久久| 啊啊啊慢点| 极品后入免费视频| 精品一区二区三区蜜桃臀赵总 | 欧美日韩99精品麻豆传媒| 欧美日韩亚洲一区二区在线观看| 日本三级精品| 成人十八禁日韩欧美一二三| 好吊妞转入那个网| 欧美强奸乱能| 蜜乳中文字幕a在线| 97中文字幕一区| 欧美精品双插| 95精品在线| 欧美一级做a爰片免费视频| 家庭乱伦国产精品| 2017天天插| 日本精品一区二区三| 色噜噜人妻丝袜AV资源| 欧美日不卡| 性做久久久久久免费观看软件| 精品日韩人妻精品一二三区| 久久高潮妇女视频| 91欧美少妇| 亚洲欧洲第二视频在线观看色图| 日本人妻一区二区| 丁香五月影院| 综合色播| 十八禁视频网站| 黄色欧美性爱视频| 日本一级婬片试看三分钟| 亚洲性爱成人| 九九综合九九综合| 亚洲欧洲自拍| 欧美 色 亚洲| 亚洲黄色电影| 久久成人东京热人妻| 色五月激情AV在线| 都市激情人妻一区二区青青操视频| 97久精品| 亚洲日韩AV视色| 色婷婷影院| 亚洲欧美中文日韩视频中国语 | 一级二级在线观看| 亚洲熟女诱惑| 97亚洲色图| 怡红院成人视频| 亚洲男人在线观看天堂| 婷婷国产精品一区二区| 精品一区二区2| 九九精品网| 久草免费在线一区二区| 中文字幕二区| 国产原创自拍| A 在线网址| 蜜桃久久久久久久久久久久 | 人妻人人做人人澡人人爽欧美一区| 国产精品一区二区手机看片| 日韩中文字墓| 久久精品国产亚洲AV清纯| 性色A∨91| 在线视频97| 三级日韩一区二区三区| 国产精品高清2021在线| 久久免费99精品久久久久久| 日本一区二区三区午夜观看| 国产一区二区三区视频在线看| 亚洲伊人a线观看视频| 97在线精品观看视频| 日韩欧美午夜视频在线| 国产av美女被艹的乱叫| 九九黄色网| 97色插| 色爱欲亚洲| 91处女在线视频| 亚洲丝袜二区在线| 舔足天天操天天射| 欧美乱伦专区| 久久精品毛片免费不卡| 丰满人妻av一区二区三区| 亚洲久热| 99啪啪| 久久精品一区二区三区蜜桃臀| 亚洲中文丝袜美腿诱惑字幕| 97爱综合| 久久五月天婷婷丁香中文字幕| 色欲日韩欧美在线一区| 天天日少妇逼AV| 吉田爱美AV在线| 久久成人精品| 思思热一热婷婷热一热| 91在线美女| 亚洲97久久精品亚洲| 黄片qw| 约操熟妇| 精品国产精品一区二区| 五月婷婷大香蕉| 五月丁香影院| 亚洲色图欧美色图制服丝袜| 人妻出轨一区二区三区| 久久999久| 中文字幕一区二区三区四五区| 国产在线激情| 日韩性爱小视频| 国产一区二区精品久久99| 亚洲欧洲国产综合av| 日韩情色视频| 久久激情视频| 一级成人性爱| 91日韩在线| 素人无码中文字幕| 男人的天堂视频精品乱在线| 久久精品国产亚洲妲己影视| 亚洲综合中文字幕有码| 操人妻丝袜高跟| 激情内射| 精品九九国产无码| 97九色人妻| 蜜桃传媒视频第一区入口在线看| 最新亚洲黄色免费电影 | 蜜桃传媒一区二区亚洲| 99日视频在线免费| 国产强奸91| 久久日韩毛| 香蕉99秘 一区精品蜜桃臀| 精品人妻中文字幕4399| 亚洲综合113页| 欧美日韩1234| 97色色网| 激情小说激情视频| 亚洲大胆人体av| 精品91日日夜夜超清资源| 美女久久久久久久| 99热婷婷一区二区三| 亚洲av青草久久一区二区| 免费一级欧美片片线观看| 99热99re6国产在线播放| 曰韩精品视频一区二区| 黑丝日韩av丝袜av| 中字幕人妻一区二区三区| 午夜性| 久久性爱视频99| AV99热18这里只有精品| 尤物网站91| 91精品人妻一区二区三区蜜桃臀| 欧美18老人禁| 天天综合网入口~91| 日本国产高清色www视频在线| 999 久久久| 天天天天天干夜夜夜夜夜操| 欧美日韩国产三级黄色| 欧日韩在线观看| 亚洲精品一区二区三区在线播放| 欧美色图在线视频少妇| www.色婷婷色综合| 亚洲九九九九| 日韩精品影视| 精品人人| 亚洲第一黄色av网站| 伊人麻豆传媒| 99色婷婷中文字幕乱色| 99热最新| 吖在线不卡一区二区国产剧情| 亚洲91射| 在线综合 亚洲 欧美中文字幕 | 色香91| 国产精品2020| 看一级黄色视频| 国产JDAV无码视频在线观看| 亚州,欧美在线| 四虎国产成人精品免费一女五男| 亚洲第一成人影院色播| 日本久久女同性恋视频| 白嫩91在线亚洲| 精品国产99| 日韩美女久久一区二区三区| 国岛片视频| 久久中文字幕一区不卡| 免费国产视频| 综合五月天| 舔人妻中文免费视频| 97超碰免费人人性爱| 大香蕉中文aV在线| 欧美v日韩欧亚洲电影天堂色诱,国产传媒| 日韩欧美综合激情| 高清国产性猛交xxxx乱大交| 国产肏逼网站| 五月丁香激情四射| 亚洲高清自拍| 久久啊啊| 国产高清自拍视频| 丁香九月婷婷| 人妻丝袜美腿中文字幕| 久久超碰网| 欧美超碰97| 久久精品国产精品一区| 久久夜夜| 亚洲精品毛片在线观看| 密乳AV免费观看| 东北丰满熟女国产一区| 麻豆区99999| 95精品在线| 欧美日韩222| 欧美大片天天看| 久草精品一区| 99超碰碰| 2024年最新色情网站在线观看| 天天干天天操天天操夜夜操天天操 | 综合久久中文字幕综合日韩精品| 国产真实野战在线视频| 色狠狠综合| 中文字幕艹艹| 中文字幕欧美日本乱码一线二线| 骚日日av| 精品蜜乳AV免费观看| 欧美精品99久久久**| 亚洲精品色| 欧洲与亚洲欧美精品中文字幕| 国产蜜臀在线| 久久久性| 五月丁香综合激情| 嗯嗯啊好大| 亚洲在线欧美| 亚洲精品国产熟女久久久久久| 日本久久精品| 9久精品视频在线观看| 国产日本一区二区三区蜜臀在线观看| 中文字日本乱码| 江都AV在线| 日本加靬比网站发布页| av午夜玫瑰| 欧美色图91| 影音先锋国产精品| 9999久久久久| 久久久久亚洲?V片无码V| 啊啊啊啊啊啊在线看| 啪啪啪男女亚洲中文字幕99| 久久男人精品| 日韩人妻精品中文字幕| 天天做天天爱夜夜爽毛片试看| 97婷婷色| 蜜臀久久99精品久久久久久婷婷| 操逼操逼视频操逼| 久久色一区二区| 五月天我淫我色av| 国产白嫩精品久久| 麻豆天美传媒毛片| 精品视频123区小说区| 国内外内射高清视频| 国产在线不卡导航| 精品国产一区探花在线观看| 久久这里都是精品| 日韩免费中文字幕视频| 91精品成人| 久操网无码在线| 亚洲美腿丝袜香蕉影视欧美成人| 国岛片视频| 男人综合网| 99热精品在线观看| 99热精品在线| 中文字幕一区二区视频在线观看| 青娱乐亚洲热| 日韩综合无码色欲vv| 日夜尻逼网| 看看小穴| 日韩 欧美 视频 在线 一区| 高潮9999外国| 精品一区二区三区最新| 近亲乱伦一区二区| 亚洲一区二区三区婷婷| 超碰碰97| 开心激情站| 再深点灬舒服灬太大了添视频| 9九九国产| 色婷婷综合久久久久中文一区二区| 韩国一级婬片A片无码天美| 好色美女九七第一页| 婷婷色香| 激情五月婷| 蜜乳AV网址| 亚洲中文字幕熟女| 桑老女人九区| 久久夜夜夜| 夜夜操夜夜爽夜夜高潮| 久久草在线综合视频| A 在线网址| 欧美精品三级黄片| 草草草视频| 啊啊啊啊,啊啊好多水| 97超碰逼| 校园春色综合色| 狠狠欧美| 蜜桃久久综合视频| 婷婷五月天久久久| 亚洲最大网站av| 丁香六月激情| 中文字幕一区二区日韩网| 亚洲天堂久久久久久粉红视频| 台湾佬大香蕉| 97神马久久| 亚洲中文字幕熟女少妇一区二区| 色亚州人久干视频在线观看免费版| 欧美亚洲中文字幕| 丝袜视频一区二区在线播放国产中文| 久久五月婷| 免费看日本操逼视频| 日韩性爱高清免费视频| 丰满人妻无码一区二区三区| 人妻一二三区| 亚洲成a人v欧美综合天堂下载| AV天堂因数| 综合夜夜| 九九黄色视频在线观看| 18禁中文字幕| 亚洲欧美精品福利在线| 成人八戒网站| 久久久久久久人妻| 色婷婷影视| 久久綜合很很很| 中文字幕久久亚州无码| daxiangjiao你懂的| 久操电影网| 国产精品久久| 国产乱伦亚洲| 亚洲欧洲综合视频在线|