最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis與RabbitMQ的區(qū)別對比和結(jié)合應(yīng)用

 更新時間:2025年10月25日 14:01:21   作者:小韓學(xué)長yyds  
RabbitMQ和Redis是兩種流行的消息隊(duì)列(Message Queue)和緩存系統(tǒng),在應(yīng)用程序開發(fā)中起著不同的角色和功能,Redis憑借內(nèi)存存儲和豐富數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)高速緩存和分布式鎖,RabbitMQ通過消息隊(duì)列實(shí)現(xiàn)系統(tǒng)解耦和異步處理,二者結(jié)合可應(yīng)對電商秒殺等高并發(fā)場景

在當(dāng)今數(shù)字化浪潮中,軟件開發(fā)面臨著日益復(fù)雜的業(yè)務(wù)需求,如何高效處理海量數(shù)據(jù)、實(shí)現(xiàn)系統(tǒng)間的可靠通信,成為了開發(fā)者們亟待攻克的難題。Redis,作為一款基于內(nèi)存的高性能鍵值對存儲數(shù)據(jù)庫,以其閃電般的讀寫速度和豐富的數(shù)據(jù)結(jié)構(gòu),在緩存、分布式鎖等場景中大放異彩。而 RabbitMQ,作為一款久經(jīng)考驗(yàn)的消息代理,憑借其強(qiáng)大的消息隊(duì)列功能、可靠的消息傳遞機(jī)制,在異步任務(wù)處理、系統(tǒng)解耦等方面展現(xiàn)出卓越的能力。

當(dāng) Redis 與 RabbitMQ 攜手并肩,它們將碰撞出怎樣的火花?又能為我們的業(yè)務(wù)帶來哪些令人驚喜的解決方案呢?

想象一下,在電商購物節(jié)的秒殺活動中,瞬間涌入的海量請求如洶涌潮水般沖擊著系統(tǒng)。此時,Redis 可以迅速緩存商品信息,讓用戶的查詢請求得到快速響應(yīng),同時利用其原子操作確保庫存扣減的準(zhǔn)確性,避免超賣現(xiàn)象。而 RabbitMQ 則可以將訂單處理任務(wù)放入消息隊(duì)列,讓系統(tǒng)能夠從容地異步處理這些請求,避免因高并發(fā)而導(dǎo)致的系統(tǒng)崩潰。再比如,在社交平臺上,用戶發(fā)布動態(tài)、點(diǎn)贊、評論等操作產(chǎn)生的大量消息,Redis 可以進(jìn)行實(shí)時緩存,提升用戶體驗(yàn),RabbitMQ 則負(fù)責(zé)將這些消息可靠地分發(fā)到各個相關(guān)系統(tǒng),實(shí)現(xiàn)數(shù)據(jù)的同步和更新。

Redis 與 RabbitMQ 的結(jié)合,猶如一對默契十足的搭檔,為我們解決各種復(fù)雜業(yè)務(wù)場景提供了強(qiáng)大的武器。接下來,就讓我們深入探索它們的融合之道,領(lǐng)略其中的技術(shù)魅力。

Redis 與 RabbitMQ 基礎(chǔ)

Redis 核心要點(diǎn)速覽

Redis,猶如一位身懷絕技的武林高手,以其獨(dú)特的本領(lǐng)在數(shù)據(jù)庫領(lǐng)域獨(dú)樹一幟。它基于內(nèi)存存儲,這一特性使其擁有閃電般的讀寫速度,能輕松應(yīng)對每秒數(shù)以萬計(jì)的請求,就像一陣旋風(fēng),迅速處理數(shù)據(jù)。采用單線程架構(gòu)的 Redis,巧妙地避免了多線程編程中常見的資源競爭問題,讓數(shù)據(jù)處理更加高效和穩(wěn)定。而且,Redis 支持多種數(shù)據(jù)結(jié)構(gòu),宛如一個百寶箱,里面裝滿了各種實(shí)用的工具。

在實(shí)際應(yīng)用中,Redis 的身影無處不在。在電商系統(tǒng)里,它常被用作緩存,將熱門商品信息、用戶登錄狀態(tài)等數(shù)據(jù)存儲其中。當(dāng)用戶查詢商品時,Redis 能瞬間響應(yīng),從內(nèi)存中快速取出數(shù)據(jù),大大提升了用戶體驗(yàn),就像在自家門口的便利店購物一樣便捷。在分布式系統(tǒng)中,Redis 更是扮演著分布式鎖的關(guān)鍵角色。在高并發(fā)場景下,比如電商的秒殺活動,眾多用戶同時搶購商品,Redis 通過其原子操作確保只有一個線程能成功獲取鎖,進(jìn)行庫存扣減等操作,有效避免了超賣現(xiàn)象的發(fā)生,如同一位公正的裁判,維持著系統(tǒng)的秩序。 此外,Redis 還在計(jì)數(shù)器、排行榜等場景中發(fā)揮著重要作用,為開發(fā)者提供了豐富的解決方案。

