盤(pán)點(diǎn)MQ中的異常測(cè)試
前言
上一篇小結(jié)了一下關(guān)于redis的異常測(cè)試,今天再來(lái)盤(pán)一盤(pán) MQ 相關(guān)的。
MQ 跟 redis 一樣,也是現(xiàn)在系統(tǒng)服務(wù)中不可或缺的重要中間件,通常用來(lái)流量削峰、應(yīng)用解耦、異步處理等。
之前有過(guò)一篇整理【MQ 快速入門(mén)】介紹、分類、組成、優(yōu)缺點(diǎn)、測(cè)試點(diǎn),有興趣也可以跳過(guò)去看看。
日常經(jīng)手的系統(tǒng)主要用的是 RocketMQ,是阿里系下開(kāi)源的一款分布式、隊(duì)列模型的消息中間件,是阿里參照kafka設(shè)計(jì)思想使用java實(shí)現(xiàn)的一套MQ,并做了自己的改進(jìn)。被廣泛的應(yīng)用在訂單、交易、充值、流計(jì)算、消息推送、日志流處理等場(chǎng)景。
這里再簡(jiǎn)述一些知識(shí)點(diǎn)。
一、RocketMQ 消息模式
RocketMQ中,也存在兩種消息模式,分別為集群消費(fèi)模式和廣播消費(fèi)模式。
集群消費(fèi)模式
RocketMQ默認(rèn)的消息模式就是集群模式,當(dāng)存在多個(gè)消費(fèi)者時(shí),消息通過(guò)一定負(fù)載均衡策略,將消息分發(fā)到多個(gè)consumer中。
比如現(xiàn)在有3個(gè)消費(fèi)者,那么一條消息投遞過(guò)來(lái),只會(huì)被consumer 1、consumer 2、consumer 3中的一個(gè)消費(fèi)。
在RockeMQ中,通過(guò)ConsumeGroup的機(jī)制,實(shí)現(xiàn)了天然的消息負(fù)載均衡,可以非常方便的通過(guò)加機(jī)器來(lái)實(shí)現(xiàn)水平擴(kuò)展。
廣播消費(fèi)模式
這種模式下,會(huì)把消息分發(fā)給每一個(gè)消費(fèi)者。一條消息投遞過(guò)來(lái),會(huì)被 consumer 1、consumer 2、consumer 3都消費(fèi)一次,就像發(fā)了條朋友圈,你的朋友都可以看見(jiàn)。
目前我們用的比較多的是集群模式,在集群模式也可以模擬廣播消費(fèi)。
二、push 和 pull 優(yōu)缺點(diǎn)
對(duì)于任何一款消息中間件而言,消費(fèi)者客戶端一般有兩種方式從消息中間件獲取消息并消費(fèi)。
Pull方式
由消費(fèi)者客戶端主動(dòng)向消息中間件(MQ消息服務(wù)器代理)拉取消息。
適用場(chǎng)景:對(duì)于生產(chǎn)者生產(chǎn)消息數(shù)據(jù)比較大時(shí),而消費(fèi)端處理比較復(fù)雜,消費(fèi)能力相對(duì)較低。
優(yōu)點(diǎn):消費(fèi)者可以依據(jù)自己的消費(fèi)能力進(jìn)行消費(fèi),生產(chǎn)者不需要維護(hù)和消費(fèi)者之間的會(huì)話。
缺點(diǎn):拉取消息的間隔不太好設(shè)置。間隔太短,對(duì)服務(wù)器請(qǐng)求壓力過(guò)大。間隔時(shí)間過(guò)長(zhǎng),那么必然會(huì)造成一部分?jǐn)?shù)據(jù)的延遲,實(shí)時(shí)性相對(duì)較低。
優(yōu)化方案:
長(zhǎng)輪詢的消費(fèi)方式,需要Server和Client的配合才能夠?qū)崿F(xiàn)。
即Client發(fā)送消息請(qǐng)求,Server端接受請(qǐng)求,如果發(fā)現(xiàn)Server隊(duì)列里沒(méi)有新消息,Server端不立即返回,而是持有這個(gè)請(qǐng)求一段時(shí)間(通過(guò)設(shè)置超時(shí)時(shí)間來(lái)實(shí)現(xiàn)),在這段時(shí)間內(nèi)輪詢Server隊(duì)列內(nèi)是否有新的消息,如果有新消息,就利用現(xiàn)有的連接返回消息給消費(fèi)者;如果這段時(shí)間內(nèi)沒(méi)有新消息進(jìn)入隊(duì)列,則返回空。
長(zhǎng)輪詢的弊端:在持有消費(fèi)者請(qǐng)求的這段時(shí)間,占用了系統(tǒng)資源,因此長(zhǎng)輪詢適合客戶端連接數(shù)可控的業(yè)務(wù)場(chǎng)景中。
Push方式
由消息服務(wù)端主動(dòng)地將消息推送給消費(fèi)者,盡可能實(shí)時(shí)地將消息發(fā)送給消費(fèi)者進(jìn)行消費(fèi)。
適用場(chǎng)景:對(duì)于數(shù)據(jù)實(shí)時(shí)性要求高的場(chǎng)景。
優(yōu)點(diǎn):生產(chǎn)者主動(dòng)推送給消費(fèi)者,及時(shí)性很高。
缺點(diǎn):當(dāng)消費(fèi)者消費(fèi)能力遠(yuǎn)低于生產(chǎn)者生產(chǎn)能力,那么一旦生產(chǎn)者推送大量消息到消費(fèi)者時(shí),就會(huì)導(dǎo)致消費(fèi)者消息堆積,處理緩慢,甚至服務(wù)崩潰。
另外,生產(chǎn)者需要維護(hù)和每個(gè)消費(fèi)者之間的會(huì)話。
優(yōu)化方案:不采用 http 長(zhǎng)連接的方法保持會(huì)話,采用 socket 監(jiān)聽(tīng)。
三、刷盤(pán)策略
RocketMQ的存儲(chǔ)讀寫(xiě)是基于JDK NIO的內(nèi)存映射機(jī)制的,消息存儲(chǔ)時(shí)首先將消息追加到內(nèi)存中,再根據(jù)不同的刷盤(pán)策略在不同的時(shí)間進(jìn)行刷盤(pán)。
同步刷盤(pán)
同步刷盤(pán)是指數(shù)據(jù)到達(dá)內(nèi)存之后,必須刷到commitlog日志之后才算成功,然后返回producer數(shù)據(jù)已經(jīng)發(fā)送成功。
異步刷盤(pán)
指數(shù)據(jù)到達(dá)內(nèi)存之后,返回producer說(shuō)數(shù)據(jù)已經(jīng)發(fā)送成功,然后再寫(xiě)入commitlog日志。
什么是commitlog?
commitlog 就是來(lái)存儲(chǔ)所有的元信息,包含消息體,類似于Mysql、Oracle 的 redolog。所以只要有 CommitLog 在,Consume Queue即使數(shù)據(jù)丟失,仍然可以恢復(fù)出來(lái)。
而 consumequeue,就是用來(lái)記錄數(shù)據(jù)的位置,以便 Consumer 快速通過(guò) consumequeue 找到 commitlog 中的數(shù)據(jù)。
四、MQ 異常測(cè)試
MQ消息體
MQ消息體中某些必填參數(shù)為 NULL,或者全部必填都為NULL,字段類型、長(zhǎng)度是否不符合約定等。
消息重復(fù)發(fā)送
消息重復(fù)發(fā)送,只消費(fèi)一條,一般根據(jù)消息內(nèi)容中唯一標(biāo)識(shí)來(lái)去重。
消息到達(dá)順序不一致
消息到達(dá)順序不一致,導(dǎo)致業(yè)務(wù)異常。
比如:訂單下單后再取消,如果先收到取消的消息,再收到下單消息,就會(huì)有問(wèn)題。
消息發(fā)送失敗重試
Producer端重試
比如網(wǎng)絡(luò)抖動(dòng)導(dǎo)致生產(chǎn)者發(fā)送消息到MQ失敗,可以手動(dòng)設(shè)置發(fā)送失敗重試的次數(shù)。
Consumer端重試
默認(rèn)16次,重試時(shí)間間隔會(huì)越來(lái)越長(zhǎng),如果失敗的多,容易堆積。這里的重試次數(shù)可自定義設(shè)置。
值得注意的是,只有消息推送失敗才需要重推,不要把其他失敗的情況也進(jìn)行重試。
接線上生產(chǎn)者
接線上已有的生產(chǎn)者,需要注意,必須設(shè)置消費(fèi)開(kāi)始時(shí)間,不然上線時(shí)會(huì)大批量消息過(guò)來(lái)會(huì)造成堆積,可能造成故障。
消息丟失
消息丟失,業(yè)務(wù)是否兼容,是否有補(bǔ)償或者監(jiān)控機(jī)制。
消息爭(zhēng)用
如果是集群模式,同一topic下新增新的消費(fèi)組,但是沒(méi)有申請(qǐng)新的group,導(dǎo)致一條消息投遞過(guò)來(lái),多個(gè)消費(fèi)組爭(zhēng)搶。
比如開(kāi)發(fā)為了省事,預(yù)發(fā)和線上同一個(gè)topic,消費(fèi)組的group也一樣,上線后,可能存在有效消息被預(yù)發(fā)消費(fèi)組消費(fèi)了。
MQ比落庫(kù)快
比如某接口A,新增一條數(shù)據(jù)后會(huì)同步更新DB和發(fā)送MQ給服務(wù)B,服務(wù)B收到消息后查詢DB這條數(shù)據(jù)。曾經(jīng)發(fā)現(xiàn)了收到消息卻查不到數(shù)據(jù)的情況,因?yàn)閿?shù)據(jù)庫(kù)更新速度沒(méi)有MQ快,后來(lái)改成異步了。
以上就是盤(pán)點(diǎn)MQ中的異常測(cè)試的詳細(xì)內(nèi)容,更多關(guān)于MQ異常測(cè)試的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java 實(shí)例化類詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了java 實(shí)例化類詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03
Spring Cloud Gateway Hystrix fallback獲取異常信息的處理
這篇文章主要介紹了Spring Cloud Gateway Hystrix fallback獲取異常信息的處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
jmeter+ant+jenkins自動(dòng)化測(cè)試環(huán)境配置搭建過(guò)程
在搭建jmeter+ant+jenkins環(huán)境有些前提條件,那就是要先配置好java環(huán)境、安裝好jenkins以及配置好jmeter,這樣才能省去很多的事情,對(duì)jmeter+ant+jenkins自動(dòng)化測(cè)試環(huán)境配置搭建過(guò)程感興趣的朋友一起看看吧2021-12-12
Java基礎(chǔ)鞏固小項(xiàng)目點(diǎn)菜系統(tǒng)的實(shí)現(xiàn)
這篇文章主要介紹了一個(gè)Java小項(xiàng)目點(diǎn)菜系統(tǒng)的實(shí)現(xiàn),主要是用的集合,適合正在學(xué)習(xí)Java的朋友拿來(lái)實(shí)戰(zhàn)練手,感興趣的朋友快來(lái)看看吧2022-03-03
java調(diào)用FFmpeg實(shí)現(xiàn)視屏壓縮功能的詳細(xì)步驟
這篇文章主要介紹了java調(diào)用FFmpeg實(shí)現(xiàn)視屏壓縮功能,本文簡(jiǎn)單的展示了java調(diào)用FFmpeg命令實(shí)現(xiàn)視屏的壓縮的詳細(xì)步驟,需要的朋友可以參考下2021-09-09
Java8?stream流的map()方法你會(huì)使用了嗎
在日常的開(kāi)發(fā)工作中經(jīng)常碰到要處理list中數(shù)據(jù)的問(wèn)題。本文主要帶大家了解下Java8?stream流中map()方法的使用,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-12-12
詳解JavaWeb過(guò)濾器 Filter問(wèn)題解決
過(guò)濾器就是對(duì)事物進(jìn)行過(guò)濾的,在Web中的過(guò)濾器,當(dāng)然就是對(duì)請(qǐng)求進(jìn)行過(guò)濾,我們使用過(guò)濾器,就可以對(duì)請(qǐng)求進(jìn)行攔截,然后做相應(yīng)的處理,實(shí)現(xiàn)許多特殊功能,今天主要給大家講解JavaWeb過(guò)濾器 Filter問(wèn)題解決,感興趣的朋友一起看看吧2022-10-10
spring如何使用命名空間p簡(jiǎn)化bean的配置
這篇文章主要介紹了spring如何使用命名空間p簡(jiǎn)化bean的配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
Java程序生成exe可執(zhí)行文件詳細(xì)教程(圖文說(shuō)明)
這篇文章主要介紹了Java程序生成exe可執(zhí)行文件詳細(xì)教程,有需要的朋友可以參考一下2013-12-12
基于spring boot 1.5.4 集成 jpa+hibernate+jdbcTemplate(詳解)
下面小編就為大家?guī)?lái)一篇基于spring boot 1.5.4 集成 jpa+hibernate+jdbcTemplate(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06

