Spring Cloud Stream - Binders, Bindings and Binding names
Binders
https://cloud.spring.io/spring-cloud-stream/multi/multi_spring-cloud-stream-overview-binders.html
Spring Cloud Stream provides a Binder abstraction for use in connecting to physical destinations at the external middleware.
In other words, Spring auto configuration uses the binders that it finds on the classpath to determine what type of external middleware options the application wants to connect to.
In Spring Cloud Stream nomenclature the implementation responsible for integration with the specific message broker is called binder
. By default, Spring Cloud Stream provides binder implementations for Kafka
and RabbitMQ
. It is able to automatically detect and use a binder found on the classpath. Any middleware-specific settings can be overridden through external configuration properties in the form supported by Spring Boot, such as application arguments, environment variables, or just the application.yml file. To include support for RabbitMQ
you should add the following dependency to the project.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
Configuring Binder and Binding specific properties
Binder specific properties in application.yaml
Because the binders are specific to the products that we are using for messaging (kafka and rabbitMQ), the properties that each of these binders need may be different. If the spring-cloud-stream framework starts supporting additional messaging products in the future, each of those may need their own configuration. To support this, spring lets us specify binder specific properties in application.yaml
- Kafka Binder Properties: https://cloud.spring.io/spring-cloud-stream-binder-kafka/spring-cloud-stream-binder-kafka.html
- Kafka Consumer Properties: https://cloud.spring.io/spring-cloud-stream-binder-kafka/spring-cloud-stream-binder-kafka.html#kafka-consumer-properties
- Kafka Producer Properties: https://cloud.spring.io/spring-cloud-stream-binder-kafka/spring-cloud-stream-binder-kafka.html#kafka-producer-properties
- Usage examples: https://cloud.spring.io/spring-cloud-stream-binder-kafka/spring-cloud-stream-binder-kafka.html#_usage_examples
-
Content-type
Spring Cloud Stream allows you to declaratively configure type conversion for inputs and outputs using the
spring.cloud.stream.bindngs.<channelName>.content-type
property of a binding.e.g.
spring.cloud.stream.bindings.output.contentType: application/json
Example yaml file
The following example shows a typical configuration for a processor application that connects to two RabbitMQ broker instances:
spring:
cloud:
stream:
bindings:
input:
destination: thing1
binder: rabbit1
output:
destination: thing2
binder: rabbit2
binders:
rabbit1:
type: rabbit
environment:
spring:
rabbitmq:
host: <host1>
rabbit2:
type: rabbit
environment:
spring:
rabbitmq:
host: <host2>
Using Beans in the application
The other option (instead of using application.yaml) is using classes from the package org.springframework.cloud.stream.binder.reactorkafka
e.g. ReceiverOptionsCustomizer
and SenderOptionsCustomizer
We get more control over the customization if we use ReceiverOptionsCustomizer
. Because, we can change the binder properties based on the function name. With binder properties in application.yaml, we do not have fine-grained control. The properties we specify in application.yaml are generic and they apply to all the bindings (for that messaging platform) in the application.
Destination Binders
Bindings
Bindings provide a bridge between the external messaging system (e.g., queue, topic etc.) and application-provided Producers and Consumers.
Binding is an abstraction that represents a bridge between sources and targets exposed by the binder and user code.
The binders will create these bindings based on the configuration provided in classpath, application.yml, any other property files, etc.
The binders know what to do with the messages that the applications are trying to Produce/Consume - like
- how to encode/decode the messages
Binding and Binding names
- https://docs.spring.io/spring-cloud-stream/docs/current/reference/html/spring-cloud-stream.html#_binding_and_binding_names
- https://docs.spring.io/spring-cloud-stream/docs/current/reference/html/spring-cloud-stream.html#_functional_binding_names
The naming follows this pattern. The naming convention used to name input and output bindings is as follows:
For input, the name will be <functionName> + -in- + <index>
For output, the name will be <functionName> + -out- + <index>
For example, if we have a function, a supplier and a consumer with these names:
public Supplier<OrderEvent> orderEventProducer() {
return () -> ...;
}
public Consumer<Payment> paymentEventConsumer() {
return e -> ...;
}
public Function<String, String> uppercase() {
return value -> value.toUpperCase();
}
public Consumer<Tuple2<String, Integer>> myConsumer() {
return t -> ...;
}
the names of the bindings will be
uppercase-in-0
uppercase-out-0
orderEventProducer-out-0
paymentEventConsumer-in-0
myConsumer-in-0 (string topic name)
myConsumer-in-1 (int topic name)
So, in the property files, this is what we have to specify
spring.cloud.stream.bindings.uppercase-in-0.destination=my-topic
spring.cloud.stream.bindings.uppercase-out-0.destination=my-topic
Functional binding names
Apache Kafka-binder documentation
There are many configuration options that you can choose to extend/override to achieve the desired runtime behavior when using Apache Kafka as the message broker. The Apache Kafka-specific binder configuration properties are listed in Apache Kafka-binder documentation