Redis 常用的數(shù)據(jù)結(jié)構(gòu)有字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。字符串類型是 Redis 最基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),可用于存儲各種類型的數(shù)據(jù),如字符串、數(shù)字、二進(jìn)制數(shù)據(jù)等。哈希類型則適合存儲對象,以字段 - 值的形式存儲,方便對對象的屬性進(jìn)行操作。列表類型是一個有序的字符串鏈表,可用于實(shí)現(xiàn)隊(duì)列、棧等數(shù)據(jù)結(jié)構(gòu)。集合類型用于存儲不重復(fù)的元素,支持集合的交、并、差等操作。有序集合則在集合的基礎(chǔ)上,為每個元素設(shè)置了一個分?jǐn)?shù),用于對元素進(jìn)行排序。

RabbitMQ 關(guān)鍵特性解讀

RabbitMQ 作為消息隊(duì)列領(lǐng)域的佼佼者,其工作原理和組件構(gòu)成了一個高效、可靠的消息傳遞系統(tǒng)。它就像一個龐大的物流網(wǎng)絡(luò),生產(chǎn)者將消息發(fā)送到這個網(wǎng)絡(luò)中,消費(fèi)者則從網(wǎng)絡(luò)中獲取消息進(jìn)行處理。在這個過程中,交換機(jī)扮演著交通樞紐的角色,它接收生產(chǎn)者發(fā)送的消息,并根據(jù)不同的路由規(guī)則,將消息分發(fā)到對應(yīng)的隊(duì)列中。隊(duì)列則像是一個個倉庫,存儲著等待被處理的消息,直到消費(fèi)者前來取走。

消息隊(duì)列在現(xiàn)代應(yīng)用架構(gòu)中有著舉足輕重的地位。在異步處理場景下,當(dāng)用戶注冊成功后,需要發(fā)送注冊郵件和短信通知。如果采用傳統(tǒng)的同步方式,系統(tǒng)需要等待郵件和短信發(fā)送完成后才能返回響應(yīng),這會導(dǎo)致用戶等待時間過長。而使用 RabbitMQ,系統(tǒng)只需將發(fā)送郵件和短信的任務(wù)放入消息隊(duì)列,即可立即返回響應(yīng)給用戶,讓郵件和短信在后臺異步發(fā)送,大大提高了系統(tǒng)的響應(yīng)速度,給用戶帶來更流暢的體驗(yàn)。

在系統(tǒng)解耦方面,以電商系統(tǒng)為例,訂單系統(tǒng)、庫存系統(tǒng)、物流系統(tǒng)等多個模塊之間存在著復(fù)雜的交互。如果各個系統(tǒng)之間直接進(jìn)行調(diào)用,當(dāng)其中一個系統(tǒng)發(fā)生故障或升級時,可能會影響到其他系統(tǒng)的正常運(yùn)行。而引入 RabbitMQ 后,訂單系統(tǒng)只需將訂單消息發(fā)送到消息隊(duì)列,庫存系統(tǒng)和物流系統(tǒng)從隊(duì)列中獲取消息進(jìn)行處理,各個系統(tǒng)之間通過消息隊(duì)列進(jìn)行解耦,降低了系統(tǒng)之間的耦合度,提高了系統(tǒng)的可維護(hù)性和擴(kuò)展性 ,就像將緊密相連的齒輪拆開,通過傳送帶連接,每個齒輪可以獨(dú)立運(yùn)轉(zhuǎn),互不干擾。

RabbitMQ 中的生產(chǎn)者是消息的發(fā)送者,負(fù)責(zé)將業(yè)務(wù)數(shù)據(jù)封裝成消息發(fā)送到交換機(jī)。消費(fèi)者則是消息的接收者,從隊(duì)列中獲取消息并進(jìn)行處理。交換機(jī)有多種類型,如直接交換機(jī)(Direct Exchange)、扇出交換機(jī)(Fanout Exchange)、主題交換機(jī)(Topic Exchange)和頭交換機(jī)(Headers Exchange)。直接交換機(jī)根據(jù)路由鍵將消息直接發(fā)送到對應(yīng)的隊(duì)列;扇出交換機(jī)將消息發(fā)送到所有綁定的隊(duì)列;主題交換機(jī)通過通配符匹配路由鍵和綁定模式,將消息發(fā)送到符合條件的隊(duì)列;頭交換機(jī)則根據(jù)消息的頭部屬性進(jìn)行路由。隊(duì)列是消息的存儲容器,多個消費(fèi)者可以訂閱同一個隊(duì)列,實(shí)現(xiàn)消息的共享消費(fèi)。

 Redis vs RabbitMQ 對比總結(jié)

兩者定位區(qū)別

項(xiàng)目RedisRabbitMQ
定位內(nèi)存數(shù)據(jù)庫 + 緩存系統(tǒng)(支持消息隊(duì)列功能)專業(yè)的消息隊(duì)列中間件(MQ 系統(tǒng))
核心用途高速緩存、分布式鎖、排行榜、簡單隊(duì)列異步解耦、削峰填谷、可靠消息傳遞
協(xié)議自定義 RESP 協(xié)議(輕量)AMQP 協(xié)議(標(biāo)準(zhǔn)、企業(yè)級)
使用場景高速緩存、延時隊(duì)列、輕量級消息通知企業(yè)級系統(tǒng)消息異步通信、任務(wù)分發(fā)、日志收集等

