Rabbitmq概念及HelloWorld

相關(guān)概念:

  • Producer:消息產(chǎn)生者

  • Consumer: 消息消費(fèi)者

  • Broker:消息中間件的服務(wù)節(jié)點(diǎn),對(duì)于Rabbitmq來(lái)說(shuō)刁赦,一個(gè)Rabbitmq broker可以認(rèn)為是一個(gè)Rabbitmq的服務(wù)實(shí)例。

  • Connection眉枕,與Broker的tcp長(zhǎng)連接忱嘹,Producer和Consumer都需要建立連接之后才可以使用

  • Channel衣迷,建立在Connection基礎(chǔ)上,每個(gè)線程分配一個(gè)channel邮破,類似于NIO的多路復(fù)用诈豌,節(jié)省連接資源仆救。大部分RabbitMQ的操作和核心概念都是基于Channel的,需要特別注意矫渔。

  • Queue:隊(duì)列派桩,RabbitMQ中用于存儲(chǔ)消息的容器。而且RabbitMQ中的消息只能存儲(chǔ)在Queue中蚌斩,這點(diǎn)跟kafka不同铆惑,kafka只能將消息放在topic中,而kafka中的queue只是topic實(shí)際存儲(chǔ)文件中的位移標(biāo)識(shí)送膳。

    多個(gè)consumer可以消費(fèi)同一個(gè)queue中的消息员魏,這時(shí)候消息的處理是互斥的,即一個(gè)消息只能被一個(gè)consumer處理叠聋。

  • Exchange:還是不翻譯成中文了撕阎,太怪。在producer將消息發(fā)到Broker中時(shí)碌补,是通過(guò)exchange按照一定規(guī)則轉(zhuǎn)發(fā)到不同的queue中虏束,而不是直接放入queue中。

  • RoutingKey:producer在發(fā)送消息給exchange時(shí)厦章,一般會(huì)指定一個(gè)RoutingKey镇匀,用來(lái)指定這個(gè)消息的路由規(guī)則。

  • BindingKey:RoutingKey和BindingKey匹配時(shí)(注意不是相同袜啃,可能是模糊匹配)汗侵,exchange才會(huì)把消息發(fā)送到對(duì)應(yīng)的queue中

Snip20180606_6.png
exchange類型
  • fanout,會(huì)把消息路由到所有綁定的queue中群发,無(wú)視RoutingKey和BindingKey
  • direct晰韵,只能將消息路由到RoutingKey和BindingKey完全匹配的queue,queue可以有多個(gè)熟妓,只要匹配就行
  • topic雪猪,可以支持# * 等通配符匹配RoutingKey和BindingKey
  • headers,不常用起愈,不會(huì)依賴RoutingKey只恨,而是根據(jù)消息內(nèi)容中的headers屬性跟exchange綁定的內(nèi)容進(jìn)行匹配,性能較低告材,不過(guò)非常靈活坤次。

一些關(guān)鍵點(diǎn)

大部分情況下,按照最簡(jiǎn)單的方式使用就好了斥赋,作為工具書去查詢《RabbitMQ實(shí)戰(zhàn)詳解》里面的配置缰猴。

  • channel.basicQos是設(shè)置一個(gè)channel中consumer所能保持的最大未確認(rèn)消息,也就是說(shuō)疤剑,如果一個(gè)channel中的qos值已經(jīng)到了最大滑绒,那么rabbitmq就不會(huì)繼續(xù)往這個(gè)channel中push對(duì)應(yīng)的消息闷堡。
  • rabbitmq的順序一致性其實(shí)是無(wú)法保證的,
    • 比如事務(wù)消息或者發(fā)送消息確認(rèn)疑故,當(dāng)發(fā)送失敗需要重試時(shí)杠览,這一條(批)數(shù)據(jù)跟其之后的數(shù)據(jù)在producer端就不一致了
    • 如果producer發(fā)送的時(shí)候設(shè)置了不同的超時(shí)時(shí)間,并且也設(shè)置了死信隊(duì)列纵势,那么消費(fèi)者在處理死信隊(duì)列的時(shí)候踱阿,也會(huì)出現(xiàn)數(shù)據(jù)順序與發(fā)送順序不同的情況。
    • 設(shè)置優(yōu)先級(jí)钦铁,也會(huì)導(dǎo)致順序一致性收到影響软舌。
  • 死信隊(duì)列、延遲隊(duì)列牛曹、消費(fèi)優(yōu)先級(jí)佛点、持久化等,查詢工具書即可黎比。

web端管理

  • 使用rabbitmq-plugins enable rabbitmq_management 來(lái)啟用web管理插件超营,重啟才會(huì)生效.
  • 使用rabbitmq-plugins list來(lái)查看正在使用的插件。
  • 訪問(wèn) server_ip:15672可以訪問(wèn)阅虫,guest用戶無(wú)法登陸遠(yuǎn)程服務(wù)器演闭,需要使用上面創(chuàng)建的root:root123 用戶/密碼來(lái)登陸
HelloWorld

加入maven依賴:

        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.2.0</version>
        </dependency>
