Redis到底適不適合做消息隊列孝情?

List隊列模型

因為 List 底層的實(shí)現(xiàn)就是一個「鏈表」只锭,在頭部和尾部操作元素著恩,時間復(fù)雜度都是 O(1),這意味著它非常符合消息隊列的模型。
生產(chǎn)者使用 LPUSH 發(fā)布消息:

127.0.0.1:6379> LPUSH queue msg1
(integer) 1
127.0.0.1:6379> LPUSH queue msg2
(integer) 2

消費(fèi)者這一側(cè)喉誊,使用 RPOP 拉取消息:

127.0.0.1:6379> RPOP queue
"msg1"
127.0.0.1:6379> RPOP queue
"msg2"

但這里有個小問題邀摆,當(dāng)隊列中已經(jīng)沒有消息了,消費(fèi)者在執(zhí)行 RPOP 時伍茄,會返回 NULL栋盹。而我們在編寫消費(fèi)者邏輯時,一般是一個「死循環(huán)」敷矫,這個邏輯需要不斷地從隊列中拉取消息進(jìn)行處理例获,偽代碼一般會這么寫:

while true:
    msg = redis.rpop("queue")
    // 沒有消息,繼續(xù)循環(huán)
    if msg == null:
        continue
    // 處理消息
    handle(msg)
如果此時隊列為空曹仗,那消費(fèi)者依舊會頻繁拉取消息榨汤,這會造成「CPU 空轉(zhuǎn)」,不僅浪費(fèi) CPU 資源整葡,還會對 Redis 造成壓力件余。

也很簡單,當(dāng)隊列為空時遭居,我們可以「休眠」一會啼器,再去嘗試?yán)∠ⅰ4a可以修改成這樣:

while true:
    msg = redis.rpop("queue")
    // 沒有消息俱萍,休眠2s
    if msg == null:
        sleep(2)
        continue
    // 處理消息        
    handle(msg)

這就解決了 CPU 空轉(zhuǎn)問題端壳。這個問題雖然解決了,但又帶來另外一個問題:當(dāng)消費(fèi)者在休眠等待時枪蘑,有新消息來了损谦,那消費(fèi)者處理新消息就會存在「延遲」。假設(shè)設(shè)置的休眠時間是 2s岳颇,那新消息最多存在 2s 的延遲照捡。要想縮短這個延遲,只能減小休眠的時間话侧。但休眠時間越小栗精,又有可能引發(fā) CPU 空轉(zhuǎn)問題。
那如何做瞻鹏,既能及時處理新消息悲立,還能避免 CPU 空轉(zhuǎn)呢?
Redis 是否存在這樣一種機(jī)制:如果隊列為空新博,消費(fèi)者在拉取消息時就「阻塞等待」薪夕,一旦有新消息過來,就通知我的消費(fèi)者立即處理新消息呢赫悄?
幸運(yùn)的是原献,Redis 確實(shí)提供了「阻塞式」拉取消息的命令:BRPOP / BLPOP馏慨,這里的 B 指的是阻塞(Block)。

注意:如果設(shè)置的超時時間太長姑隅,這個連接太久沒有活躍過熏纯,可能會被 Redis Server 判定為無效連接,之后 Redis Server 會強(qiáng)制把這個客戶端踢下線粤策。所以,采用這種方案误窖,客戶端要有重連機(jī)制叮盘。

List隊列的缺點(diǎn):

  • 不支持重復(fù)消費(fèi):消費(fèi)者拉取消息后,這條消息就從 List 中刪除了霹俺,無法被其它消費(fèi)者再次消費(fèi)柔吼,即不支持多個消費(fèi)者消費(fèi)同一批數(shù)據(jù)。
  • 消息丟失:消費(fèi)者拉取到消息后丙唧,如果發(fā)生異常宕機(jī)愈魏,那這條消息就丟失了。

發(fā)布/訂閱模型:Pub/Sub