數(shù)據(jù)持久化機(jī)制對比

對比項(xiàng)RedisRabbitMQ
是否支持持久化? 支持(RDB、AOF)? 支持(消息持久化)
持久化方式1?? RDB:定期快照保存內(nèi)存數(shù)據(jù)
2?? AOF:記錄每次寫操作日志
消息存儲到磁盤(需顯式設(shè)置 durablepersistent
丟失風(fēng)險斷電時,RDB 模式可能丟失最后一次快照后的數(shù)據(jù);AOF 可更安全但性能略低若開啟持久化且確認(rèn)(ACK),數(shù)據(jù)不會丟失
性能表現(xiàn)持久化時寫入較慢,但仍以內(nèi)存為主寫入持久化后性能略降,但可靠性高
寫入順序保證支持簡單順序(List、Stream)嚴(yán)格的消息投遞順序、確認(rèn)機(jī)制(ACK/NACK)
恢復(fù)機(jī)制Redis 重啟加載 RDB/AOF 文件RabbitMQ 重啟后從磁盤恢復(fù)未消費(fèi)的持久化消息

可靠性與消息特性對比

特性Redis(Stream / List)RabbitMQ
消息確認(rèn)機(jī)制無(List)/手動 ack(Stream)完整 ACK、NACK、重試機(jī)制
消費(fèi)模式Pub/Sub(廣播)、Stream(分組消費(fèi))點(diǎn)對點(diǎn)、廣播、路由、主題匹配等多種模式
事務(wù)/一致性簡單事務(wù)支持(MULTI/EXEC)支持事務(wù)與確認(rèn)通道
延時隊(duì)列需借助 ZSET/Stream 實(shí)現(xiàn)原生 TTL + DLX 支持延時與死信
消息順序Stream 有序、List 先進(jìn)先出隊(duì)列內(nèi)消息嚴(yán)格有序
消息路由簡單通道強(qiáng)大路由機(jī)制(Exchange + Queue)

性能與擴(kuò)展性對比

對比項(xiàng)RedisRabbitMQ
性能(吞吐量)極高(百萬級 QPS)中等偏高(萬級 QPS)
延遲極低(微秒級)較低(毫秒級)
水平擴(kuò)展集群分片 Redis Cluster集群鏡像 + Federation/Shard
高可用Redis Sentinel / Cluster鏡像隊(duì)列 + 集群模式
適用規(guī)模小到中型異步任務(wù)、緩存中大型分布式系統(tǒng)、異步任務(wù)系統(tǒng)

優(yōu)缺點(diǎn)對比總結(jié)

維度RedisRabbitMQ
優(yōu)點(diǎn)?? 超高性能,易部署,支持多功能(緩存+隊(duì)列+分布式鎖)?? 高可靠、強(qiáng)一致性、完整確認(rèn)機(jī)制、多種消息模式
缺點(diǎn)? 消息可靠性較弱,易丟數(shù)據(jù)(尤其在斷電或宕機(jī)時)?? 部署和維護(hù)復(fù)雜,性能低于 Redis
適合場景臨時隊(duì)列、緩存任務(wù)、實(shí)時計(jì)數(shù)、輕量異步任務(wù)核心交易系統(tǒng)、消息總線、需要確認(rèn)的任務(wù)分發(fā)

實(shí)戰(zhàn)推薦策略

業(yè)務(wù)場景推薦方案
高性能緩存、排行榜、輕量通知? Redis
需要可靠消息、不允許丟失? RabbitMQ
兼顧性能與可靠性(分層架構(gòu))?? Redis + RabbitMQ 結(jié)合:
RabbitMQ 負(fù)責(zé)可靠傳遞,Redis 負(fù)責(zé)高效緩存與讀取

結(jié)合實(shí)現(xiàn)的高級業(yè)務(wù)場景

秒殺場景:應(yīng)對高并發(fā)挑戰(zhàn)

在電商領(lǐng)域,秒殺活動可謂是一場緊張刺激的 “購物大戰(zhàn)”,眾多消費(fèi)者如同饑餓的獵豹,緊盯屏幕,準(zhǔn)備在瞬間發(fā)起搶購。在這個過程中,Redis 和 RabbitMQ 攜手合作,共同應(yīng)對高并發(fā)帶來的巨大挑戰(zhàn)。

在秒殺活動開始前,商家會將參與秒殺的商品信息,如商品名稱、價格、庫存等,精心存儲到 Redis 緩存中。這就好比在超市的促銷區(qū)提前擺放好商品,消費(fèi)者可以快速瀏覽。當(dāng)用戶發(fā)起秒殺請求時,系統(tǒng)會第一時間從 Redis 中查詢商品庫存。由于 Redis 基于內(nèi)存存儲,查詢速度極快,能夠瞬間響應(yīng),就像在自家抽屜里找東西一樣迅速,極大地提高了系統(tǒng)的響應(yīng)速度。同時,利用 Redis 的原子操作對庫存進(jìn)行扣減,確保庫存的準(zhǔn)確性。原子操作就像是一把鎖,在同一時刻只有一個線程能夠?qū)齑孢M(jìn)行修改,避免了多個線程同時操作導(dǎo)致的超賣問題。例如,使用 Redis 的decr命令對庫存進(jìn)行遞減操作,保證庫存扣減的原子性。

