做網(wǎng)站開發(fā)的集團(tuán)品牌策劃案例
背景
已知rabbitmq和kafka作為消息中間件來給程序之間增加異步消息傳遞功能,這兩個(gè)中間件都是專業(yè)的,功能也很強(qiáng),但是有的時(shí)候過于復(fù)雜,對(duì)于只有一組消費(fèi)者的消息隊(duì)列,使用Redis 就可以輕松搞定。
異步消息隊(duì)列
讀者可以思考一下他的幾種數(shù)據(jù)結(jié)構(gòu)哪種更適合,string,hash,set,zset,list?
是的很明顯list',使用rpush/lpush進(jìn)隊(duì)列,rpop/lpop出隊(duì)列
隊(duì)列空了怎么辦
消費(fèi)者重復(fù)快速從隊(duì)列中消費(fèi),那么隊(duì)列很快就會(huì)空,那么就會(huì)重復(fù)pop操作。浪費(fèi)生命的空輪詢,拉高無用的能耗,通常的解決方案就是讓消費(fèi)線程睡一會(huì),一般1s就夠了。
但是又有新問題,如果消費(fèi)者數(shù)量過多,睡眠時(shí)間綜合起來就太多了,縮短睡眠時(shí)間?但還是有別的方案,阻塞讀
blpop brpop? ?b前綴是blocking 阻塞
?阻塞讀是隊(duì)列為空時(shí)會(huì)立刻進(jìn)入休眠狀態(tài),一旦數(shù)據(jù)來了就立即喚醒,基本沒有延遲。
看起來是不是完美無缺,但是如果斷開鏈接呢?
線程一直阻塞的話,Redis鏈接閑置的話,服務(wù)器會(huì)關(guān)閉它,并拋出異常。
延時(shí)隊(duì)列的實(shí)現(xiàn)
redis中一種特殊的數(shù)據(jù)結(jié)構(gòu),zset,消息序列化成一個(gè)字符串作為zset的value,消息的到期時(shí)間作為他們的score,用多個(gè)線程輪詢zset獲取到期的任務(wù)處理。(多個(gè)線程保證可用,一個(gè)線程掛了還有其他的)