1. Spring Cloud Stream-最简单的kafka整合示例

333 阅读2分钟

介绍

简单、高效、稳定地使用Spring Cloud Stream。

版本说明

  • kafka server version:2.5.x
  • kafka client version:2.5.1
  • spring boot version: 2.3.12.RELEASE
  • spring cloud version:Hoxton.SR12
  • spring cloud stream version: 3.0.13.RELEASE
  • spring cloud stream binder kafka version: 3.0.13.RELEASE
  • java version:1.8

其他版本的完整代码示例,请访问 github.com/codebaorg/S…

如果这篇文章帮助到了你,欢迎评论、点赞、转发。

依赖

Maven

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.12.RELEASE</version>
    <relativePath/>
</parent>

<properties>
    <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-stream</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-stream-binder-kafka</artifactId>
    </dependency>

</dependencies>

工程和配置

完整代码地址:github.com/codebaorg/S…

application.yaml 配置

kafka相关配置内容示例如下,其中localhost:9092test-topictest-group 可以替换为你的配置:

spring:
  cloud:
    stream:
      kafka:
        binder:
          brokers: localhost:9092

      bindings:
        my-input:
          destination: test-topic
          group: test-group

生产者发送消息

假设业务的消息实体示例为MyMessage类:

public class MyMessage {
    private String foo;
    private Integer bar;

    public MyMessage(String foo, Integer bar) {
        this.foo = foo;
        this.bar = bar;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyMessage myMessage = (MyMessage) o;
        return Objects.equals(foo, myMessage.foo) && Objects.equals(bar, myMessage.bar);
    }

    @Override
    public int hashCode() {
        return Objects.hash(foo, bar);
    }


    @Override
    public String toString() {
        return "MyMessage{" +
                "foo='" + foo + ''' +
                ", bar=" + bar +
                '}';
    }

    public String getFoo() {
        return foo;
    }

    public void setFoo(String foo) {
        this.foo = foo;
    }

    public Integer getBar() {
        return bar;
    }

    public void setBar(Integer bar) {
        this.bar = bar;
    }
}

发送消息的代码示例:

@Autowired
private BinderAwareChannelResolver channelResolver;

public void devTest() {
    // send message
    String topic = "test-topic";
    final MyMessage myMessage = new MyMessage("hello world", 2024);
    final Message<MyMessage> message = MessageBuilder.withPayload(myMessage).build();
    channelResolver.resolveDestination(topic).send(message);
}

消费者消费消息

MySink.class 用于定义input binder的相关信息,其中INPUT的值和application.yaml中的spring.cloud.stream.bindings的值保持一致。

import org.springframework.cloud.stream.annotation.Input;
import org.springframework.messaging.SubscribableChannel;

public interface MySink {

    String INPUT = "my-input";

    @Input(INPUT)
    SubscribableChannel input();

}

消费消息的代码示例:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

@Component
@EnableBinding(MySink.class)
public class MyConsumer {

    /**
     * logger
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(MyConsumer.class);

    /**
     * Consume.
     *
     * @param payload the payload
     */
    @StreamListener(MySink.INPUT)
    public void consume (@Payload Object payload) {
        LOGGER.info("payload:{}", payload.toString());
        // do something
    }

}

总结

  1. 根据你使用的kafka server的版本来确定springboot和spring cloud的版本,避免因为版本不一致而发生一些不符合预期的问题。
  2. spring cloud stream 整合kafka最简单的application.yaml配置如下:
spring:
  cloud:
    stream:
      kafka:
        binder:
          brokers: localhost:9092

      bindings:
        my-input:
          destination: test-topic
          group: test-group
  1. 使用BinderAwareChannelResolver类发送消息,写消息的同时可以自动创建topic,不需要提前自己创建topic。
  2. 使用StreamListener来消费消息(此时是kafka client自动提交消费的offset)。

参考

版本说明 · alibaba/spring-cloud-alibaba Wiki (github.com)

如果这篇文章帮助到了你,欢迎评论、点赞、转发。