當(dāng)庫存扣減成功后,系統(tǒng)會將訂單信息發(fā)送到 RabbitMQ 隊(duì)列中。這就像是將訂單放入一個專門的處理通道,讓后續(xù)的訂單處理工作能夠有條不紊地進(jìn)行。在訂單處理過程中,可能會涉及到創(chuàng)建訂單記錄、扣減庫存、更新用戶信息等一系列操作。如果這些操作都在高并發(fā)的情況下同步執(zhí)行,很容易導(dǎo)致系統(tǒng)崩潰。而通過 RabbitMQ 的異步處理機(jī)制,將訂單信息放入隊(duì)列后,系統(tǒng)可以立即返回響應(yīng)給用戶,告知用戶秒殺結(jié)果,讓用戶無需長時間等待。同時,后臺的消費(fèi)者從隊(duì)列中獲取訂單信息,按照順序進(jìn)行處理,大大提高了系統(tǒng)的并發(fā)處理能力。而且,RabbitMQ 的持久化機(jī)制可以確保訂單信息不會因?yàn)橄到y(tǒng)故障而丟失,就像把重要文件鎖在保險柜里一樣安全可靠。

異步任務(wù)處理:提升系統(tǒng)響應(yīng)效率

在當(dāng)今數(shù)字化時代,用戶注冊已經(jīng)成為眾多應(yīng)用的基礎(chǔ)功能。當(dāng)用戶注冊成功后,系統(tǒng)通常需要發(fā)送注冊郵件和短信通知,以告知用戶注冊結(jié)果,并提供相關(guān)的賬號信息和操作指引。然而,發(fā)送郵件和短信的過程往往需要與外部服務(wù)進(jìn)行交互,如郵件服務(wù)器、短信網(wǎng)關(guān)等,這一過程可能會比較耗時。如果采用傳統(tǒng)的同步方式,系統(tǒng)需要等待郵件和短信發(fā)送完成后才能返回響應(yīng)給用戶,這會導(dǎo)致用戶等待時間過長,影響用戶體驗(yàn)。

Redis 與 RabbitMQ 的結(jié)合,為解決這一問題提供了高效的解決方案。當(dāng)用戶注冊成功后,系統(tǒng)會將發(fā)送郵件和短信的任務(wù)封裝成消息,發(fā)送到 RabbitMQ 隊(duì)列中。這就好比將任務(wù)交給快遞員,讓快遞員按照順序去處理。同時,系統(tǒng)可以在 Redis 中記錄任務(wù)的狀態(tài),如任務(wù)是否已發(fā)送、是否已處理等。例如,使用 Redis 的哈希數(shù)據(jù)結(jié)構(gòu),以任務(wù) ID 為鍵,任務(wù)狀態(tài)為值,存儲任務(wù)的相關(guān)信息。這樣,系統(tǒng)可以隨時從 Redis 中查詢?nèi)蝿?wù)的執(zhí)行情況,方便進(jìn)行監(jiān)控和管理。

在后臺,消費(fèi)者從 RabbitMQ 隊(duì)列中獲取任務(wù),并執(zhí)行發(fā)送郵件和短信的操作。由于任務(wù)是異步處理的,系統(tǒng)可以立即返回響應(yīng)給用戶,告知用戶注冊成功,無需等待郵件和短信發(fā)送完成。這就像在餐廳點(diǎn)餐,服務(wù)員點(diǎn)完單后立即告知顧客點(diǎn)單已接收,而不需要等待菜品制作完成,大大提高了系統(tǒng)的響應(yīng)速度,給用戶帶來更流暢的體驗(yàn)。當(dāng)郵件和短信發(fā)送完成后,消費(fèi)者可以更新 Redis 中任務(wù)的狀態(tài),以便系統(tǒng)了解任務(wù)的執(zhí)行結(jié)果。

分布式系統(tǒng)中的數(shù)據(jù)同步

在分布式系統(tǒng)中,數(shù)據(jù)就像散落的珍珠,分布在各個節(jié)點(diǎn)上。如何確保這些數(shù)據(jù)的一致性,成為了一個關(guān)鍵難題。Redis 和 RabbitMQ 的結(jié)合,為數(shù)據(jù)同步提供了有效的解決方案。

