マイクロサービストピック15-SpringCloudStreamの実装

序文

前の章では、Spring CloudBusについて説明しました

このセクションでは、マイクロサービストピックの内容、合計16のセクションを引き続き共有します。

このセクションの要点は次のとおりです。

  • RocketMQにSpringCloudStreamを実装する

Spring CloudStreamおよびBinderアーキテクチャ

ここに画像の説明を挿入

Spring Cloud StreamBinderの既存の実装を参照してください

ここでは、Spring CloudStreamのドキュメントを参照します。

バインダーの実装手順

一般的なバインダーの実装は、次のもので構成されます。

  • Binderインターフェイスを実装するクラス;インターフェイスを
    実装Binderする

  • 春Aの@ConfigurationAを作成BeanタイプのクラスBinderミドルウェアザ・コネクションインフラストラクチャと共に。
    Binder実装クラス上の注釈@Configurationの注釈

  • META-INF/spring.binders次の例に示すように、定義1つ以上のバインダーを含むCLASSPATHで見つかっファイル:
    META-INF/spring.binders構成Binder名とBinder自動アセンブリClassMap

  kafka:\
  org.springframework.cloud.stream.binder.kafka.config.KafkaBinderConfiguration

考えてみてください。複数のバインダー実装jarが同時に存在すると仮定すると、どれを使用する必要がありますか?

  • デフォルトのバインダー名を構成します
spring.cloud.stream.defaultBinder = rabbit
  • バインダーの実装を指定する
spring.cloud.stream.bindings.input.binder=kafka
spring.cloud.stream.bindings.output.binder=rabbit

常春クラウドストリームバインダーRabbitMQ

Spring Cloud Stream Binder RabbitMQ

支配的な春のクラウドストリームバインダーカフカ

Spring Cloud Stream Binder Kafka

Spring Cloud Stream BinderRocketMQを実装する

Spring Cloud Stream BinderRabbitMQとSpringCloud Stream Binder Kafkaの実装プロセスを模倣し、Spring Cloud Stream BinderRocketMQの実装を開始しました。3つのステップがあります。

  • RocketMQ->メッセージの送受信

  • bindProducerでメッセージを送信する

  • bindConsumerはメッセージを受信します

準備作業


  1. バージョン4.7.1を使用してRocketMQダウンロードします。インストールプロセスは省略されます。

  2. ネームサーバーを起動します
    つまり、mqname

  3. MQエージェントを起動します
    ここに画像の説明を挿入

  4. mqコンソールを起動します(オプション、主にデモンストレーション目的)

ここに画像の説明を挿入

実装手順

  • spring-cloud-stream-binder-rocketmqプロジェクトを作成する
<groupId>com.test</groupId>
<artifactId>spring-cloud-stream-binder-rocketmq</artifactId>
<version>0.0.1-SNAPSHOT</version>
  • Spring Cloud StreamBinderの依存関係を増やす
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-stream</artifactId>
</dependency>
  • RocketMQクライアントの依存関係を増やす
<dependency>
	<groupId>org.apache.rocketmq</groupId>
	<artifactId>rocketmq-client</artifactId>
	<version>4.3.0</version>
</dependency>
  • プロデューサーデモを書く
public class RocketMQProducerDemo {
    
    

    public static void main(String[] args) throws Exception {
    
    
        //Instantiate with a producer group name.
        DefaultMQProducer producer = new
                DefaultMQProducer("test-group");
        //这里配置自己的mq地址即可
        producer.setNamesrvAddr("127.0.0.1:9876");
        //Launch the instance.
        producer.start();
        //CountDownLatch countDownLatch = new CountDownLatch(100);
        //countDownLatch.await(10, TimeUnit.SECONDS);
        for (int i = 0; i < 100; i++) {
    
    
            //Create a message instance, specifying topic, tag and message body.
            Message msg = new Message("TopicTest-1" /* Topic */,
                    "TagA" /* Tag */,
                    ("Hello RocketMQ " +
                            i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
            );
            //Call send message to deliver message to one of brokers.
            SendResult sendResult = producer.send(msg);
            System.out.printf("%s%n", sendResult);
        }
        //Shut down once the producer instance is not longer in use.
        producer.shutdown();
    }
}

  • mqを起動した後、結果を確認し、main関数を実行します

ここに画像の説明を挿入
100回ループすると、ここは明らかに成功します。

  • 消費者デモを書く
    public static void main(String[] args) throws Exception {
    
    
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("test-group");
        consumer.setNamesrvAddr("192.168.200.111:9876");
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);

//        //set to broadcast mode
//        consumer.setMessageModel(MessageModel.BROADCASTING);

        consumer.subscribe("TopicTest-1", "TagA");

        consumer.registerMessageListener(new MessageListenerConcurrently() {
    
    

            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                                                            ConsumeConcurrentlyContext context) {
    
    
                System.out.printf(Thread.currentThread().getName() + " Receive New Messages: " + msgs + "%n");
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

        consumer.start();
        System.out.printf("Broadcast Consumer Started.%n");
    }
}