Redis 提供了 PUBLISH / SUBSCRIBE 命令想际,來完成發(fā)布培漏、訂閱的操作。
假設(shè)你想開啟 2 個消費(fèi)者胡本,同時消費(fèi)同一批數(shù)據(jù)牌柄,就可以按照以下方式來實(shí)現(xiàn)。首先侧甫,使用 SUBSCRIBE 命令珊佣,啟動 2 個消費(fèi)者,并「訂閱」同一個隊列披粟。

// 2個消費(fèi)者 都訂閱一個隊列
127.0.0.1:6379> SUBSCRIBE queue
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "queue"
3) (integer) 1

此時咒锻,2 個消費(fèi)者都會被阻塞住,等待新消息的到來守屉。之后惑艇,再啟動一個生產(chǎn)者,發(fā)布一條消息胸梆。這時敦捧,2 個消費(fèi)者就會解除阻塞,收到生產(chǎn)者發(fā)來的新消息碰镜。

127.0.0.1:6379> PUBLISH queue msg1
//發(fā)送新消息
(integer) 1

127.0.0.1:6379> SUBSCRIBE queue
// 收到新消息
1) "message"
2) "queue"
3) "msg1"

使用 Pub/Sub 這種方案兢卵,既支持阻塞式拉取消息,還很好地滿足了多組消費(fèi)者绪颖,消費(fèi)同一批數(shù)據(jù)的業(yè)務(wù)需求秽荤。除此之外甜奄,Pub/Sub 還提供了「匹配訂閱」模式,允許消費(fèi)者根據(jù)一定規(guī)則窃款,訂閱「多個」自己感興趣的隊列课兄。

// 訂閱符合規(guī)則的隊列
127.0.0.1:6379> PSUBSCRIBE queue.*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "queue.*"
3) (integer) 1

Pub/Sub 最大的優(yōu)勢就是,支持多組生產(chǎn)者晨继、消費(fèi)者處理消息烟阐。講完了它的優(yōu)點(diǎn),那它有什么缺點(diǎn)呢紊扬?其實(shí)蜒茄,Pub/Sub 最大問題是:丟數(shù)據(jù)。

  • 消費(fèi)者下線
  • Redis 宕機(jī)
  • 消息堆積

Pub/Sub 在實(shí)現(xiàn)時非常簡單餐屎,它沒有基于任何數(shù)據(jù)類型檀葛,也沒有做任何的數(shù)據(jù)存儲,它只是單純地為生產(chǎn)者腹缩、消費(fèi)者建立「數(shù)據(jù)轉(zhuǎn)發(fā)通道」屿聋,把符合規(guī)則的數(shù)據(jù),從一端轉(zhuǎn)發(fā)到另一端藏鹊。
一個完整的發(fā)布润讥、訂閱消息處理流程是這樣的:
消費(fèi)者訂閱指定隊列,Redis 就會記錄一個映射關(guān)系:隊列->消費(fèi)者
生產(chǎn)者向這個隊列發(fā)布消息盘寡,那 Redis 就從映射關(guān)系中找出對應(yīng)的消費(fèi)者象对,把消息轉(zhuǎn)發(fā)給它,整個過程中,沒有任何的數(shù)據(jù)存儲宴抚,一切都是實(shí)時轉(zhuǎn)發(fā)的勒魔。

  • 例如,如果一個消費(fèi)者異常掛掉了菇曲,它再重新上線后冠绢,只能接收新的消息,在下線期間生產(chǎn)者發(fā)布的消息常潮,因為找不到消費(fèi)者弟胀,都會被丟棄掉。
  • 如果所有消費(fèi)者都下線了喊式,那生產(chǎn)者發(fā)布的消息孵户,因為找不到任何一個消費(fèi)者,也會全部「丟棄」岔留。
    所以夏哭,當(dāng)你在使用 Pub/Sub 時,一定要注意:消費(fèi)者必須先訂閱隊列献联,生產(chǎn)者才能發(fā)布消息竖配,否則消息會丟失何址。
    另外,因為 Pub/Sub 沒有基于任何數(shù)據(jù)類型實(shí)現(xiàn)进胯,所以它也不具備「數(shù)據(jù)持久化」的能力用爪。
    也就是說,Pub/Sub 的相關(guān)操作胁镐,不會寫入到 RDB 和 AOF 中偎血,當(dāng) Redis 宕機(jī)重啟,Pub/Sub 的數(shù)據(jù)也會全部丟失盯漂。