以電商系統(tǒng)為例,當(dāng)商品信息發(fā)生變更時,如商品價格調(diào)整、庫存更新等,系統(tǒng)會將數(shù)據(jù)變更消息發(fā)送到 RabbitMQ 隊(duì)列中。這就像是在一個信息共享的大群里發(fā)布通知,讓所有相關(guān)人員都能收到消息。各個節(jié)點(diǎn)的應(yīng)用程序從隊(duì)列中獲取消息,并根據(jù)消息內(nèi)容更新本地的數(shù)據(jù)。同時,Redis 可以作為數(shù)據(jù)緩存和臨時存儲的工具,用于存儲最新的商品信息。當(dāng)用戶查詢商品信息時,系統(tǒng)會優(yōu)先從 Redis 中獲取數(shù)據(jù)。如果 Redis 中沒有數(shù)據(jù),再從數(shù)據(jù)庫中查詢,并將查詢結(jié)果存入 Redis 中,以便下次查詢時能夠快速響應(yīng)。這就像在辦公室設(shè)置了一個文件共享區(qū),大家可以先從共享區(qū)查找文件,如果沒有再去檔案室查找,提高了數(shù)據(jù)查詢的效率。

通過 RabbitMQ 傳遞數(shù)據(jù)變更消息,Redis 進(jìn)行數(shù)據(jù)緩存和臨時存儲,能夠?qū)崿F(xiàn)分布式系統(tǒng)中數(shù)據(jù)的實(shí)時同步,確保各個節(jié)點(diǎn)的數(shù)據(jù)一致性。同時,這種方式還可以降低數(shù)據(jù)庫的壓力,提高系統(tǒng)的性能和可靠性。

代碼實(shí)例深度剖析

環(huán)境搭建與依賴引入

在構(gòu)建基于 Redis 與 RabbitMQ 的應(yīng)用時,首先要搭建好開發(fā)環(huán)境并引入相應(yīng)的依賴。對于 Java 項(xiàng)目,通常使用 Maven 來管理項(xiàng)目依賴。在pom.xml文件中,添加 Redis 和 RabbitMQ 的依賴坐標(biāo)。

引入 Redis 依賴,如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

這將引入 Spring Data Redis,它為我們操作 Redis 提供了豐富的功能和便捷的接口。通過它,我們可以輕松地與 Redis 進(jìn)行交互,實(shí)現(xiàn)數(shù)據(jù)的存儲、讀取和刪除等操作 。

接著引入 RabbitMQ 依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

該依賴使得我們的項(xiàng)目能夠集成 RabbitMQ,利用其強(qiáng)大的消息隊(duì)列功能。它提供了與 RabbitMQ 服務(wù)器進(jìn)行連接、發(fā)送和接收消息的能力,為實(shí)現(xiàn)異步任務(wù)處理、系統(tǒng)解耦等場景奠定基礎(chǔ)。

除了依賴引入,還需要在配置文件中配置 Redis 和 RabbitMQ 的連接參數(shù)。在application.yml文件中,配置 Redis 連接信息:

spring:
  redis:
    host: localhost
    port: 6379
    password: 

這里指定了 Redis 服務(wù)器的主機(jī)地址、端口號以及密碼(若有)。通過這些配置,項(xiàng)目能夠正確地連接到 Redis 服務(wù)器,進(jìn)行后續(xù)的數(shù)據(jù)操作。

配置 RabbitMQ 連接信息

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

此配置設(shè)置了 RabbitMQ 服務(wù)器的連接地址、端口號、用戶名和密碼。確保這些信息準(zhǔn)確無誤,才能保證項(xiàng)目與 RabbitMQ 服務(wù)器之間的正常通信 。

秒殺場景代碼實(shí)現(xiàn)

在秒殺場景中,代碼實(shí)現(xiàn)主要涉及 Redis 緩存庫存以及 RabbitMQ 處理秒殺請求兩部分。

首先,創(chuàng)建一個秒殺控制器SecKillController,用于接收前端傳來的秒殺請求:

@RestController
@RequestMapping("/secKill")
public class SecKillController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedisTemplate<String, Integer> redisTemplate;

    @PostMapping("/startSecKill/{productId}")
    public ResponseEntity<String> startSecKill(@PathVariable Integer productId, @RequestParam Integer userId) {
        // 從緩存查詢庫存
        String key = "product_stock:" + productId;
        Integer stock = redisTemplate.opsForValue().get(key);

        // 校驗(yàn)庫存
        if (stock == null || stock <= 0) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("秒殺失敗,商品庫存不足");
        }

        // 一人一單校驗(yàn)
        if (redisTemplate.opsForValue().setIfAbsent("secKill:user:" + userId, productId, 30, TimeUnit.MINUTES)) {
            // 發(fā)送秒殺請求
            rabbitTemplate.convertAndSend("secKill_queue", new SecKillRequest(productId, userId));
            return ResponseEntity.ok("秒殺請求已提交,請稍后查看結(jié)果");
        } else {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("您已經(jīng)參與過該商品的秒殺活動");
        }
    }
}

在這個控制器中,首先從 Redis 緩存中獲取商品庫存。如果庫存不足,直接返回秒殺失敗的響應(yīng)。然后,通過 Redis 的setIfAbsent方法進(jìn)行一人一單校驗(yàn),確保同一用戶在一定時間內(nèi)只能參與一次秒殺。若校驗(yàn)通過,將秒殺請求發(fā)送到 RabbitMQ 的secKill_queue隊(duì)列中,并返回請求已提交的響應(yīng)。

