Debezium 支持
Debezium Engine ,变更数据捕获 (CDC) 入站通道适配器。DebeziumMessageProducer 允许捕获数据库变更事件,将它们转换为消息,并在之后流式传输到出站通道。
你需要将 spring integration Debezium 依赖添加到你的项目中:
- Maven
- Gradle
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-debezium</artifactId>
    <version>6.4.2</version>
</dependency>
compile "org.springframework.integration:spring-integration-debezium:6.4.2"
您还需要为输入数据库包含一个 debezium connector 依赖项。例如,要使用 Debezium 与 PostgreSQL,您将需要 postgres debezium 连接器:
- Maven
- Gradle
<dependency>
    <groupId>io.debezium</groupId>
    <artifactId>debezium-connector-postgres</artifactId>
    <version>${debezium-version}</version>
</dependency>
compile "io.debezium:debezium-connector-postgres:{debezium-version}"
将 debezium-version 替换为与所使用的 spring-integration-debezium 版本兼容的版本。
入站 Debezium 通道适配器
Debezium 适配器期望有一个预配置的 DebeziumEngine.Builder<ChangeEvent<byte[], byte[]>> 实例。
debezium-supplier 提供了一个开箱即用的 DebeziumEngine.Builder Spring Boot 自动配置,并且有一个方便的 DebeziumProperties 配置抽象。
Debezium Java DSL 可以从提供的 DebeziumEngine.Builder 创建一个 DebeziumMessageProducer 实例,也可以从普通的 Debezium 配置(例如 java.util.Properties)创建。后者对于一些常见的用例和约定的配置及序列化格式非常有用。
此外,DebeziumMessageProducer 可以使用以下配置属性进行调整:
- 
contentType- 允许处理JSON(默认)、AVRO和PROTOBUF消息内容。内容类型必须与为提供的DebeziumEngine.Builder配置的SerializationFormat保持一致。
- 
enableBatch- 当设置为false(默认)时,debezium 适配器会对从源数据库接收到的每个ChangeEvent数据更改事件发送新的Message。如果设置为true,则适配器会为从 Debezium 引擎接收到的每批ChangeEvent发送一个单一的Message。这种负载不可序列化,需要自定义序列化/反序列化实现。
- 
enableEmptyPayload- 启用对墓碑(即删除)消息的支持。在数据库行被删除时,Debezium 可以发送一个具有与已删除行相同键且值为Optional.empty的墓碑更改事件。默认为false。
- 
headerMapper- 自定义HeaderMapper实现,允许选择和转换ChangeEvent头部到Message头部。默认的DefaultDebeziumHeaderMapper实现提供了setHeaderNamesToMap的 setter。默认情况下,所有头部都被映射。
- 
taskExecutor- 为 Debezium 引擎设置自定义TaskExecutor。
以下代码片段演示了此通道适配器的各种配置:
使用 Java 配置进行配置
下面的 Spring Boot 应用程序展示了如何使用 Java 配置来配置入站适配器:
@SpringBootApplication
public class DebeziumJavaApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(DebeziumJavaApplication.class)
                .web(WebApplicationType.NONE)
                .run(args);
    }
    @Bean
    public MessageChannel debeziumInputChannel() {
        return new DirectChannel();
    }
    @Bean
    public MessageProducer debeziumMessageProducer(
            DebeziumEngine.Builder<ChangeEvent<byte[], byte[]>> debeziumEngineBuilder,
            MessageChannel debeziumInputChannel) {
        DebeziumMessageProducer debeziumMessageProducer =
            new DebeziumMessageProducer(debeziumEngineBuilder);
        debeziumMessageProducer.setOutputChannel(debeziumInputChannel);
        return debeziumMessageProducer;
    }
    @ServiceActivator(inputChannel = "debeziumInputChannel")
    public void handler(Message<?> message) {
        Object destination = message.getHeaders().get(DebeziumHeaders.DESTINATION); 1
        String key = new String((byte[]) message.getHeaders().get(DebeziumHeaders.KEY)); 2
        String payload = new String((byte[]) message.getPayload()); 3
        System.out.println("KEY: " + key + ", DESTINATION: " + destination + ", PAYLOAD: " + payload);
    }
}
- 事件所针对的逻辑目的地的名称。通常,目的地由 - topic.prefix配置选项、数据库名称和表名称组成。例如:- my-topic.inventory.orders。
- 包含已更改表的键的模式以及已更改行的实际键。键模式及其对应的键有效负载在连接器创建事件时包含更改表中每个 - PRIMARY KEY(或唯一约束)列的一个字段。
- 类似于键,有效负载具有模式部分和有效负载值部分。模式部分包含描述有效负载值部分的信封结构的模式,包括其嵌套字段。对于创建、更新或删除数据的操作的更改事件都具有带有信封结构的值有效负载。 
key.converter.schemas.enable=false 和/或 value.converter.schemas.enable=false 允许分别禁用键或负载的消息内部模式内容。
同样地,我们可以配置 DebeziumMessageProducer 以批处理的方式处理传入的变更事件:
@Bean
public MessageProducer debeziumMessageProducer(
        DebeziumEngine.Builder<ChangeEvent<byte[], byte[]>> debeziumEngineBuilder,
        MessageChannel debeziumInputChannel) {
    DebeziumMessageProducer debeziumMessageProducer = new DebeziumMessageProducer(debeziumEngineBuilder);
	debeziumMessageProducer.setEnableBatch(true);
    debeziumMessageProducer.setOutputChannel(debeziumInputChannel);
    return debeziumMessageProducer;
}
@ServiceActivator(inputChannel = "debeziumInputChannel")
public void handler(List<ChangeEvent<Object, Object>> payload) {
    System.out.println(payload);
}
Debezium Java DSL 支持
spring-integration-debezium 通过 Debezium 工厂和 DebeziumMessageProducerSpec 实现提供了一个方便的 Java DSL 流式 API。
Debezium Java DSL 的 inbound channel adapter 是:
DebeziumEngine.Builder<ChangeEvent<byte[], byte[]>>   debeziumEngineBuilder = ...
 IntegrationFlow.from(
    Debezium.inboundChannelAdapter(debeziumEngineBuilder)
        .headerNames("special*")
        .contentType("application/json")
        .enableBatch(false))
    .handle(m -> System.out.println(new String((byte[]) m.getPayload())))
或者从本地 Debezium 配置属性创建一个 DebeziumMessageProducerSpec 实例,并默认使用 JSON 序列化格式。
Properties debeziumConfig = ...
 IntegrationFlow
    .from(Debezium.inboundChannelAdapter(debeziumConfig))
    .handle(m -> System.out.println(new String((byte[]) m.getPayload())))
以下 Spring Boot 应用程序提供了使用 Java DSL 配置入站适配器的示例:
@SpringBootApplication
public class DebeziumJavaApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(DebeziumJavaApplication.class)
            .web(false)
            .run(args);
    }
    @Bean
    public IntegrationFlow debeziumInbound(
        DebeziumEngine.Builder<ChangeEvent<byte[], byte[]>> debeziumEngineBuilder) {
        return IntegrationFlow
                .from(Debezium
                        .inboundChannelAdapter(debeziumEngineBuilder)
					    .headerNames("special*")
					    .contentType("application/json")
					    .enableBatch(false))
                .handle(m -> System.out.println(new String((byte[]) m.getPayload())))
                .get();
    }
}