Pub/Sub 在處理「消息積壓」時烁巫,為什么也會丟數(shù)據(jù)?

當(dāng)消費(fèi)者的速度宠能,跟不上生產(chǎn)者時,就會導(dǎo)致數(shù)據(jù)積壓的情況發(fā)生磁餐。
如果采用 List 當(dāng)作隊列违崇,消息積壓時,會導(dǎo)致這個鏈表很長诊霹,最直接的影響就是羞延,Redis 內(nèi)存會持續(xù)增長,直到消費(fèi)者把所有數(shù)據(jù)都從鏈表中取出脾还。
但 Pub/Sub 的處理方式卻不一樣伴箩,當(dāng)消息積壓時有可能會導(dǎo)致消費(fèi)失敗和消息丟失。
每個消費(fèi)者訂閱一個隊列時鄙漏,Redis 都會在 Server 上給這個消費(fèi)者在分配一個「緩沖區(qū)」嗤谚,這個緩沖區(qū)其實(shí)就是一塊內(nèi)存。當(dāng)生產(chǎn)者發(fā)布消息時怔蚌,Redis 先把消息寫到對應(yīng)消費(fèi)者的緩沖區(qū)中巩步。之后,消費(fèi)者不斷地從緩沖區(qū)讀取消息桦踊,處理消息椅野。
因為這個緩沖區(qū)其實(shí)是有「上限」的(可配置),如果消費(fèi)者拉取消息很慢籍胯,就會造成生產(chǎn)者發(fā)布到緩沖區(qū)的消息開始積壓竟闪,緩沖區(qū)內(nèi)存持續(xù)增長。
client-output-buffer-limit pubsub 32mb 8mb 60

  • 32mb:緩沖區(qū)一旦超過 32MB杖狼,Redis 直接強(qiáng)制把消費(fèi)者踢下線
  • 8mb + 60:緩沖區(qū)超過 8MB炼蛤,并且持續(xù) 60 秒,Redis 也會把消費(fèi)者踢下線
    Pub/Sub 的優(yōu)缺點(diǎn):
  • 支持發(fā)布 / 訂閱蝶涩,支持多組生產(chǎn)者鲸湃、消費(fèi)者處理消息
  • 消費(fèi)者下線赠涮,數(shù)據(jù)會丟失
  • 不支持?jǐn)?shù)據(jù)持久化,Redis 宕機(jī)暗挑,數(shù)據(jù)也會丟失
  • 消息堆積笋除,緩沖區(qū)溢出,消費(fèi)者會被強(qiáng)制踢下線炸裆,數(shù)據(jù)也會丟失

二者的區(qū)別

List 其實(shí)是屬于「拉」模型垃它,而 Pub/Sub 其實(shí)屬于「推」模型。List 中的數(shù)據(jù)可以一直積壓在內(nèi)存中烹看,消費(fèi)者什么時候來「拉」都可以国拇。但 Pub/Sub 是把消息先「推」到消費(fèi)者在 Redis Server 上的緩沖區(qū)中,然后等消費(fèi)者再來取惯殊。

Stream模型

在 Redis 5.0 版本酱吝,作者把 disque 功能移植到了 Redis 中,并給它定義了一個新的數(shù)據(jù)類型:Stream土思。

生產(chǎn)者發(fā)布 2 條消息:
使用 XADD 命令發(fā)布消息务热,其中的「*」表示讓 Redis 自動生成唯一的消息 ID,這個消息 ID 的格式是「時間戳-自增序號」。
127.0.0.1:6379> XADD queue * name zhangsan
"1618469123380-0"
127.0.0.1:6379> XADD queue * name lisi
"1618469127777-0"