接下來,創(chuàng)建一個秒殺消費(fèi)者SecKillConsumer,從 RabbitMQ 隊(duì)列中獲取秒殺請求并進(jìn)行處理:

@Component
public class SecKillConsumer {

    private static final Logger logger = LoggerFactory.getLogger(SecKillConsumer.class);

    @Autowired
    private RedisTemplate<String, Integer> redisTemplate;

    @RabbitListener(queues = "secKill_queue")
    public void receiveMessage(SecKillRequest message) {
        String key = "product_stock:" + message.getProductId();
        Integer stock = redisTemplate.opsForValue().get(key);

        // 再次校驗(yàn)庫存
        if (stock!= null && stock > 0) {
            // 扣減庫存
            redisTemplate.opsForValue().decrement(key);
            // 創(chuàng)建訂單業(yè)務(wù)邏輯
        } else {
            // 庫存不足,處理邏輯
            logger.info("秒殺失敗: 商品 " + message.getProductId() + " 庫存不足");
        }
    }
}

在消費(fèi)者中,從 RabbitMQ 隊(duì)列接收到秒殺請求后,再次從 Redis 中獲取商品庫存進(jìn)行校驗(yàn)。若庫存充足,利用 Redis 的decrement方法原子性地扣減庫存,然后進(jìn)行創(chuàng)建訂單等后續(xù)業(yè)務(wù)邏輯。若庫存不足,則記錄日志表明秒殺失敗 。

異步任務(wù)處理代碼展示

以用戶注冊發(fā)送郵件和短信通知為例,展示異步任務(wù)處理的代碼實(shí)現(xiàn)。

首先,創(chuàng)建一個任務(wù)發(fā)送服務(wù)TaskSenderService,在用戶注冊成功后,將發(fā)送郵件和短信的任務(wù)發(fā)送到 RabbitMQ 隊(duì)列:

@Service
public class TaskSenderService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendTask(Task task) {
        rabbitTemplate.convertAndSend("task_queue", task);
    }
}

這里的Task是一個自定義的任務(wù)類,包含了發(fā)送郵件和短信所需的信息,如收件人郵箱、手機(jī)號、郵件內(nèi)容、短信內(nèi)容等。

然后,創(chuàng)建一個任務(wù)消費(fèi)者TaskConsumer,從 RabbitMQ 隊(duì)列中獲取任務(wù)并執(zhí)行:

@Component
public class TaskConsumer {

    @RabbitListener(queues = "task_queue")
    public void handleTask(Task task) {
        // 發(fā)送郵件邏輯
        sendEmail(task.getEmail(), task.getEmailContent());

        // 發(fā)送短信邏輯
        sendSms(task.getPhone(), task.getSmsContent());
    }

    private void sendEmail(String email, String content) {
        // 實(shí)際的郵件發(fā)送邏輯,這里省略具體實(shí)現(xiàn)
        System.out.println("發(fā)送郵件到 " + email + ",內(nèi)容為:" + content);
    }

    private void sendSms(String phone, String content) {
        // 實(shí)際的短信發(fā)送邏輯,這里省略具體實(shí)現(xiàn)
        System.out.println("發(fā)送短信到 " + phone + ",內(nèi)容為:" + content);
    }
}

在任務(wù)消費(fèi)者中,從task_queue隊(duì)列獲取任務(wù)后,分別執(zhí)行發(fā)送郵件和短信的邏輯。雖然這里的郵件和短信發(fā)送邏輯只是簡單的打印輸出,但在實(shí)際應(yīng)用中,會調(diào)用相應(yīng)的郵件發(fā)送庫和短信網(wǎng)關(guān)接口來完成真正的發(fā)送操作 。

通過以上代碼實(shí)例,我們可以清晰地看到 Redis 與 RabbitMQ 在不同業(yè)務(wù)場景中的具體實(shí)現(xiàn)方式,它們的緊密配合為解決復(fù)雜業(yè)務(wù)問題提供了高效、可靠的方案。

優(yōu)化策略與注意事項(xiàng)

性能優(yōu)化技巧

在使用 Redis 與 RabbitMQ 構(gòu)建系統(tǒng)時,優(yōu)化性能是確保系統(tǒng)高效運(yùn)行的關(guān)鍵。對于 Redis,合理的緩存策略至關(guān)重要??梢圆捎镁彺骖A(yù)熱的方式,在系統(tǒng)啟動或業(yè)務(wù)高峰期來臨前,將熱點(diǎn)數(shù)據(jù)提前加載到 Redis 緩存中。例如,在電商大促活動前,將熱門商品的信息預(yù)先存入 Redis,這樣當(dāng)用戶大量請求時,能夠直接從緩存中獲取數(shù)據(jù),大大減少數(shù)據(jù)庫的壓力,提高系統(tǒng)響應(yīng)速度,就像提前儲備好物資,隨時滿足需求。

