隊列:實現方式 queue
特色:先進先出
做用:
1)實現程序的解耦(思想) 生產者消費者模型 :生產者->Q->消費者
2)流量削峯
生活中的實例:春運火車(繞來繞去的柵欄控制人流量)
線下場景:秒殺
用redis裏的鏈表
將鏈表維護到一個1000長度的大小,而後秒殺開始後,只保存前1000個請求
微博場景:
星軌:一個一線明星出軌帶來的流量,微博服務器如今能夠同時扛八個星軌
微博的流量波動是很難預測的,指不定何時出來一個熱點話題,微博的流量會垂直上升
消息隊列能夠把消息分類,分別下發,好比點贊、評論和轉發,各自走各自的通道
消息隊列能夠暫存消息。當用戶的請求到達消息隊列之後,消息隊列就給用戶發出響應,顯示評論成功,即便這時候該評論還沒寫入數據庫,但是用戶是不感知的。當流量暴增的時候,生產者生成的消息大於消費者的處理能力,消息就會先被暫存在消息隊列裏,而後消費者全力去處理,這樣就避免了服務器壓力過大。消息隊列並非所有存儲在內存中,也是能夠寫入硬盤的,因此能存儲很大量的消息。
①redis
②微博用的kafaka(java)專門用來作消息隊列的性能巨高
③rabbitmq
④rocketmq(阿里開源的基於rabbitmq搞的,只要是阿里開源的基本都是用java寫的)
https://lupython.gitee.io/2018/05/07/RabbitMQ的使用講解/
linux:
安裝:[root@db01 ~]# yum install rabbitmq*
啓動:[root@db01 ~]# rabbitmq-server
https://www.rabbitmq.com
如何實現生產者,queue,消費者數據不丟失?
-在聲明queue的時候,持久化(durable=True) #生產者消費者都要持久化
例如:聲明一個叫hello的queue
channel.queue_declare(queue='hello',durable=True)
-在生產者端,須要加上下面代碼,確保消息已經持久化了
properties=pika.BasicProperties(
delivery_mode=2, # make message persistent
)
-消費者端:
auto_ack = False #當queue中的消息消費完之後,給生產者一個反饋
Exchange類型:
direct:組播 #rabbitmq官網中的Routing
消息中的路由鍵(routing key)若是和 Binding 中的 binding key 一致, 交換器就將消息發到對應的隊列中。路由鍵與隊列名徹底匹配,若是一個隊列綁定到交換機要求路由鍵爲「dog」,則只轉發 routing key 標記爲「dog」的消息,不會轉發「dog.puppy」,也不會轉發「dog.guard」等等。它是徹底匹配、單播的模式
fanout:廣播
每一個發到fanout 類型交換器的消息都會分到全部綁定的隊列上去。fanout交換器不處理路由鍵,只是簡單的將隊列綁定到交換器上,每一個發送到交換器的消息都會被轉發到與該交換器綁定的全部隊列上。很像子網廣播,每臺子網內的主機都得到了一份複製的消息。fanout類型轉發消息是最快的。例子:發微博粉絲均可以收到信息
topic :規則播 #rabbitmq官網中的Topics
topic交換器經過模式匹配分配消息的路由鍵屬性,將路由鍵和某個模式進行匹配,此時隊列須要綁定到一個模式上。它將路由鍵和綁定鍵的字符串切分紅單詞,這些單詞之間用點隔開,實際上增長了一點正則表達式的知識在裏面,例如你的消息是usa開頭的,那麼它會走到usa.# 這個routing key裏面
headers: headers 交換器和 direct 交換器徹底一致,但性能差不少,目前幾乎用不到了