RabbitMQの基本的な使用にはこれで十分です

1.簡単な紹介

MQフルネーム(メッセージキュー)は、メッセージキューとも呼ばれ、非同期通信のミドルウェアです。郵便局と理解できます。送信者が郵便局にメッセージを配信すると、郵便局が特定のメッセージ受信者(消費者)にメッセージを送信するのを手伝ってくれます。特定の送信プロセスを気にする必要はありません。と時間、そしてそれは私の他のものに干渉しません。共通MQそこにkafkaactivemqzeromqrabbitmqというように。
RabbitMQこれは、AMQP高い同時実行性を指​​向するerlanng言語によって開発され高い信頼性要件を持つリアルタイムメッセージングで使用され、多言語クライアントをサポートするプロトコルです

基本コンセプト

  • Broker:簡単に言えば、それはメッセージキューサーバーエンティティです
  • Exchange:メッセージ交換。メッセージのルーティング先のルールとキューを指定します。
  • Queue:メッセージキューキャリア、各メッセージは1つ以上のキューに入れられます
  • Binding:バインディング、その役割は、ルーティングルールに従ってそれらexchangequeueバインドすることです
  • Routing Keyexchangeメッセージ配信用のこのキーワードに応じたルーティングキーワード
  • vhost:仮想ホスト、broker複数を1つに設定できvhost、異なるユーザーの権限を分離するために使用されます
  • producer:メッセージプロデューサーはメッセージを配信するプログラムです
  • consumer:メッセージコンシューマーは、メッセージを受信するプログラムです。
  • channel:メッセージチャネル、クライアントの各接続で、複数を確立できchannel、それぞれchannelがセッションタスクを表します

一般的な参照シナリオ

  • 電子メールの送信:ユーザーが登録すると、メッセージがユーザーrabbitmq配信され、メッセージのコンシューマーが電子メールを非同期に送信します。これにより、システムの応答速度が向上します。
  • トラフィックのピークカット:一般に、スパイクアクティビティで広く使用されています。スパイクにより、過剰なトラフィックが原因でアプリケーションがハングします。この問題を解決するために、通常、メッセージキューがアプリケーションのフロントエンドに追加されます。これはアクティビティの数を制御するために使用され、この特定のしきい値を超える注文は直接破棄されます。短期間の高流量破砕用途を緩和します。
  • 注文タイムアウト:rabbitmq遅延キューを使用すると、注文タイムアウト機能を簡単に実現できます。たとえば、ユーザーは注文後30分を支払うことなく注文をキャンセルできます。

2.RabbitMQ環境を準備します

RabbitMQインストール問題ため、ここでのテストでは、Docker環境を例として取り上げます。最初Linuxにdockerをインストールします。インストールしない場合は、docker install / dockerの一般的なコマンドを参照してください。

次に、ダウンロードして起動しますRabbitMQ

docker run -d --hostname my-rabbit --name pikachues-rabbit -p 5672:5672 -p15672:15672 rabbitmq:3-management

3.テスト

RabbitMQ4つのメッセージ交換があります。それらは、直接(デフォルト)、ファンアウト、トピック、およびヘッダーです。スイッチのタイプが異なれば、メッセージ転送戦略も異なります。次のspringboot4種類のメッセージ交換テストされます。

0.テスト環境を準備します

頼る
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
構成ファイル
spring.rabbitmq.host=rabbitmq安装的ip地址
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.port=5672

1.直接

ユニキャストと同様に機能する直接交換は、と完全Exchangeに一致ROUTING_KEYするキューにメッセージを送信します

直接構成
@Configuration
public class RabbitDirectConfig {
    public final static String DIRECTNAME = "pikachues-direct";
    @Bean
    Queue queue() {
        return new Queue("hello.pikachues");
    }
    @Bean
    DirectExchange directExchange(){
        return new DirectExchange(DIRECTNAME,true,false);
    }

    @Bean
    Binding binding(){
        return BindingBuilder.bind(queue()).to(directExchange()).with("direct");
    }
}
メッセージ受信
@Component
public class DirectReceiver {
    @RabbitListener(queues = "hello.pikachues")
    public void handler1(String msg){
        System.out.println(">>>handler"+msg);
    }
}
テスト
@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitmqDemoApplicationTests {

	@Autowired
	RabbitTemplate rabbitTemplate;

	@Test
	public void direct() {
		rabbitTemplate.convertAndSend("hello.pikachues","hello pikachues");
	}
}

2.ファンアウト

ブロードキャストはスイッチの一種でROUTING_KEYあり、メッセージの設定に関係なく、Exchangeバインドされているすべてのメッセージにメッセージを転送しますQueue

ファンアウト構成
@Configuration
public class RabbitFanoutConfig {
    public static final String FANOUTNAME = "pikachues-fanout";

    @Bean
    Queue queueOne(){
        return new Queue("queue-one");
    }

    @Bean
    Queue queueTwo(){
        return new Queue("queue-two");
    }

    @Bean
    FanoutExchange fanoutExchange(){
        return new FanoutExchange(FANOUTNAME,true,false);
    }

