1.Hello World#前山翻譯

注:這是RabbitMQ-java版Client的指導(dǎo)教程翻譯系列文章,歡迎大家批評指正
第一篇Hello Word了解RabbitMQ的基本用法
第二篇Work Queues介紹隊(duì)列的使用
第三篇Publish/Subscribe介紹轉(zhuǎn)換器以及其中fanout類型
第四篇Routing介紹direct類型轉(zhuǎn)換器
第五篇Topics介紹topic類型轉(zhuǎn)換器
第六篇RPC介紹遠(yuǎn)程調(diào)用

預(yù)備條件
這篇指導(dǎo)教程的前提是已經(jīng)下載了RabbitMQ并且運(yùn)行在本機(jī)上默認(rèn)端口號5672。如果你使用不同的主機(jī),端口號或者相關(guān)認(rèn)證,連接設(shè)置需要做一些調(diào)整。
尋求幫助
如果你在閱讀這個(gè)系列指導(dǎo)教程時(shí)有任何的問題,可以通過郵件聯(lián)系我們

介紹(Introduction)

RabbitMQ是一個(gè)消息中間件:它接受并轉(zhuǎn)發(fā)消息。你可以把它看成是一個(gè)郵局:當(dāng)你把想投遞的郵件放在郵箱中時(shí),知道郵遞員終會(huì)把郵件派送給收件人。這個(gè)比喻中,RabbitMQ是郵箱,郵局和郵遞員。

RabbitMQ和郵局之間最大的不同是前者不需要處理紙張,就可以接受,存儲(chǔ)并且傳發(fā)二進(jìn)制數(shù)據(jù)的消息。

通常,RabbitMQ和消息傳送會(huì)有一些專業(yè)術(shù)語。

生產(chǎn)和發(fā)送的意義是一樣的,一個(gè)應(yīng)用發(fā)送消息就是生產(chǎn)者:

producer.png

隊(duì)列類似郵局中的郵箱存在于RabbitMQ中,盡管消息是在RabbitMQ和應(yīng)用間傳送,但消息只存儲(chǔ)在隊(duì)列中。隊(duì)列的大小只受限于主機(jī)的內(nèi)存或者硬盤的大小,本質(zhì)上是有無限大的緩存區(qū)間。許多生產(chǎn)者可以發(fā)送消息到一個(gè)隊(duì)列中,當(dāng)然需要消費(fèi)者也可以從一個(gè)隊(duì)列中接受消息。我們用下列圖形代表隊(duì)列:

queue.png

消費(fèi)和接受有著同樣的意思,一個(gè)應(yīng)用常在等待接受消息就是消費(fèi)者:
consumer.png

注解:生產(chǎn)者,消費(fèi)者以及消息中間件并不會(huì)存在于同一個(gè)主機(jī)上,且大部分應(yīng)用確實(shí)也不會(huì)這樣做。

"Hello World"

(using the java Client ,我是搞Android開發(fā)的,所以語言沒得選:java是當(dāng)今世界上最流行的語言)

在這篇指導(dǎo)教程中,我們將用Java寫兩個(gè)應(yīng)用,發(fā)送一條簡單消息的生產(chǎn)者,和接受消息并且將消息打印出來的消費(fèi)者。我們將會(huì)省略掉部分Java API的具體細(xì)節(jié),專注于開始學(xué)習(xí)最簡單的"Hello World"消息傳遞。

在下面的圖表中,"P"表示生產(chǎn)者和"C"表示消費(fèi)者,中間的盒子表示隊(duì)列-消費(fèi)者的消息緩存在RabbitMQ中。

java_one.png