消費(fèi)者拉取消息:
從開頭讀取5條消息己儒,0-0表示從開頭讀取
127.0.0.1:6379> XREAD COUNT 5 STREAMS queue 0-0
1) 1) "queue"
   2) 1) 1) "1618469123380-0"
         2) 1) "name"
            2) "zhangsan"
      2) 1) "1618469127777-0"
         2) 1) "name"
            2) "lisi"


如果想繼續(xù)拉取消息崎岂,需要傳入上一條消息的 ID:
127.0.0.1:6379> XREAD COUNT 5 STREAMS queue 1618469127777-0
沒有消息,Redis 會返回 NULL闪湾。

Stream 是否支持「阻塞式」拉取消息冲甘?

// BLOCK 0 表示阻塞等待,不設(shè)置超時時間
127.0.0.1:6379> XREAD COUNT 5 BLOCK 0 STREAMS queue 1618469127777-0

Stream 是否支持發(fā)布 / 訂閱模式途样?

  • XGROUP:創(chuàng)建消費(fèi)者組
  • XREADGROUP:在指定消費(fèi)組下江醇,開啟消費(fèi)者拉取消息
生產(chǎn)者發(fā)布 2 條消息:
127.0.0.1:6379> XADD queue * name zhangsan
"1618470740565-0"
127.0.0.1:6379> XADD queue * name lisi
"1618470743793-0"

2 組消費(fèi)者處理同一批數(shù)據(jù),就需要創(chuàng)建 2 個消費(fèi)者組:
// 創(chuàng)建消費(fèi)者組1何暇,0-0表示從頭拉取消息
127.0.0.1:6379> XGROUP CREATE queue group1 0-0
OK
// 創(chuàng)建消費(fèi)者組2嫁审,0-0表示從頭拉取消息
127.0.0.1:6379> XGROUP CREATE queue group2 0-0
OK

消費(fèi)者組創(chuàng)建好之后,我們可以給每個「消費(fèi)者組」下面掛一個「消費(fèi)者」赖晶,讓它們分別處理同一批數(shù)據(jù)律适。

第一個消費(fèi)組開始消費(fèi):
// group1的consumer開始消費(fèi),>表示拉取最新數(shù)據(jù)
127.0.0.1:6379> XREADGROUP GROUP group1 consumer COUNT 5 STREAMS queue >
1) 1) "queue"
   2) 1) 1) "1618470740565-0"
         2) 1) "name"
            2) "zhangsan"
      2) 1) "1618470743793-0"
         2) 1) "name"
            2) "lisi"
第二個消費(fèi)組開始消費(fèi):



// group2的consumer開始消費(fèi)遏插,>表示拉取最新數(shù)據(jù)
127.0.0.1:6379> XREADGROUP GROUP group2 consumer COUNT 5 STREAMS queue >
1) 1) "queue"
   2) 1) 1) "1618470740565-0"
         2) 1) "name"
            2) "zhangsan"
      2) 1) "1618470743793-0"
         2) 1) "name"
            2) "lisi"

消息處理時異常捂贿,Stream 能否保證消息不丟失,重新消費(fèi)胳嘲?

除了上面拉取消息時用到了消息 ID厂僧,這里為了保證重新消費(fèi),也要用到這個消息 ID了牛。
當(dāng)一組消費(fèi)者處理完消息后颜屠,需要執(zhí)行 XACK 命令告知 Redis辰妙,這時 Redis 就會把這條消息標(biāo)記為「處理完成」。如果消費(fèi)者異常宕機(jī)甫窟,肯定不會發(fā)送 XACK密浑,那么 Redis 就會依舊保留這條消息。待這組消費(fèi)者重新上線后粗井,Redis 就會把之前沒有處理成功的數(shù)據(jù)尔破,重新發(fā)給這個消費(fèi)者。這樣一來浇衬,即使消費(fèi)者異常懒构,也不會丟失數(shù)據(jù)了。