    @Bean
    Binding bindingOne(){
        return BindingBuilder.bind(queueOne()).to(fanoutExchange());
    }
    @Bean
    Binding bindingTwo(){
        return BindingBuilder.bind(queueTwo()).to(fanoutExchange());
    }
}
メッセージ受信
@Component
public class FanoutReceiver {

    @RabbitListener(queues = "queue-one")
    public void handler1(String msg){
        System.out.println("FanoutReceiver:handler1"+msg);
    }

    @RabbitListener(queues = "queue-two")
    public void handler2(String msg){
        System.out.println("FanoutReceiver:handler2"+msg);
    }
}
テスト
@Test
	public void testFanout(){
		rabbitTemplate.convertAndSend(RabbitFanoutConfig.FANOUTNAME,null,"hello Fanout");
	}

3.トピック

テーマ交換器は、マルチキャストのように動作し、Exchange転送したメッセージとROUTING_KEY同じパターンがこのようなすべてのキュー、一致するROUTING_KEYように*。*、結合様式に合わせて、転送* .stock、user.stockをと#.user .stock。#キュー。(*表は任意のフレーズに一致するものです。#は0個以上のフレーズに一致することを意味します)user.stockMessage

トピック構成
@Configuration
public class RabbitTopicConfig {

    public static final String TOPICNAME = "pikachues-topic";

    @Bean
    TopicExchange topicExchange(){
        return new TopicExchange(TOPICNAME,true,false);
    }

    @Bean
    Queue xiaomi(){
        return new Queue("xiaomi");
    }

    @Bean
    Queue huaiwei(){
        return new Queue("huawei");
    }

    @Bean
    Queue phone(){
        return new Queue("phone");
    }

    @Bean
    Binding xiaomiBinding(){
        return BindingBuilder.bind(xiaomi()).to(topicExchange()).with("xiaomi.#");
    }

    @Bean
    Binding huaiweiBinding(){
        return BindingBuilder.bind(huaiwei()).to(topicExchange()).with("huawei.#");
    }
    @Bean
    Binding phoneBinding(){
        return BindingBuilder.bind(phone()).to(topicExchange()).with("#.phone.#");
    }

}
メッセージ受信
@Component
public class TopicReceiver {
    @RabbitListener(queues = "xiaomi")
    public void handler1(String msg) {
        System.out.println("TopicReceiver:handler1:" + msg);
    }

    @RabbitListener(queues = "huawei")
    public void handler2(String msg) {
        System.out.println("TopicReceiver:handler2:" + msg);
    }

    @RabbitListener(queues = "phone")
    public void handler3(String msg) {
        System.out.println("TopicReceiver:handler3:" + msg);
    }
}
テスト
@Test
	public void testTopic(){
		rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPICNAME,"xiaomi.news","小米新闻");
		rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPICNAME,"vivo.phone","小米手机");
		rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPICNAME,"huawei.phone","华为手机");
	}

4.ヘッダー

メッセージ本文のヘッダーが一致します(無視)

ヘッダー構成
@Configuration
public class RabbitHeaderConfig {

    public static final String HEADERNAME = "pikachues-header";

    @Bean
    HeadersExchange headersExchange(){
        return new HeadersExchange(HEADERNAME, true,false);
    }

    @Bean
    Queue queueName(){
        return new Queue("name-queue");
    }
    @Bean
    Queue queueAge(){
        return new Queue("age-queue");
    }
    @Bean
    Binding bindingName(){
        Map<String,Object> map = new HashMap<>();
        map.put("name","pikachues");
        return BindingBuilder.bind(queueName()).to(headersExchange()).whereAny(map).match();
    }

    @Bean
    Binding bindingAge(){
        return BindingBuilder.bind(queueAge()).to(headersExchange()).where("age").exists();
    }
}
メッセージ受信
@Component
public class HeaderReceiver {

    @RabbitListener(queues = "name-queue")
    public void handler1(byte[] msg) {
        System.out.println("HeaderReceiver:handler1:" + new String(msg, 0, msg.length));
    }

    @RabbitListener(queues = "age-queue")
    public void handler2(byte[] msg) {
        System.out.println("HeaderReceiver:handler2:" + new String(msg, 0, msg.length));
    }
}
テスト
@Test
	public void testHeaders(){
		Message nameMsg = MessageBuilder.withBody("hello pikachues".getBytes()).setHeader("name","pikachues").build();
		Message ageMsg = MessageBuilder.withBody("hello 99".getBytes()).setHeader("age","99").build();
		rabbitTemplate.convertAndSend(RabbitHeaderConfig.HEADERNAME,null,nameMsg);
		rabbitTemplate.convertAndSend(RabbitHeaderConfig.HEADERNAME,null,ageMsg);
	}

4.その他

RabbitMQ基本原則を理解たい場合はこの記事またはspringboot公式ウェブサイトの紹介をお読みください

おすすめ

転載: blog.csdn.net/qq_41262903/article/details/106131293
おすすめ