MabbitMQ的java版本客戶端的依賴包(The Java Client library)
RabbitMQ支持多種協(xié)議,這篇指導(dǎo)教程中使用AMQP協(xié)議,這是一個(gè)開源,多用途的消息傳遞協(xié)議。針對不同的語言,RabbitMQ提供專門的客戶端版本,目前我們使用的是Java版本。
下載Java Client library并且依賴于SLF4J APISLF4J Simple,拷貝這些文件到你的工作目錄下,跟其它的java文件一塊放。
請注意SLF4J Simple只是在指導(dǎo)教程中使用,而在真正的生產(chǎn)項(xiàng)目中,應(yīng)該使用更強(qiáng)大的日志包,像Logback。
現(xiàn)在我們有了Java版本的客戶端RabbitMQ和依賴包,可以寫些代碼了。

發(fā)送(Sending)

sending.png

我們將稱消息發(fā)布者(發(fā)送者)為Send,消息消費(fèi)者(接受者)為Recv。發(fā)布者將會(huì)連接上服務(wù)端RabbitMQ,發(fā)送一條簡單的消息,然后退出。

在Send.java中,我們需要引入一些類:

import com.rabbitmq.client.ConnectionFactory;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.Channel;

創(chuàng)建類并且給隊(duì)列命名:

public class Send {

    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv)  throws java.io.IOException {

      ...

    }

}

接著我們連接服務(wù)端:

ConnectionFactory factory = new ConnectionFactory();

factory.setHost("localhost");  //factory可以設(shè)置主機(jī)Ip,端口號,認(rèn)證信息等連接服務(wù)端

Connection connection = factory.newConnection();  //創(chuàng)建連接

Channel channel = connection.createChannel();  //創(chuàng)建通道

這是抽象的Socket(套接宇)連接方式,注意協(xié)議版本的差異和驗(yàn)證等等都取決于我們自己。我們連接到本機(jī)的RabbitMQ上,所以才是localhost。如果我們想連接到不同的機(jī)器上的RabbitMQ上,可以簡單說明該機(jī)器的名稱和IP地址。(下面代碼是我擅自添加的)

factory.setPort(8080);

factory.setUsername("admin");

factory.setPassword("password"):

下一步創(chuàng)建通道(channel),大部分的事情都是在這里處理。

我們必須先聲明發(fā)送消息去的隊(duì)列,然后發(fā)送消息到隊(duì)列中:

channel.queueDeclare(QUEUE_NAME, false, false, false, null);

String message = "Hello World!";

channel.basicPublish("", QUEUE_NAME, null, message.getBytes());

System.out.println(" [x] Sent '" + message + "'");

聲明隊(duì)列是很重要的,它不存在時(shí)才會(huì)被創(chuàng)建,消息體是字節(jié)數(shù)組類型,因此可以在這里編碼你需要的類型。
最后,關(guān)閉通道和連接:

channel.close();
connection.close();

這里是Send.java的源碼(這么簡答的代碼,不想貼)

發(fā)送失敗

如果這是你第一次使用RabbitMQ,并且你沒有看到發(fā)送的消息,可能傷腦筋了:哪里出了問題?可能是消息中間件開始的時(shí)候可用硬盤空間不足(默認(rèn)的至少剩余200MB),因此會(huì)拒絕接收消息。查看消息中間件的日志文件和如果有必要的話減少這些限制。這篇配置文檔將會(huì)告訴你如何去設(shè)置硬盤剩余空間的限制。

接受(Receiving)

發(fā)布者相對應(yīng)的就是我們的接受者,接受者是接受從RabbitMQ推送過來的消息,而不像發(fā)布者是發(fā)布消息到RabbitMQ中。我們設(shè)置了對消息的監(jiān)聽,并且打印出消息:


receiving.png

Recv.java的引入類和Send.java有三個(gè)是一樣的:

import com.rabbitmq.client.ConnectionFactory;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Consumer;

import com.rabbitmq.client.DefaultConsumer;

這個(gè)額外的DefaultConsumer是一個(gè)實(shí)現(xiàn)了Consumer接口的類,我們用來緩存由服務(wù)端推送給接受者的消息。