// group1下的 1618472043089-0 消息已處理完成
127.0.0.1:6379> XACK queue group1 1618472043089-0

// 消費(fèi)者重新上線耘擂,0-0表示重新拉取未ACK的消息
127.0.0.1:6379> XREADGROUP GROUP group1 consumer1 COUNT 5 STREAMS queue 0-0
// 之前沒消費(fèi)成功的數(shù)據(jù)胆剧,依舊可以重新消費(fèi)
1) 1) "queue"
   2) 1) 1) "1618472043089-0"
         2) 1) "name"
            2) "zhangsan"
      2) 1) "1618472045158-0"
         2) 1) "name"
            2) "lisi"

Stream 數(shù)據(jù)會寫入到 RDB 和 AOF 做持久化嗎?

Stream 是新增加的數(shù)據(jù)類型醉冤,它與其它數(shù)據(jù)類型一樣秩霍,每個寫操作,也都會寫入到 RDB 和 AOF 中冤灾。我們只需要配置好持久化策略,就算 Redis 宕機(jī)重啟辕近,Stream 中的數(shù)據(jù)也可以從 RDB 或 AOF 中恢復(fù)回來韵吨。

消息堆積時,Stream 是怎么處理的移宅?

當(dāng)消息隊列發(fā)生消息堆積時归粉,一般只有 2 個解決方案:

  • 生產(chǎn)者限流:避免消費(fèi)者處理不及時,導(dǎo)致持續(xù)積壓
  • 丟棄消息:中間件丟棄舊消息漏峰,只保留固定長度的新消息

而 Redis 在實(shí)現(xiàn) Stream 時糠悼,采用了第 2 個方案。在發(fā)布消息時浅乔,你可以指定隊列的最大長度倔喂,防止隊列積壓導(dǎo)致內(nèi)存爆炸。當(dāng)隊列長度超過上限后靖苇,舊消息會被刪除席噩,只保留固定長度的新消息。

// 隊列長度最大10000
127.0.0.1:6379> XADD queue MAXLEN 10000 * name zhangsan
"1618473015018-0"

到底Redis適不適合做消息隊列贤壁?

核心目標(biāo)就是不允許數(shù)據(jù)丟失悼枢,消息是否會發(fā)生丟失,其重點(diǎn)也就在于以下 3 個環(huán)節(jié):

  • 生產(chǎn)者會不會丟消息脾拆?
  • 消費(fèi)者會不會丟消息馒索?
  • 隊列中間件會不會丟消息莹妒?

生產(chǎn)者會不會丟消息?

當(dāng)生產(chǎn)者在發(fā)布消息時绰上,可能發(fā)生以下異常情況:

  • 消息沒發(fā)出去:網(wǎng)絡(luò)故障或其它問題導(dǎo)致發(fā)布失敗旨怠,中間件直接返回失敗
  • 不確定是否發(fā)布成功:網(wǎng)絡(luò)問題導(dǎo)致發(fā)布超時,可能數(shù)據(jù)已發(fā)送成功渔期,但讀取響應(yīng)結(jié)果超時了
    如果是情況 1运吓,消息根本沒發(fā)出去,那么重新發(fā)一次就好了疯趟。
    如果是情況 2拘哨,生產(chǎn)者沒辦法知道消息到底有沒有發(fā)成功?所以信峻,為了避免消息丟失倦青,它也只能繼續(xù)重試,直到發(fā)布成功為止盹舞。
    生產(chǎn)者一般會設(shè)定一個最大重試次數(shù)产镐,超過上限依舊失敗,需要記錄日志報警處理踢步。也就是說癣亚,生產(chǎn)者為了避免消息丟失,只能采用失敗重試的方式來處理获印。這也意味著消息可能會重復(fù)發(fā)送述雾。
    是的,在使用消息隊列時兼丰,要保證消息不丟玻孟,寧可重發(fā),也不能丟棄鳍征。
    那消費(fèi)者這邊黍翎,就需要多做一些邏輯了。對于敏感業(yè)務(wù)艳丛,當(dāng)消費(fèi)者收到重復(fù)數(shù)據(jù)數(shù)據(jù)時匣掸,要設(shè)計冪等邏輯,保證業(yè)務(wù)的正確性氮双。
    從這個角度來看旺聚,生產(chǎn)者會不會丟消息,取決于生產(chǎn)者對于異常情況的處理是否合理眶蕉。
    以砰粹,無論是 Redis 還是專業(yè)的隊列中間件,生產(chǎn)者在這一點(diǎn)上都是可以保證消息不丟的。