在設(shè)置緩存過期時間時,避免大量緩存同時失效,引發(fā)緩存雪崩問題??梢酝ㄟ^為不同數(shù)據(jù)設(shè)置不同的過期時間,或者在過期時間上增加一定的隨機(jī)數(shù),讓緩存失效時間分散開來 。在一個新聞資訊平臺中,各類新聞的緩存過期時間可以根據(jù)其熱度和時效性進(jìn)行差異化設(shè)置,熱門新聞的過期時間稍長,冷門新聞的過期時間較短,且每個過期時間都添加一個隨機(jī)的分鐘數(shù),防止大量新聞緩存同時過期,對數(shù)據(jù)庫造成沖擊。

對于 RabbitMQ,優(yōu)化隊(duì)列設(shè)置能顯著提升性能??梢愿鶕?jù)業(yè)務(wù)需求調(diào)整隊(duì)列的大小和消費(fèi)者的數(shù)量。在高并發(fā)場景下,如果隊(duì)列過小,可能導(dǎo)致消息堆積,影響系統(tǒng)性能;而消費(fèi)者數(shù)量不足,則無法及時處理消息。因此,需要根據(jù)實(shí)際的消息處理量和處理速度,動態(tài)調(diào)整隊(duì)列大小和消費(fèi)者數(shù)量,以達(dá)到最佳的性能平衡。在一個訂單處理系統(tǒng)中,通過監(jiān)控訂單消息的產(chǎn)生速度和處理速度,合理增加或減少隊(duì)列的容量,以及啟動相應(yīng)數(shù)量的消費(fèi)者,確保訂單消息能夠及時、高效地被處理 。

還可以采用批量發(fā)送和接收消息的方式,減少網(wǎng)絡(luò)通信開銷。在生產(chǎn)者端,將多條消息批量發(fā)送到 RabbitMQ,而不是逐條發(fā)送;在消費(fèi)者端,批量從隊(duì)列中獲取消息進(jìn)行處理。這樣可以有效減少網(wǎng)絡(luò)請求次數(shù),提高消息處理效率,就像一次運(yùn)輸多批貨物,減少運(yùn)輸次數(shù),提高運(yùn)輸效率。

常見問題及解決方案

在 Redis 與 RabbitMQ 的實(shí)際應(yīng)用中,可能會遇到一些問題,需要及時解決,以保證系統(tǒng)的穩(wěn)定運(yùn)行。消息丟失是一個常見問題,可能發(fā)生在生產(chǎn)者、RabbitMQ 服務(wù)器或消費(fèi)者端。在生產(chǎn)者端,若網(wǎng)絡(luò)出現(xiàn)問題,可能導(dǎo)致消息未能成功發(fā)送到 RabbitMQ 服務(wù)器。為解決此問題,可以啟用生產(chǎn)者確認(rèn)機(jī)制,生產(chǎn)者將信道設(shè)置為 confirm 模式,消息發(fā)送后,RabbitMQ 會返回確認(rèn)消息給生產(chǎn)者,告知消息是否成功投遞。如果生產(chǎn)者未收到確認(rèn)消息,可以進(jìn)行消息重發(fā),確保消息不丟失,就像寄快遞時,要求快遞員提供簽收確認(rèn),若未收到確認(rèn),就重新寄送。

在 RabbitMQ 服務(wù)器端,若服務(wù)器宕機(jī)或重啟,且消息未進(jìn)行持久化,可能導(dǎo)致消息丟失。因此,需要開啟 RabbitMQ 的持久化功能,將隊(duì)列和消息都設(shè)置為持久化。在創(chuàng)建隊(duì)列時,將其設(shè)置為持久化隊(duì)列;發(fā)送消息時,將消息的deliveryMode設(shè)置為 2,即持久化消息,這樣即使服務(wù)器出現(xiàn)故障,重啟后也能從磁盤中恢復(fù)消息 。

在消費(fèi)者端,如果消費(fèi)者在處理消息過程中出錯,且自動返回了 ack,可能導(dǎo)致消息丟失。為避免這種情況,消費(fèi)者應(yīng)將確認(rèn)模式設(shè)置為手動確認(rèn),在成功處理消息后,再手動向 RabbitMQ 發(fā)送 ack 確認(rèn)消息,確保消息被正確處理 。

消息重復(fù)消費(fèi)也是一個需要關(guān)注的問題。網(wǎng)絡(luò)波動、消費(fèi)者故障等原因都可能導(dǎo)致消息重復(fù)消費(fèi)。為解決此問題,可以在消息中添加唯一標(biāo)識,如 UUID。消費(fèi)者在處理消息前,先檢查 Redis 中是否已存在該消息的唯一標(biāo)識,如果存在,說明該消息已被處理過,直接跳過;如果不存在,則處理消息,并將唯一標(biāo)識存入 Redis。在一個用戶注冊發(fā)送郵件通知的場景中,為每個注冊郵件消息生成一個唯一的 UUID,消費(fèi)者在發(fā)送郵件前,先檢查 Redis 中是否存在該 UUID,若不存在則發(fā)送郵件,并將 UUID 存入 Redis,若存在則表示郵件已發(fā)送,避免重復(fù)發(fā)送 。

