1.connection可以用來創(chuàng)建多個channel實例,但是channel實例不能再線程間共享,應(yīng)用程序應(yīng)該為每一個線程開辟一個channel。
2.生產(chǎn)者和消費者都可以聲明一個交換機或者隊列。如果嘗試聲明一個已經(jīng)存在的交換機或者隊列,只要聲明的參數(shù)完全匹配現(xiàn)存的交換機或者隊列浅妆,rabbitmq就可以什么都不做,并成功返回障癌。
3.exchangeDeclare方法詳解: exchangeDeclare(String exchange, Sreing type, boolean derable, boolean autoDelete, boolean internal, Map<String, Object> arguments)throws IOException; exchange:交換機名稱, type:direct, topic, fanout;durable:設(shè)置是否持久化凌外, 設(shè)置為true可以將交換機存盤,在服務(wù)器重啟的時候不會丟失相關(guān)信息涛浙,autoDelete:設(shè)置是否自動刪除,自動刪除的前提是至少有一個隊列或者交換機與這個交換機綁定康辑,之后所有與這個交換機綁定的隊列或者交換機都于此解綁摄欲。internal:設(shè)置是否是內(nèi)置的,內(nèi)置的交換機疮薇,客戶端程序無法直接發(fā)送消息到這個交換機中胸墙,只能通過交換機路由到交換機這種方式。argument:其他一些結(jié)構(gòu)化參數(shù)
4.queueDeclare方法詳解:Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> argument)throws IOException;queue:隊列名稱按咒,durable:設(shè)置是否持久化迟隅。exclusive:設(shè)置是否排他。為true則設(shè)置隊伍為排他励七。如果一個隊列被聲明為排他隊列智袭,該隊列僅對首次聲明他的連接可見,并在連接斷開時自動刪除掠抬,這里要注意三點:排他隊列時基于連接(connection)可見吼野,同一個連接的不同通道(channel)時可以同時訪問同一個連接創(chuàng)建的排他隊列;”首次“是指如果一個連接已經(jīng)聲明一個排他隊列两波,其他連接是不允許創(chuàng)立同名的排他隊列的瞳步,這個與不同隊列不同;即使該隊列是持久化腰奋,一旦連接關(guān)閉或者客戶端退出谚攒,該排他隊列都會被自動刪除,這個隊列適用于一個客戶端同時發(fā)送和讀取消息的應(yīng)用場景氛堕。autoDelete:設(shè)置是否自動刪除,自動刪除的前提是野蝇,至少有一個消費者連接到這個隊列讼稚,之后所有與這個隊列連接的消費者都斷開時,才會自動刪除绕沈。arguments:設(shè)置隊列的其他一些參數(shù)
5.queueBind方法詳解: queueBind(String queue, String exchange, String routingKey);參數(shù)說明:queue:隊列名稱锐想, exchange:交換機名稱, routingKey:用來綁定隊列和交換機的路由健乍狐,argument:定義綁定的一些參數(shù)
6.不僅可以將隊列和交換機綁定起來赠摇,也可以將已經(jīng)被綁定的隊列和交換機進行解綁。具體方法如下:queueUnbind(String queue, String exchange, String routingKey)....
7.交換機與交換機綁定浅蚪。exchangeBind方法詳解:exchangeBind(String destination, String source, String routingkey);destination:目的地交換機藕帜。綁定之后,消息從source交換機轉(zhuǎn)發(fā)到destination交換機惜傲。所以destination交換機的類型是不是應(yīng)該設(shè)置為fanout洽故。
8.發(fā)送消息:basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body) throws IOException;參數(shù)說明:exchange:交換機名稱, routingkey:路由健盗誊, props:消息的基本屬性集时甚, byte[] body:消息體隘弊, mandatory和immediate
9.消費信息:rabbitmq的消費模式分為2種:推(push)模式和拉(pull)模式。推模式采用Basic.consunme進行消費荒适,而拉模式則調(diào)用Basic.Get進行消費梨熙;方法詳解:String basicConsume(String queue, boolean autoAck, Map<String, Object> arguments, Consumer callback)。 queu:隊列的名稱刀诬,autoAck:設(shè)置是否自動確認咽扇,consumerTag:消費者標簽,用來區(qū)分多個消費者舅列。noLocal:設(shè)置為true則表示不能將同一個connection中生產(chǎn)者的消息發(fā)送到這個connection中的消費者肌割,exclusive:設(shè)置是否排他, arguments:設(shè)置消費者的其他參數(shù)帐要, callback:設(shè)置消費者的回調(diào)函數(shù)把敞。
10.basic.Consume將信道(channel)置為接受模式,直到去誒下隊列的訂閱為止榨惠,在接受模式期間奋早,Rabbitmq會不斷的推送消息給消費者,當然推送消息的個數(shù)還是會受到Basic.Qos的限制赠橙。如果只想從隊列獲得單條信息而不是持續(xù)訂閱耽装,建議還是使用basic.Get進行消費,但是不能將Basic.Get放在一個循環(huán)里來代替Basic.Consume,這有會嚴重影響rabbitmq的性能期揪,如果要實現(xiàn)高吞吐量掉奄,消費者應(yīng)該使用basic.Consume方法
11.mandatory參數(shù):設(shè)為true時,交換機無法根據(jù)自身的類型和路由健找到一個符合條件的隊列凤薛,那么Rabbitmq會調(diào)用basic.return命令將消息返回給生產(chǎn)者姓建。當mandatory為false時,出現(xiàn)上述情況缤苫,則消息直接丟棄
12.immediate參數(shù)設(shè)為true時速兔,如果交換機在將消息路由到隊列時發(fā)現(xiàn)隊列上并不存在任何消息者,那么這條消息將不會存入隊列中活玲。(會影響鏡像隊列的性能涣狗,增加代碼復(fù)雜度,建議采用TTL和DLX的方法替代)
13.備份交換器(備胎交換器)生產(chǎn)者在發(fā)送消息的時候如果不設(shè)置mandatory參數(shù)舒憾,那么消息在未被路由的情況下將會丟失镀钓,如果設(shè)置了mandatory參數(shù),那么需要添加returnListener的編程邏輯珍剑,代碼變得復(fù)雜掸宛,那么可以使用備份交換器,這有可以將未被路由的消息存儲在rabbitmq中招拙,再在需要的時間去處理這些消息唧瘾。
求豫。另外如果將ttl設(shè)置為0塌衰,則表示除非此時可以直接將消息投遞給消費者,否則該消息會被直接丟棄蝠嘉。這個特征可以部分替代之前的immediate參數(shù)最疆,之所以部分代替,是因為immediate參數(shù)在投遞失敗時會用basic.return將信息返回蚤告。(這個功能可以用死信隊列來實現(xiàn))
15.設(shè)置隊列的ttl 努酸,(參數(shù):x-expire)表示超過多長時間未使用隊列,就刪除隊列杜恰。未使用的意思就是隊列上沒有任何消費者)
16.DLX 死信交換器获诈。當消息在一個隊列(注意是隊列)中變成死信之后,它能重新被發(fā)送到另一個交換機中心褐,這個交換機就是DLX舔涎,綁定DLX交換機的隊列就稱之為隊列。 消息變成死信的情況有:1.消息被拒絕(basic.Reject/Basic.Nack),并且設(shè)置requeue參數(shù)為false逗爹; 2.消息過期 3.隊列達到最大長度亡嫌。DLX也是一個正常的交換器,和一般的交換器沒什么區(qū)別掘而,它能在任何的隊列上被指定昼伴,實際上就是設(shè)置某個隊列的屬性。通過channel.queueDeclare方法中設(shè)置x-dead-letter-exchange參數(shù)來添加DLX镣屹,也可以設(shè)置DLX的路由健(如果不設(shè)置就按照原來的路由健路由)參數(shù)是x-dead-letter-routing-key.如下圖:
17.優(yōu)先級隊列价涝。具有高優(yōu)先級的隊列具有高的優(yōu)先權(quán)女蜈,優(yōu)先級高的消息具備優(yōu)先被消費的特權(quán)。通過設(shè)置隊列的x-max-priority參數(shù)來實現(xiàn)色瘩。下如圖:
18.消息持久化: 設(shè)置basicProperties中的deliveryMode屬性伪窖,設(shè)置為2就可以實現(xiàn)消息持久化,MessageProperties.PERSISTENT_TEXT_PLAIN實際上封裝了這個屬性
19.注意要點:可以將所有的消息都設(shè)置為持久化居兆,但是這有會嚴重影響rabbitmq的性能(隨機)覆山。寫入磁盤的速度比寫入內(nèi)存的速度慢的不是一點點。對于可靠性不是那么高的消息可以不采用持久化處理以提高整體的吞吐量泥栖。
20.事務(wù)機制簇宽。 rabbitmq客戶端中與事務(wù)機制相關(guān)的方法有三個:channel.txSelect勋篓、channel.txCommit、channel.txRollback魏割。 channel.txSelect將當前信道設(shè)置成事務(wù)模式譬嚣,channel.txCommit用于提交事務(wù),channel.rxRollback用于事務(wù)回滾钞它。 但是問題來了拜银,事務(wù)機制會吸干rabbitmq的性能。所有可以采用下面的方法解決
21.發(fā)送方確認機制遭垛。生產(chǎn)者將信道設(shè)置成confirm(確認)模式尼桶,一旦信號進入confirm模式,所有在該信道上面發(fā)送的消息都會被指派一個唯一的ID(從1開始)锯仪,一旦消息被投遞到所匹配的隊列之后泵督,rabbitmq就會發(fā)送一條確認(basic.ack)給生產(chǎn)者(包含消息的唯一ID),這就是生產(chǎn)者知曉消息已經(jīng)正確到達了隊列卵酪。如果消息和隊列都是可持久化的幌蚊,那么確認消息會在消息寫入磁盤之后發(fā)出。rabbitmq回傳給生產(chǎn)者的確認消息中的deliveryTag包含了確認消息的序號溃卡,此外rabbitmq也可以設(shè)置成channel.basicAck方法中的multiple參數(shù)溢豆,表示到這個序號之前的所有消息已經(jīng)得到了處理。事務(wù)機制在一條信息發(fā)送之后會使發(fā)送端阻塞瘸羡,等待rabbitmq的回應(yīng)漩仙,之后才能繼續(xù)發(fā)送嚇一跳消息。相比之下犹赖,發(fā)送方確認機制最大的好處在于它是異步的队他。
22.生產(chǎn)者通過調(diào)用channel.confirmSelect方法(即Confirm.select命令)將信道設(shè)置成confirm模式,之后rabbitmq會返回confirm.select-ok命令表示同意生產(chǎn)者將當前信道設(shè)置為confirm模式峻村。所有被發(fā)送的后續(xù)消息都被ack或者nack一次麸折。不會出現(xiàn)一條消息既被ack又被nack的情況。并且rabbitmq也并沒有對消息被confirm的快慢做任何保證粘昨。代碼實現(xiàn)如下圖:
也有監(jiān)聽方法:(建議使用此方法)
另外這里需要非常注意的:事務(wù)機制和confirm機制只能確保消息能夠正確的發(fā)送到rabbitmq垢啼。如果交換機沒有匹配的隊列,那么消息也會丟失张肾。所以發(fā)送方要配合mandatory參數(shù)或者備份交換器一起使用來提高消息傳輸?shù)目煽啃浴?
23.新建vhost; rabbitmqctl add_vhost { vhostName} ; 羅列vhost: rabbitmqctl list_vhosts芭析; 刪除vhost: rabbitmqctl delete vhost { vhostName}
24.新建權(quán)限:rabbitmqctl set_permissions [-p vhost] {user} {conf} {write} {read}
清除權(quán)限 rabbitmqctl clear_permissions [ -p vhost ] {username}
25.列舉權(quán)限:有2個列舉權(quán)限的方法,一個是列舉vhost下所有用戶的權(quán)限(rabbitmqctl list_permissions [-p vhost])吞瞪,一個是列舉用戶的所有權(quán)限 (rabbitmqctl list_user_permissions {username} );如圖:
26.用戶管理馁启。用戶是訪問管理的基本單元,且單個用戶可以跨越多個vhost進行授權(quán)芍秆。新增用戶:rabbitmqctl add_user { username} { password} ; 羅列用戶:rabbitmqctl list_users ; 修改用戶密碼:rabbitmq change_password { username} {newpassword} ;刪除用戶: rabbitctl delete_user {username} ,清除用戶密碼:rabbitmqctl clear_password {username} 惯疙。驗證用戶密碼:rabbitmqctl authenticate_user {username} {password} ;分配用戶權(quán)限:rabbitmqctl set_user_tags {username} { 權(quán)限} ;權(quán)限如下:
27.開啟rabbitmq web界面管理翠勉。
rabbitmq-plugins list 查看插件開啟狀況
rabbitmq-plugins enable rabbitmq_management 開啟web界面管理;這里需要注意了螟碎,如果是docker眉菱,那么需要預(yù)先綁定15672端口,因為默認的docker版的rabbitmq:latest是沒有聲明15672端口的掉分。
28.應(yīng)用與集群管理
28.1 rabbitmqctl stop [pid_file] 用于停止運行rabbitmq的Erlang虛擬機和rabbitmq的服務(wù)應(yīng)用
28.2 rabbitmqctl shutdown 用于停止運行rabbitmq的erlang虛擬機和rabbitmq服務(wù)應(yīng)用
28.3 rabbitmqctl stop_app 停止rabbitmq服務(wù)應(yīng)用俭缓,但是erlang虛擬機還是處于運行狀態(tài)
28.4 rabbitmqctl start_app 啟動rabbitmq服務(wù)應(yīng)用.
28.5 rabbitmqctl wait [pid_file] 等待rabbitmq應(yīng)用的啟動。
28.6 rabbitmqctl reset 將rabbitmq節(jié)點重置還原到最初狀態(tài).(執(zhí)行reset之前要先停止rabbitmq應(yīng)用酥郭,比如先執(zhí)行rabbitmqctl stop_app)
28.7 rabbitmqctl force_reset 強制將rabbitmq節(jié)點重置還原到最初狀態(tài)(執(zhí)行reset之前要先停止rabbitmq應(yīng)用华坦,比如先執(zhí)行rabbitmqctl stop_app)
28.8 rabbitmqctl rotate_logs { suffix} 指示rabbitmq節(jié)點輪換日志文件。rabbitmq節(jié)點會將原來的日志文件中的內(nèi)容追加到“原始名稱+后綴”的日志文件中不从,然后再將信的日志內(nèi)容記錄到新創(chuàng)建的日志中(與原日志文件同名)惜姐。當目標文件不存在是,會重新創(chuàng)建椿息。如果不指定后綴suffix歹袁,則日志文件只是重新打開而不會進行輪換。
28.9 rabbitmqctl hipe_compile {directory} 將部分rabbitmq代碼用hipe編譯寝优,并且將編譯后的.beam文件保存到指定的文件目中条舔。如果這個目錄不存在則會自行創(chuàng)建。如果這個目錄原本有任何.beam文件乏矾,則會在執(zhí)行編譯前被刪除孟抗。
29.集群管理
29.1 rabbitmqctl join_cluster { cluster_node} [ --ram] 將節(jié)點加入指定集群中。在這個命令執(zhí)行前需要停止rabbitmq并且重置節(jié)點
29.2 rabbitmqctl cluster_status 顯示集群的狀態(tài)
29.3 rabbitmqctl change_cluster_node_type {disc|ram} 修改節(jié)點集群節(jié)點的類型钻心。在這個命令執(zhí)行前需要停止rabbitmq應(yīng)用凄硼。
29.4 rabbitmqctl forget_cluster_node [ --offine] 將節(jié)點從集群中刪除,允許離線執(zhí)行
29.5 rabbitmqctl update_cluster_nodes { clusternode} 在集群中的節(jié)點應(yīng)用啟動前咨詢clusternode節(jié)點的最新信息捷沸,并更新相應(yīng)的集群信息摊沉。這個和join_cluster不同,它不加入集群
29.6 rabbitmqctl force_boot 確保節(jié)點可以啟動痒给,及時它不是最后一個關(guān)閉的節(jié)點坯钦。
29.7 rabbitmqctl sync_queue [-p vhost] {queue} 只是未通過隊列queue的slave鏡像可以同步master鏡像行的內(nèi)容
29.8 rabbitmqctl set_cluster_name {name} 設(shè)置集群名稱.
30.服務(wù)端狀態(tài)