【譯】RabbitMQ教程一

內(nèi)容來自:RabbitMQ Tutorials Java版


介紹

RabbitMQ是一個消息代理:它接受并轉(zhuǎn)發(fā)消息卦尊。你可以把它當成一個郵局:當你想郵寄信件的時候,你會把信件放在投遞箱中成黄,并確信郵遞員最終會將信件送到收件人的手里。在這個例子中稠炬,RabbitMQ就相當與投遞箱点额、郵局和郵遞員。

RabbitMQ與郵局的區(qū)別在于:RabbitMQ并不處理紙質(zhì)信件洁灵,而是接受、存儲并轉(zhuǎn)發(fā)二進制數(shù)據(jù)---消息掺出。

談到RabbitMQ的消息徽千,通常有幾個術(shù)語:

  • 生產(chǎn)者:是指發(fā)送消息的程序
  • 隊列:相當于RabbitMQ的投遞箱。盡管消息在RabbitMQ和你的應用之間傳遞汤锨,但是消息僅僅會在隊列之中存儲双抽。隊列只能存儲在內(nèi)存或磁盤中,本質(zhì)上是一個大的消息緩沖區(qū)闲礼。不同的生產(chǎn)者可以發(fā)送消息到同一個對隊列牍汹,不同的消費者也可以從同一個隊列中獲取消息铐维。
  • 消費者:等待接受消息的程序。

注意慎菲,生產(chǎn)者嫁蛇、消費者以及RabbitMQ并不一定要在同一個主機上,在絕大部分的應用中它們都不在同一主機上露该。

在開始教程之前睬棚,請確保:你已經(jīng)安裝了RabbitMQ,并且在localhost上運行起來(默認端口5672)解幼。如果你使用了不同的主機或端口抑党,請在下文中的連接設置中
更改相應的參數(shù)。


一撵摆、Hello World

在這一部分底靠,我們將會使用Java編寫兩個小程序:一個發(fā)送單個消息的生產(chǎn)者、一個接受消息并打印出消息的消費者特铝。這個消息就是Hello World暑中。

下圖中,P代表生產(chǎn)者苟呐,C代表消費者痒芝,中間紅色的小箱子就代表隊列--RabbitMQ為了讓消費者收到消息而保持的消息緩沖區(qū)。


Rabbit.png

在這一部分牵素,只需要引入Java客戶端依賴即可:amqp-client.jar严衬,也可以通過maven的方式引入:

<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>4.1.0</version>
</dependency>
1、生產(chǎn)者

我們將消息的發(fā)布者(生產(chǎn)者)命名為Send笆呆,將消息的消費者命名為Recv请琳。發(fā)布者將會連接到RabbitMQ,并且發(fā)送一條消息赠幕,然后退出俄精。
Send.java中,首先引入相關(guān)類:

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;

再定義隊列的名字:

private final static String QUEUE_NAME = "hello";

然后榕堰,創(chuàng)建一個連接到Rabbit服務器的連接:

ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();

上面的代碼中竖慧,connection是socket連接的抽象,為我們處理了通信協(xié)議版本協(xié)商以及認證等逆屡。這樣圾旨,我們就連接到了本地機器上的一個消息代理(broker)。如果想連接到其他機器上的broker魏蔗,只要修改IP即可砍的。

之后,我們又創(chuàng)建了一個通道(channel)莺治,大部分的API操作均在這里完成廓鞠。

對于Send來說帚稠,必須指明消息要發(fā)到哪個隊列:

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 + "'");

隊列的定義是冪等的,它僅僅在不存在時才會創(chuàng)建床佳。消息的內(nèi)容是一個字節(jié)數(shù)組滋早,所以你可以隨意編碼(encode)。

最后夕土,必須將通道和連接關(guān)閉馆衔。

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

完整代碼

//引入相關(guān)Class文件
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class Send {

    //定義隊列名字
    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv) throws Exception {
        //創(chuàng)建連接和通道
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        //為通道指明隊列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        String message = "Hello World!";
        
        //發(fā)布消息
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
        System.out.println(" [x] Sent '" + message + "'");

        //關(guān)閉連接
        channel.close();
        connection.close();
    }
}
2、接收者(消費者)