通過以上優(yōu)化策略和問題解決方案,可以更好地發(fā)揮 Redis 與 RabbitMQ 的優(yōu)勢,構(gòu)建出高效、穩(wěn)定的系統(tǒng),滿足復(fù)雜業(yè)務(wù)場景的需求。

到此這篇關(guān)于Redis與RabbitMQ的區(qū)別對比和結(jié)合應(yīng)用的文章就介紹到這了,更多相關(guān)Redis與RabbitMQ的區(qū)別和合作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 利用redis實(shí)現(xiàn)聊天記錄轉(zhuǎn)存功能的全過程

    利用redis實(shí)現(xiàn)聊天記錄轉(zhuǎn)存功能的全過程

    社交類軟件聊天功能必不可少,聊天記錄存儲的方式也比較多,比如文本,數(shù)據(jù)庫,云等等,但是最好的選擇還是redis進(jìn)行存儲,這篇文章主要給大家介紹了關(guān)于如何利用redis實(shí)現(xiàn)聊天記錄轉(zhuǎn)存功能的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Redis實(shí)現(xiàn)附近商鋪的項(xiàng)目實(shí)戰(zhàn)

    Redis實(shí)現(xiàn)附近商鋪的項(xiàng)目實(shí)戰(zhàn)

    本文主要介紹了Redis實(shí)現(xiàn)附近商鋪的項(xiàng)目實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 本地訪問不到公網(wǎng)redis的解決方案

    本地訪問不到公網(wǎng)redis的解決方案

    本文詳述了本地訪問不到公網(wǎng)redis的解決方案,包括分析報錯原因、Redis配置文件的區(qū)別、bind和protected-mode配置的解析,最終通過修改Redis配置文件及創(chuàng)建啟動腳本解決了訪問不到公網(wǎng)redis得問題,需要的朋友可以參考下
    2024-08-08
  • Redis中的List結(jié)構(gòu)從使用到原理分析

    Redis中的List結(jié)構(gòu)從使用到原理分析

    本文詳解Redis List結(jié)構(gòu),涵蓋其基本操作、內(nèi)部實(shí)現(xiàn)(ziplist、linkedlist、quicklist)、應(yīng)用場景(消息隊(duì)列、動態(tài)排行、歷史記錄)及性能優(yōu)化策略,如配置參數(shù)、批量操作,幫助開發(fā)者高效使用
    2025-09-09
  • Redisson延時隊(duì)列RedissonDelayed的具體使用

    Redisson延時隊(duì)列RedissonDelayed的具體使用

    定時調(diào)度基本是每個項(xiàng)目都會遇到的業(yè)務(wù)場景,一般地,都會通過任務(wù)調(diào)度工具執(zhí)行定時任務(wù)完成,但是會有一定的缺點(diǎn),本文主要介紹了Redisson延時隊(duì)列RedissonDelayed的具體使用,感興趣的可以了解一下
    2024-02-02
  • Redis實(shí)現(xiàn)分布式鎖詳解

    Redis實(shí)現(xiàn)分布式鎖詳解

    這篇文章主要介紹了redis如何實(shí)現(xiàn)分布式鎖,文章中有詳細(xì)的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-04-04
  • Redis緩存IO模型的演進(jìn)教程示例精講

    Redis緩存IO模型的演進(jìn)教程示例精講

    這篇文章主要為大家介紹了Redis線程IO模型演進(jìn)的教程示例精講,有需要朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2021-11-11
  • Redis Sentinel服務(wù)配置流程(詳解)

    Redis Sentinel服務(wù)配置流程(詳解)

    下面小編就為大家?guī)硪黄猂edis Sentinel服務(wù)配置流程(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Redis中Zset類型常用命令的實(shí)現(xiàn)

    Redis中Zset類型常用命令的實(shí)現(xiàn)

    Zset是Redis的一種有序集合數(shù)據(jù)類型,Zset通過壓縮列表和跳躍表兩種底層編碼方式支持小數(shù)據(jù)集和大數(shù)據(jù)集,支持多種操作,包括添加、查詢、刪除元素以及集合運(yùn)算等,具有不同的時間復(fù)雜度,感興趣的可以了解一下
    2024-10-10
  • redis哈希和集合_動力節(jié)點(diǎn)Java學(xué)院整理

    redis哈希和集合_動力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要為大家詳細(xì)介紹了redis哈希和集合的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08

最新評論

凤翔县| 安阳县| 新田县| 临洮县| 繁峙县| 呼玛县| 龙南县| 虹口区| 汉沽区| 横山县| 乐东| 繁峙县| 文安县| 靖州| 民和| 昌宁县| 莱阳市| 宜城市| 大丰市| 西藏| 石河子市| 广宗县| 砚山县| 南漳县| 沁源县| 东兴市| 鹤岗市| 耿马| 长乐市| 永寿县| 淮安市| 巧家县| 盘锦市| 田东县| 正镶白旗| 富宁县| 固安县| 池州市| 南部县| 新闻| 襄樊市|