消費(fèi)者會不會丟消息碱璃?

消費(fèi)者拿到消息后弄痹,還沒處理完成就異常宕機(jī)了,那消費(fèi)者還能否重新消費(fèi)失敗的消息嵌器?
要解決這個問題肛真,消費(fèi)者在處理完消息后,必須「告知」隊列中間件爽航,隊列中間件才會把標(biāo)記已處理蚓让,否則仍舊把這些數(shù)據(jù)發(fā)給消費(fèi)者。這種方案需要消費(fèi)者和中間件互相配合讥珍,才能保證消費(fèi)者這一側(cè)的消息不丟历极。無論是 Redis 的 Stream,還是專業(yè)的隊列中間件衷佃,例如 RabbitMQ趟卸、Kafka,其實(shí)都是這么做的氏义。
所以锄列,從這個角度來看,Redis 也是合格的惯悠。

隊列中間件會不會丟消息邻邮?

在這個方面,Redis 其實(shí)沒有達(dá)到要求克婶。Redis 在以下 2 個場景下筒严,都會導(dǎo)致數(shù)據(jù)丟失。

  • AOF 持久化配置為每秒寫盤鸠补,但這個寫盤過程是異步的萝风,Redis 宕機(jī)時會存在數(shù)據(jù)丟失的可能
  • 主從復(fù)制也是異步的嘀掸,主從切換時紫岩,也存在丟失數(shù)據(jù)的可能(從庫還未同步完成主庫發(fā)來的數(shù)據(jù),就被提成主庫)
    基于以上原因我們可以看到睬塌,Redis 本身的無法保證嚴(yán)格的數(shù)據(jù)完整性泉蝌。所以,如果把 Redis 當(dāng)做消息隊列揩晴,在這方面是有可能導(dǎo)致數(shù)據(jù)丟失的勋陪。
    像 RabbitMQ 或 Kafka 這類專業(yè)的隊列中間件,在使用時硫兰,一般是部署一個集群诅愚,生產(chǎn)者在發(fā)布消息時,隊列中間件通常會寫「多個節(jié)點(diǎn)」劫映,以此保證消息的完整性违孝。這樣一來刹前,即便其中一個節(jié)點(diǎn)掛了,也能保證集群的數(shù)據(jù)不丟失雌桑。
    也正因為如此喇喉,RabbitMQ、Kafka在設(shè)計時也更復(fù)雜校坑。畢竟拣技,它們是專門針對隊列場景設(shè)計的。
    但 Redis 的定位則不同耍目,它的定位更多是當(dāng)作緩存來用膏斤,它們兩者在這個方面肯定是存在差異的。

消息積壓怎么辦制妄?

因為 Redis 的數(shù)據(jù)都存儲在內(nèi)存中掸绞,這就意味著一旦發(fā)生消息積壓,則會導(dǎo)致 Redis 的內(nèi)存持續(xù)增長耕捞,如果超過機(jī)器內(nèi)存上限衔掸,就會面臨被 OOM 的風(fēng)險。
所以俺抽,Redis 的 Stream 提供了可以指定隊列最大長度的功能敞映,就是為了避免這種情況發(fā)生。
但 Kafka磷斧、RabbitMQ 這類消息隊列就不一樣了振愿,它們的數(shù)據(jù)都會存儲在磁盤上,磁盤的成本要比內(nèi)存小得多弛饭,當(dāng)消息積壓時冕末,無非就是多占用一些磁盤空間,相比于內(nèi)存侣颂,在面對積壓時也會更加「坦然」档桃。