消費者從RabbitMQ中取出消息怨绣。不同于發(fā)布者只發(fā)送一條消息就退出角溃,這里我們讓消費者一直監(jiān)聽消息,并把接受到的消息打印出來篮撑。
與Send.java類似减细,首先引入相關(guān)類:

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;

上面引入的DefaultConsumerConsumer接口的實現(xiàn)類,我們使用它來緩沖從服務器push來的消息赢笨。
接下來的設置與發(fā)布者類似未蝌,打開連接和通道,聲明我們想消費的隊列茧妒。注意萧吠,這里的隊列的名字要與發(fā)布者中聲明的隊列的名字一致。

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, fasle, false, false, null);
    System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
    ...
    }
}

注意桐筏,消費者同樣聲明了隊列纸型。這是因為,我們可能在啟動生產(chǎn)者之前啟動了消費者應用梅忌,我們想確保在從一個隊列消費消息之前狰腌,這個隊列是存在的。

接下來牧氮,告訴服務器(RabbitMQ)把隊列中的消息發(fā)過來琼腔。因為這個過程是異步的,可以通過DefaultConsumer來進行回調(diào)踱葛。

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);

Consumer的完整代碼如下:

package com.maxwell.rabbitdemo;

import com.rabbitmq.client.*;

import java.io.IOException;

public class Recv {

    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv) throws Exception {
        //建立連接和通道
        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");

        //回調(diào)消費消息
        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);
    }
}

這樣丹莲,消費者就會一直監(jiān)聽聲明的隊列。運行一次生產(chǎn)者(即Send.java中的main方法)尸诽,消費者就會打印出接受到的消息圾笨。


說明

①與原文略有出入,如有疑問逊谋,請參考原文。
②RabbitMQ的官方rabbitmq-tutorials的java示例中土铺,amqp-client版本為3.5胶滋,我改為了4.1板鬓,否則后續(xù)的示例教程中會報錯說找不到文件。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末究恤,一起剝皮案震驚了整個濱河市俭令,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌部宿,老刑警劉巖抄腔,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異理张,居然都是意外死亡赫蛇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門雾叭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悟耘,“玉大人,你說我怎么就攤上這事织狐≡萦祝” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵移迫,是天一觀的道長旺嬉。 經(jīng)常有香客問我,道長厨埋,這世上最難降的妖魔是什么邪媳? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮揽咕,結(jié)果婚禮上悲酷,老公的妹妹穿的比我還像新娘。我一直安慰自己亲善,他們只是感情好设易,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛹头,像睡著了一般顿肺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上渣蜗,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天屠尊,我揣著相機與錄音,去河邊找鬼耕拷。 笑死讼昆,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的骚烧。 我是一名探鬼主播浸赫,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼闰围,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了既峡?” 一聲冷哼從身側(cè)響起羡榴,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎运敢,沒想到半個月后校仑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡传惠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年迄沫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涉枫。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡邢滑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愿汰,到底是詐尸還是另有隱情困后,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布衬廷,位于F島的核電站摇予,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吗跋。R本人自食惡果不足惜侧戴,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望跌宛。 院中可真熱鬧酗宋,春花似錦、人聲如沸疆拘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哎迄。三九已至回右,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間漱挚,已是汗流浹背翔烁。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留旨涝,地道東北人蹬屹。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哩治。 傳聞我的和親對象是個殘疾皇子秃踩,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)业筏,斷路器,智...
    卡卡羅2017閱讀 134,633評論 18 139
  • 來源 RabbitMQ是用Erlang實現(xiàn)的一個高并發(fā)高可靠AMQP消息隊列服務器鸟赫。支持消息的持久化蒜胖、事務、擁塞控...
    jiangmo閱讀 10,350評論 2 34
  • 關(guān)于消息隊列抛蚤,從前年開始斷斷續(xù)續(xù)看了些資料台谢,想寫很久了,但一直沒騰出空岁经,近來分別碰到幾個朋友聊這塊的技術(shù)選型朋沮,是時...
    預流閱讀 584,551評論 51 786
  • 有些過程確實很煎熬,但真的缀壤,熬過去就好了樊拓,而且,我可以塘慕!
    小兔紙的胡蘿卜閱讀 96評論 1 1
  • 有時候覺得自己就是太二了筋夏,很多自己不愿的事但又覺得無所謂╮(╯_╰)╭的,就忍忍將就將就一下就可以了图呢,可是這樣真的...
    子絔627閱讀 154評論 0 0