  • mqを起動した後、結果を確認し、main関数を実行します

ここに画像の説明を挿入
100回リサイクルすれば消費成功!

RocketMQスターター用のSpringCloud Stream Binder

ここで、spring-cloud-stream-binder-rocketmqrocketmqとSpringCloudをバインドするために特別に使用されるサービスである汎用jarパッケージを作成します。

まず、RocketMQのメッセージを実装します。

public class RocketMQMessageChannelBinder implements
        Binder<MessageChannel, ConsumerProperties, ProducerProperties> {
    
    

    private static final String GROUP = "test-group";

    private static final String TOPIC = "TEST_TOPIC";

    private static final String TAG = "TEST_TAG";

    private static final String NAME_ADDRESS = "192.168.200.111:9876";

    @Override
    public Binding<MessageChannel> bindConsumer(String name, String group,
                                                MessageChannel inputChannel, ConsumerProperties consumerProperties) {
    
    

        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(GROUP);
        consumer.setNamesrvAddr(NAME_ADDRESS);
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);

        try {
    
    
            consumer.subscribe(TOPIC, TAG);

            consumer.registerMessageListener(new MessageListenerConcurrently() {
    
    

                @Override
                public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                                                                ConsumeConcurrentlyContext context) {
    
    
                    System.out.printf(Thread.currentThread().getName() + " Receive New Messages: " + msgs + "%n");

                    msgs.forEach(msg -> {
    
    
                        byte[] body = msg.getBody();
                        // 发送消息到 消息管道
                        inputChannel.send(new GenericMessage<Object>(body));
                    });

                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                }
            });

            consumer.start();

        } catch (Exception e) {
    
    
            e.getMessage();
        }

        return () -> {
    
    
            System.out.println("consumer shutdown...");
            consumer.shutdown();
        };
    }

    /**
     * 发送消息
     *
     * @param name
     * @param outputChannel
     * @param producerProperties
     * @return
     */
    @Override
    public Binding<MessageChannel> bindProducer(String name, MessageChannel outputChannel, ProducerProperties producerProperties) {
    
    

        //Instantiate with a producer group name.
        DefaultMQProducer producer = new DefaultMQProducer(GROUP);

        producer.setNamesrvAddr(NAME_ADDRESS);
        //Launch the instance.
        try {
    
    
            producer.start();


            SubscribableChannel subscribableChannel = (SubscribableChannel) outputChannel;
            // 消息订阅回调
            subscribableChannel.subscribe(message -> {
    
    
                // 消息主题
                Object messageBody = message.getPayload();
                Message mqMessage = new Message();
                mqMessage.setTopic(TOPIC);
                mqMessage.setTags(TAG);
                try {
    
    
                    mqMessage.setBody(serialize(messageBody));
                    SendResult sendResult = producer.send(mqMessage);
                    System.out.printf("消息发送 : %s%n", sendResult);
                } catch (Exception e) {
    
    
                    e.getMessage();
                }
            });

        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

        return () -> {
    
    
            System.out.println("producer shutdown...");
            producer.shutdown();
        };
    }

    private byte[] serialize(Object serializable) throws IOException {
    
    

        if (serializable instanceof byte[]) {
    
    
            return (byte[]) serializable;
        }

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
        // 通过 Java 序列化 将 Object 写入字节流
        objectOutputStream.writeObject(serializable);
        // 返回字节数组
        return outputStream.toByteArray();
    }
}

RocketMQMessageChannelBinderConfiguration配置:

@Configuration
public class RocketMQMessageChannelBinderConfiguration {
    
    

    @Bean
    public RocketMQMessageChannelBinder rocketMQMessageChannelBinder() {
    
    
        return new RocketMQMessageChannelBinder();
    }

}

自動アセンブリクラスマッピングを実現するための構成ファイルを追加します。

rocketmq=\
com.test.micro.services.spring.cloud.stream.binder.rocketmq.RocketMQMessageChannelBinderConfiguration

現在作成しているjarパッケージは、暫定的に完成しています。これは、spring-cloud-stream-binder-rocketmq(V1.0バージョン)と呼ぶことができます。次にどのようにテストしますか?

前の章では、spring-cloud-client-applicationとspring-cloud-server-applicationの2つのサービスについて何度も言及しましたが、ここでは、これら2つのモジュールを使用してspring-cloud-stream-binder-rocketmq(V1 .0)を統合します。バージョン):

  1. クライアント設定オープンAPI
    @GetMapping("/stream/send/rocketmq")
    public boolean streamSendToRocketMQ(@RequestParam String message) {
    
    
        // 获取 MessageChannel
        MessageChannel messageChannel = simpleMessageService.testChannel();
        return messageChannel.send(new GenericMessage(message));
    }

サービスの実装:

public interface SimpleMessageService {
    
    

    @Output("test007")
    MessageChannel testChannel(); //  destination = test007

  
}

  1. クライアントとサーバーの設定構成ファイル

spring.cloud.stream.defaultBinder = rabbit

## Spring Cloud Stream Binder - RocketMQ
### Channel  名字是 test007
spring.cloud.stream.bindings.test007.binder = rocketmq
spring.cloud.stream.bindings.test007.destination = test007
  1. クライアントpomは、spring-cloud-stream-binder-rocketmqのjarパッケージを導入します。
    <!--  RocketMQ -->
        <dependency>
            <groupId>com.test</groupId>
            <artifactId>spring-cloud-stream-binder-rocketmq</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
  1. 実装結果を確認する

最初にzkとspring-cloud-client-application、spring-cloud-server-applicationを起動します

ここに画像の説明を挿入

次に、アドレスにアクセスします:http:// localhost:8888 / stream / send / rocketmq?message = test
ここに画像の説明を挿入

メッセージは正常に送信されました。
同時に、メッセージを受信するサーバーの状況は次のとおりです。
ここに画像の説明を挿入
メッセージは正常に受信されました。

追記

このセクションのコードアドレス:RocketmqのSpring Cloud Stream Binder

アーキテクチャに関する知識の詳細については、Javaに関するこのシリーズの記事に注意してくださいJavaアーキテクトの成長への道

おすすめ

転載: blog.csdn.net/qq_34361283/article/details/108089247