消息隊列方案選型

綜上,我們可以看到憔晒,把 Redis 當(dāng)作隊列來使用時藻肄,始終面臨的 2 個問題:

  • Redis 本身可能會丟數(shù)據(jù)
  • 面對消息積壓,Redis 內(nèi)存資源緊張
    如果你的業(yè)務(wù)場景足夠簡單拒担,對于數(shù)據(jù)丟失不敏感嘹屯,而且消息積壓概率比較小的情況下,把 Redis 當(dāng)作隊列是完全可以的从撼。
    而且州弟,Redis 相比于 Kafka、RabbitMQ,部署和運(yùn)維也更加輕量婆翔。
    如果你的業(yè)務(wù)場景對于數(shù)據(jù)丟失非常敏感桐经,而且寫入量非常大消息積壓時會占用很多的機(jī)器資源,那么我建議你使用專業(yè)的消息隊列中間件浙滤。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阴挣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子纺腊,更是在濱河造成了極大的恐慌畔咧,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揖膜,死亡現(xiàn)場離奇詭異誓沸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)壹粟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門拜隧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人趁仙,你說我怎么就攤上這事洪添。” “怎么了雀费?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵干奢,是天一觀的道長。 經(jīng)常有香客問我盏袄,道長忿峻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任辕羽,我火速辦了婚禮逛尚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘刁愿。我一直安慰自己绰寞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布酌毡。 她就那樣靜靜地躺著克握,像睡著了一般蕾管。 火紅的嫁衣襯著肌膚如雪枷踏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天掰曾,我揣著相機(jī)與錄音旭蠕,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛掏熬,可吹牛的內(nèi)容都是我干的佑稠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼旗芬,長吁一口氣:“原來是場噩夢啊……” “哼舌胶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起疮丛,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤幔嫂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后誊薄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體履恩,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年呢蔫,在試婚紗的時候發(fā)現(xiàn)自己被綠了切心。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡片吊,死狀恐怖绽昏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情俏脊,我是刑警寧澤而涉,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站联予,受9級特大地震影響啼县,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沸久,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一季眷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卷胯,春花似錦子刮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至担钮,卻和暖如春橱赠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背箫津。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工狭姨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宰啦,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓饼拍,卻偏偏與公主長得像赡模,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子师抄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 本文轉(zhuǎn)載于:https://mp.weixin.qq.com/s/uhMrqR__6qgpl7vrE_otTQ[h...
    上善若淚閱讀 860評論 0 1
  • 原文鏈接:Redis實(shí)現(xiàn)消息隊列的方案 Redis作為內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)存儲漓柑,常用作數(shù)據(jù)庫、緩存和消息代理叨吮。它支持?jǐn)?shù)...
    這個ID狠溫柔閱讀 101,246評論 2 28
  • 一欺缘、概述 消息隊列,Message Queue挤安,常用于解決并發(fā)系統(tǒng)中的資源一致性問題谚殊,提升峰值的處理能力,同時保證...
    陽公子_閱讀 767評論 0 1
  • Redis實(shí)現(xiàn)輕量級的消息隊列與消息中間件相比蛤铜,沒有高級特性也沒有ACK保證嫩絮,無法做到數(shù)據(jù)不重不漏,如果業(yè)務(wù)簡單而...
    JunChow520閱讀 39,487評論 3 11
  • Redis真的不愧是萬金油围肥,小到靜態(tài)緩存剿干,大到鎖機(jī)制,消息隊列穆刻,啥都能做置尔。今天小馬就來一起體驗下redis實(shí)現(xiàn)消息...
    小馬過河R閱讀 415評論 2 4