producer代碼:
package rabbitmq.server;


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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class RabbitMQProducer {

    private static final String exchange_name = "exchange_siyu";

    private static final String routing_key = "routing_key_siyu";

    private static final String queue_name = "queue_siyu";

    private static final String rabbitmq_server_ip_addr = "10.199.189.30";

    private static final int rabbitmq_server_port = 5672;

    public static void main(String[] args) throws IOException, TimeoutException {

        // 連接工廠類
        ConnectionFactory connectionFactory = new ConnectionFactory();

        // 設(shè)置連接屬性及用戶名密碼,用戶书妻、密碼要通過(guò)rabbitmqctl設(shè)置過(guò)權(quán)限
        connectionFactory.setHost(rabbitmq_server_ip_addr);
        connectionFactory.setPort(rabbitmq_server_port);
        connectionFactory.setUsername("root");
        connectionFactory.setPassword("root123"); // 如果用戶名密碼不匹配船响,會(huì)連接失敗

        // 建立連接,一個(gè)tcp長(zhǎng)連接
        Connection connection = connectionFactory.newConnection();

        // 創(chuàng)建信道躲履,主要操作通過(guò)channel執(zhí)行,可以認(rèn)為channel是虛擬化出來(lái)的一個(gè)Connection聊闯,用于復(fù)用
        Channel channel = connection.createChannel();

        // 定義路由工猜,direct是point-2-piont的,直接到對(duì)應(yīng)的單個(gè)queue中
        channel.exchangeDeclare(exchange_name,"direct",true,false,null);

        // 定義queue
        channel.queueDeclare(queue_name,true,false,false,null);

        // 通過(guò)routingkey 綁定queue和exchange
        channel.queueBind(queue_name,exchange_name,routing_key);



        // 開(kāi)始發(fā)送消息
        String message = "Hello World!!";

        /* MessageProperties中預(yù)置了一部分消息的參數(shù)菱蔬,比如PERSIST_TEXT_PLAIN篷帅,其中的定義如下:
        *
        *
        public static final BasicProperties PERSISTENT_TEXT_PLAIN =
        new BasicProperties("text/plain",
                            null,
                            null,
                            2,
                            0, null, null, null,
                            null, null, null, null,
                            null, null);
        * */
        channel.basicPublish(exchange_name,routing_key, MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes());

        // 關(guān)閉channel和connection
        channel.close();
        connection.close();

    }

}

Consumer
package rabbitmq.client;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class RabbitMQConsumer {

    private static final String queue_name = "queue_siyu";
    private static final String rabbitmq_server_ip_address = "10.199.189.30";
    private static final int port = 5672;


    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {

        Address[] addresses = new Address[]{
                new Address(rabbitmq_server_ip_address,port)
        };

        // 長(zhǎng)連接工廠
        ConnectionFactory connectionFactory = new ConnectionFactory();

        connectionFactory.setUsername("root");
        connectionFactory.setPassword("root123");

        // 這里創(chuàng)建連接跟server端不同,傳入了address
        Connection connection = connectionFactory.newConnection(addresses);

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

        channel.basicQos(64);// 拴泌?魏身? 設(shè)置客戶端最多接收未被ack的消息個(gè)數(shù)

        // 創(chuàng)建消費(fèi)
        final Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("receive msg:" + new String(body));

                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                channel.basicAck(envelope.getDeliveryTag(),false); // 發(fā)送ack之后,消息會(huì)在queue中被刪除
            }
        };

        channel.basicConsume(queue_name,consumer);

        TimeUnit.SECONDS.sleep(5);

        // 如果先關(guān)閉connection蚪腐,再關(guān)閉channel箭昵,就會(huì)拋出異常:
        // com.rabbitmq.client.AlreadyClosedException: connection is already closed due to clean connection shutdown;
        // 所以這里一定要注意關(guān)閉的順序
        channel.close();
        connection.close();

    }

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市回季,隨后出現(xiàn)的幾起案子家制,更是在濱河造成了極大的恐慌正林,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颤殴,死亡現(xiàn)場(chǎng)離奇詭異觅廓,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)涵但,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門杈绸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人矮瘟,你說(shuō)我怎么就攤上這事瞳脓。” “怎么了芥永?”我有些...
    開(kāi)封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵篡殷,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我埋涧,道長(zhǎng)板辽,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任棘催,我火速辦了婚禮劲弦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘醇坝。我一直安慰自己邑跪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布呼猪。 她就那樣靜靜地躺著画畅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪宋距。 梳的紋絲不亂的頭發(fā)上轴踱,一...
    開(kāi)封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音谚赎,去河邊找鬼淫僻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛壶唤,可吹牛的內(nèi)容都是我干的雳灵。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼闸盔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼悯辙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤笑撞,失蹤者是張志新(化名)和其女友劉穎岛啸,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體茴肥,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坚踩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瓤狐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞬铸。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖础锐,靈堂內(nèi)的尸體忽然破棺而出嗓节,到底是詐尸還是另有隱情,我是刑警寧澤皆警,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布拦宣,位于F島的核電站,受9級(jí)特大地震影響信姓,放射性物質(zhì)發(fā)生泄漏鸵隧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一意推、第九天 我趴在偏房一處隱蔽的房頂上張望豆瘫。 院中可真熱鬧,春花似錦菊值、人聲如沸外驱。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)昵宇。三九已至,卻和暖如春儿子,著一層夾襖步出監(jiān)牢的瞬間趟薄,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工典徊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恩够。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓卒落,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蜂桶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子儡毕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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