和發(fā)布者開始的創(chuàng)建是類似的,打開連接(connection)和通道(channel),并且聲明一條可以消費(fèi)消息的隊(duì)列。注意這個(gè)隊(duì)列是匹配send發(fā)布消息的隊(duì)列:

public class Recv {

    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv)  throws  java.io.IOException,  java.lang.InterruptedException {

        ConnectionFactory factory = new ConnectionFactory();

        factory.setHost("localhost");

        Connection connection = factory.newConnection();

        Channel channel = connection.createChannel();

        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

        ...

    }

}

請注意消費(fèi)者也聲明了隊(duì)列,因?yàn)槲覀兛梢栽趧?chuàng)建發(fā)布者之前先創(chuàng)建消費(fèi)者。我們像確保這些隊(duì)列已經(jīng)存在了,然后就可以從隊(duì)列中消費(fèi)消息。

將要告訴 服務(wù)端要從隊(duì)列中分發(fā)消費(fèi)者的消息,然后就會(huì)異步的推送消息給消費(fèi)者。我們提供了一個(gè)callBack的表單對象用于緩存消息直到消費(fèi)者已經(jīng)獲取到它們。這個(gè)就是DefaultConsumer子類的工作:

Consumer consumer = new DefaultConsumer(channel) {

    @Override

    public void handleDelivery(String consumerTag, Envelope envelope,AMQP.BasicProperties properties, byte[] body)  throws IOException {

        String message = new String(body, "UTF-8");

        System.out.println(" [x] Received '" + message + "'");

   }

};

    channel.basicConsume(QUEUE_NAME, true, consumer);

綜合

你可以在RabbitMQ java客戶端編譯這些類:

javac -cp amqp-client-4.0.2.jar Send.java Recv.java

在一個(gè)終端上運(yùn)行消費(fèi)者,你需要rabbitmq-client.jar和一些依賴:

java -cp .:amqp-client-4.0.2.jar:slf4j-api-1.7.21.jar:slf4j-simple-1.7.22.jar Recv

接著運(yùn)行生產(chǎn)者:

java -cp .:amqp-client-4.0.2.jar:slf4j-api-1.7.21.jar:slf4j-simple-1.7.22.jar Send

在Windows系統(tǒng)上,使用分好代替冒號去分割每一個(gè)條目。
通過RabbitMQ,消費(fèi)者將會(huì)打印出從生產(chǎn)者接受的消息,并且一直運(yùn)行等待著接受消息(可以使用Ctrl +C去停止運(yùn)行),因此可以嘗試從另外一個(gè)終端來運(yùn)行生產(chǎn)者。

第一節(jié)的內(nèi)容大致翻譯完了,這里是原文的鏈接。接著進(jìn)入下一節(jié):Work Queues

終篇是我對RabbitMQ使用理解的總結(jié)文章,歡迎討教。
--謝謝--

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,976評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,958評論 2 373

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,781評論 18 139
  • 來源 RabbitMQ是用Erlang實(shí)現(xiàn)的一個(gè)高并發(fā)高可靠AMQP消息隊(duì)列服務(wù)器。支持消息的持久化、事務(wù)、擁塞控...
    jiangmo閱讀 10,374評論 2 34
  • 關(guān)于消息隊(duì)列,從前年開始斷斷續(xù)續(xù)看了些資料,想寫很久了,但一直沒騰出空,近來分別碰到幾個(gè)朋友聊這塊的技術(shù)選型,是時(shí)...
    預(yù)流閱讀 585,203評論 51 786
  • 在我的少年時(shí)代,看電影可是一件天大的事兒。 那時(shí)候,一個(gè)公社(大體上相當(dāng)于現(xiàn)在的一個(gè)鄉(xiāng)鎮(zhèn),在管轄范圍上甚至還要更大...
    唐風(fēng)漢韻1970閱讀 92評論 17 16
  • 問答 一、Jquery 中, $(document).ready()是什么意思?和window.onload 的區(qū)...
    咩咩咩1024閱讀 241評論 0 1