で春クラウドメッセージング・紹介を分散し、スタートの春クラウドストリームでは、我々は簡単に春のクラウドストリームを導入し、簡単な例を作るために春のクラウドストリームが提供するデフォルトチャンネルの入力と出力を使用していました。この記事では、我々は自己を使用します。例としてチャネルを定義し、Spring CloudStreamの高度なアプリケーションを紹介します。SpringCloudStreamがわからない場合は、SpringCloud分散メッセージ-SpringCloudStreamの概要とはじめにを読むことができます。
前回の記事では、入力チャネルと出力チャネルをそれぞれ定義するために、2つの注釈@Inputと@Outputを導入しました。SpringCloudStreamによって定義されたSInkとSourceは、これら2つの注釈を使用します。また、カスタムチャネルにもこれら2つの注釈を使用する必要があります。これら2つの注釈を使用すると、入力チャネルと出力チャネルを簡単に定義できます。たとえば、ログの入力チャネルと出力チャネルを定義します。コードは次のとおりです。
//定义日志输入通道
public interface LogSink {
String INPUT = "logInput";
@Input("logInput")
SubscribableChannel input();
}
//定义日志输出通道
public interface LogSource {
String OUTPUT = "logOutput";
@Output("logOutput")
MessageChannel output();
}
チャネルを書き込んだ後、構成ファイルでチャネルを定義し、チャネルをバインダーにバインドし、バインダーをメッセージミドルウェアにバインドする必要があります。上記のチャネル構成は次のとおりです。
spring:
cloud:
stream:
bindings: #用于绑定通道到binder
logInput: #ChannelName 这里是输入通道的名称,如果@Input不指定默认为方法名
destination: log #从哪里接收消息,这里指topic或者队列名称,在rabbit中为exchange
binder: logBinder #绑定到名为logBinder的binder
logOutput: #ChannelName 这里是输出通道的名称,如果@Output不指定默认为方法名
destination: log #将消息发送到哪里,这里指topic或者队列名称,在rabbit中为exchange
binder: logBinder #绑定到名为logBinder的binder
content-type:
binders: #配置binder
logBinder: #配置名称为hello1的binder
type: rabbit #binder类型为rabbitMq
environment: #配置运行环境
spring:
rabbitmq:
host: 10.0.10.63 #地址
port: 5672 #端口
username: guest #用户名
password: guest #密码
server:
port: 8092
次に、チャネルをバインドするために@EnableBindingアノテーションが必要です。メッセージ受信コードを以下に示します。メッセージを送信するためのコードはここには示されていません。必要なのは@EnableBinding(LogSource.class)のみで、@ Autowireアノテーションを使用してLogSourceを挿入します。
@EnableBinding(LogSink.class)
public class LogReceiver {
private static Logger logger = LoggerFactory.getLogger(LogReceiver.class);
@StreamListener(LogSink.INPUT)
public void receive(String payload) {
logger.info("Received: " + payload);
}
}
上記のコードでは、入力チャネルと出力チャネルを異なるインターフェイスで定義します。チャネルが多すぎる場合は、複数のインターフェイスを定義する必要があります。したがって、1つのインターフェイスで複数のチャネルを定義できます。@ EnableBindingも必要です。インターフェイスをバインドするだけです。次のコードでは、@ EnableBinding(LogChannel.class)のみが必要であり、メッセージを送信するときに@Autowireを使用してLogChannelインターフェイスに注釈を付けます。
public interface LogChannel {
String INPUT = "service1logInput";
@Input("service1logInput")
SubscribableChannel service1input();
String INPUT2 = "service2logInput";
@Input("service1logInput")
SubscribableChannel service2input();
String OUTPUT = "service1logOutput";
@Output("service1logOutput")
MessageChannel service1logOutput();
String OUTPUT2 = "service2logOutput";
@Output("service12ogOutput")
MessageChannel service2logOutput();
}
Spring Cloud Streamは、Enterprise Integration Patternsによって定義された概念とパターンに基づいており、Springプロジェクトポートフォリオで確立され人気のあるEnterprise IntegrationPatternsの実装であるSpringIntegrationFrameworkに依存する内部実装に依存しています。したがって、Spring Integrationの確立された基盤、セマンティクス、および構成オプションを自然にサポートします。たとえば、@ InboundChannelAdapterを使用してSourceの出力チャネルをMessageSourceにアタッチできます。同様に、Processorバインディングコントラクトのメッセージハンドラメソッドの実装を提供するときに@Transformerまたは@ServiceActivatorを使用できます。コード例は次のとおりです。
@EnableBinding(Source.class)
public class TimerSource {
@Bean
@InboundChannelAdapter(value = Source.OUTPUT, poller = @Poller(fixedDelay = "10", maxMessagesPerPoll = "1"))
public MessageSource<String> timerMessageSource() {
return () -> new GenericMessage<>("Hello Spring Cloud Stream");
}
}
@EnableBinding(Processor.class)
public class TransformProcessor {
@Transformer(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
public Object transform(String message) {
return message.toUpperCase();
}
}
@StreamListenerアノテーションに関しては、Spring CloudStreamのSpringIntegrationの補足です。他のSpringMessagingアノテーション(@JmsListener)と同様に、ルーティングなどの機能を提供できます。@StreamListenerで注釈が付けられたメソッドの場合、データの一部を返すことができますが、@ SendTo注釈を使用して、メソッドによって返されるデータの出力先を指定する必要があります。コードは次のとおりです。
@EnableBinding(Processor.class)
public class TransformProcessor {
@Autowired
VotingService votingService;
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public VoteResult handle(Vote vote) {
return votingService.record(vote);
}
}
Spring Cloud Streamは、@ SpringListenerアノテーションの条件に基づいて、複数の処理メソッドへのメッセージの転送をサポートしています。これらのメソッドは戻り値を持つことはできず、個別のメッセージ処理メソッドです。@StreamListenerの条件パラメーターに指定されたSpEL式を渡すことができます。このようにして、式に一致するプロセッサのみが呼び出されます。コード例は次のとおりです。
@EnableBinding(Sink.class)
@EnableAutoConfiguration
public static class TestPojoWithAnnotatedArguments {
@StreamListener(target = Sink.INPUT, condition = "headers['type']=='bogey'")
public void receiveBogey(@Payload BogeyPojo bogeyPojo) {
// handle the message
}
@StreamListener(target = Sink.INPUT, condition = "headers['type']=='bacall'")
public void receiveBacall(@Payload BacallPojo bacallPojo) {
// handle the message
}
}
公開/サブスクライブモデルを使用すると、共有トピックを介してアプリケーション間の対話が容易になりますが、特定のアプリケーションの複数のインスタンスを作成して拡張する機能も同様に重要です。そうすることで、アプリケーションのさまざまなインスタンスが競合する消費者関係に置かれ、1つのインスタンスのみが特定のメッセージを処理できます。Spring Cloud Streamは、コンシューマーグループの概念を提供します。spring.cloud.stream.bindings。<channelName> .groupを介してグループを構成できます。次の図のコンシューマーは、次の構成を使用します:spring.cloud.stream.bindings。<channelName> .group = hdfsWriteまたはspring.cloud.stream.bindings。<channelName> .group = average。
特定のターゲットにサブスクライブするすべてのグループは、公開されたデータのコピーを受け取りますが、各グループの1人のメンバーだけがそのターゲットから特定のメッセージを受け取ります。デフォルトでは、グループが指定されていない場合、Spring Cloud Streamは、アプリケーションを匿名の独立した単一メンバーの消費者グループに割り当てます。このグループは、他のすべての消費者グループと公開/購読関係にあります。
グループ化に加えて、
Spring Cloud Streamは、特定のアプリケーションの複数のインスタンス間のデータ分割をサポートします。パーティショニングスキームでは、物理通信媒体(プロキシトピックなど)は複数のパーティションに構造化されていると見なされます。1つ以上のプロデューサーアプリケーションインスタンスが複数のコンシューマーアプリケーションインスタンスにデータを送信し、共通の特性によって識別されるデータが同じコンシューマーインスタンスによって処理されるようにします。Spring Cloud Streamは、パーティション処理のユースケースを統一された方法で実装するための一般的な抽象化を提供します。したがって、ブローカー自体が自然なパーティション(Kafkaなど)であろうと、不自然なパーティション(RabbitMQなど)であろうと、パーティショニングを使用できます。パーティション構造と必要な構成は次のとおりです。
#下面是生产者配置
#通过该参数指定了分区键的表达式规则
spring.cloud.stream.bindings.<channel-name>.producer.partitionKeyExpression=payload
#指定了消息分区的数量。
spring.cloud.stream.bindings.<channel-name>.producer.partitionCount=2
#下面是消费者配置
#开启消费者分区功能
spring.cloud.stream.bindings.<channel-name>.consumer.partitioned=true
#指定了当前消费者的总实例数量
spring.cloud.stream.instanceCount=2
#设置当前实例的索引号,从 0 开始
spring.cloud.stream.instanceIndex=1
この記事では、Spring Cloud Streamがチャネル名、Spring Cloud Streamのグループ化、パーティショニング、ルーティング、およびその他の高度なアプリケーションをカスタマイズする方法を紹介します。次の記事では、Spring CloudStreamの例外処理といくつかの高度な構成に関する知識を紹介します。