[SpringCloud-SpringCloudStream] 简单通过Spring-cloud-stream组件使用kafka

本文详细介绍了如何使用Spring Cloud Stream结合Kafka实现消息的消费与生产,包括配置依赖、设置Kafka参数、编写消费者与生产者代码等关键步骤,为开发者提供了实用的参考。

1.消费者

一.pom依赖

        <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-stream-kafka</artifactId>
			<version>1.2.1.RELEASE</version>
		</dependency>
		也可以根据springcloud适配版本,省略版本号

二.Kafka消费者配置

#kafka对应的地址
spring.cloud.stream.kafka.binder.brokers = 192.168.xx.xxx:9092
#kafka的zookeeper对应的地址
spring.cloud.stream.kafka.binder.zkNodes = 192.168.xx.xxx:2181
#监听kafka的topic
spring.cloud.stream.bindings.xxxxxx.destination = topic-test
#消费者分组
spring.cloud.stream.bindings.xxxxxx.group = test-group
#接收原始消息
spring.cloud.stream.bindings.xxxxxx.consumer.headerMode = raw

其中“xxxxxx”是自定义字段,需要和第三步中消费者代码的String INPUT = "xxxxxx";保持一致;

三.消费者代码

public interface MqSinkI {

    String INPUT = "xxxxxx";

    /**
     * 消费者接口
     *
     * @return org.springframework.messaging.SubscribableChannel 接口对象
     */
    @Input(MqSinkI.INPUT)
    SubscribableChannel input();

}


@EnableBinding(value = {MqSinkI.class})
public class MqSinkReceiver {

    @Autowired
    MqListener mqListener;

    @StreamListener(MqSinkI.INPUT)
    public void messageListen(JSONObject jsonParam) {
        System.out.println("收到信息:" + jsonParam.toString());
        //处理请求的类,对消息进行处理
        mqListener.listen(jsonParam);
    }
}

@Component
public class MqListener {

    public void listen(JSONObject jsonParam) {
        System.out.println("收到:" + jsonParam);
    }
}

四.小结

  • 注意配置项里面的xxx字段要和代码定义的字符串常量保持一致
  • MqListener 类可以可以省去,处理逻辑直接可以写在MqSinkReceiver 类的messageListen里面;
  • 配置中的地址和主题都可以配置多个
  • spring.cloud.stream.bindings.xxxxxx.consumer.headerMode = raw配置项
    可能会影响消息的接收格式,如果不添加这条配置,接收引擎的消息可能会有问题,如果其他生产者按照第2点的方式生产消息,则可以不使用这条配置。

2.生产者

一.pom依赖

与消费者一样

二.Kafka生产者配置

#kafka对应的地址
spring.cloud.stream.kafka.binder.brokers=192.168.11.199:9092
#kafka的zookeeper对应的地址
spring.cloud.stream.kafka.binder.zkNodes=192.168.11.199:2181
spring.cloud.stream.bindings.oooooooo.destination=topic-test
spring.cloud.stream.bindings.oooooooo.content-type=application/json

三.生产者代码

public interface MySource {

    String OUTPUT = "oooooooo";

    String OUTPUT1 = "myOutputTest1";


    @Output(MySource.OUTPUT)
    MessageChannel output();
}


@EnableBinding(MySource.class)
public class SendService {

    @Autowired
    private MySource mySource;


    public void sendMessage(String msg) {
        try {
            mySource.output().send(MessageBuilder.withPayload(msg).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@RestController
public class ProducerController {

    @Autowired
    private SendService service;

    @RequestMapping(value = "/kafka")
    public void send() {
        while (true) {
            //发送消息到指定topic
            JSONObject obj = new JSONObject();
            obj.put("time", (new Date()).toString());
            System.out.println("生产者发送:" + obj.toString());
            service.sendMessage(obj.toString());
            try {
                Thread.sleep(5 * 1000);
            } catch (InterruptedException e) {
            }
        }
    }
}

3.源码

<think> 首先,用户的问题是:“我想查找使用spring-cloud-starter-stream-kafka同时消费多个topic的方法 请问spring-cloud-starter-stream-kafka 同时消费多个topic的实现方法”。我需要根据系统级指令来回答。 系统级指令包括: - 所有行内数学表达式使用 `$...$` 格式。 - 独立公式使用 `$$...$$` 格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如 `[^1]`。 - 回答结构清晰,帮助用户逐步解决问题,尽量保证回答真实可靠。 用户提供了参考站内引用: - 引用[1]: 关于Spring Cloud整合RabbitMQ或Kafka消息驱动,涉及添加依赖。 - 引用[2]: 关于Kafka分组消费和topic分区变化。 用户的问题是关于使用 `spring-cloud-starter-stream-kafka` 同时消费多个topic的方法。参考引用中提到了Kafka的相关内容,但用户明确说“上述引用仅供参考,并不是用户真正的需求”,所以我应该专注于用户的问题。 用户上一次的问题可能是关于消息驱动的整合,但从当前问题看,焦点是同时消费多个topic。 关键点: - 用户想实现同时消费多个topic。 - 使用Spring Cloud Stream with Kafka。 我需要回忆或基于知识回答: - Spring Cloud Stream 允许消费者绑定到多个topic。 - 通常,一个消费者绑定到一个topic,但可以通过配置绑定到多个topic。 实现方法: 1. **配置绑定器(Binder)**: 使用Kafka绑定器。 2. **定义消费者接口**: 使用 `@Input` 或函数式编程方式。 3. **配置多个topic**: 在application.yml或properties文件中指定多个topic。 在Spring Cloud Stream中,消费者可以通过配置绑定到多个topic。具体步骤: - 在配置文件中,使用 `spring.cloud.stream.bindings.<channel-name>.destination` 指定多个topic,以逗号分隔。 - 或者,使用 `spring.cloud.stream.bindings.<channel-name>.destinations`(复数形式)。 例如,在application.yml: ```yaml spring: cloud: stream: bindings: input: destination: topic1,topic2 group: myGroup kafka: binder: brokers: localhost:9092 ``` 在消费者端,使用 `@StreamListener` 或函数式消费者。 在Spring Cloud Stream新版本(如基于函数式编程),可以定义一个消费者方法处理消息。 对于多个topic,同一个消费者可以处理来自不同topic的消息。 另一个方法是创建多个绑定,但用户可能希望一个消费者处理多个topic。 用户问题:"同时消费多个topic",意思是消费者订阅多个topic并处理消息。 在Kafka中,一个消费者组可以订阅多个topic,Spring Cloud Stream支持这个。 实现步骤: 1. 添加依赖:`spring-cloud-starter-stream-kafka` 2. 配置消费者绑定。 3. 编写消费者代码。 基于参考引用: - 引用[2]提到分组分区消费和topic分区变化,这相关,但不直接解决多个topic消费。 我应该提供清晰的步骤。 回答结构: - 逐步解释方法。 - 使用中文。 - 在末尾生成相关问题。 - 添加引用标识:由于用户提供了引用,我应该引用它们,但用户说“上述引用仅供参考”,所以可能不需要强制引用,除非在内容中使用。指令说“回答中引用的段落末尾自然地添加引用标识”,所以我应该在引用时添加。 在内容中,我可以提到参考信息,但主要根据知识回答。 最终回答: 1. **介绍**:简要说明方法。 2. **步骤**: - 添加依赖。 - 配置文件设置。 - 消费者代码。 3. **示例**:提供代码示例。 4. **生成相关问题**。 确保没有数学表达式,所以可能不需要LaTeX,除非有公式。但指令要求如果有,必须使用格式。 在这个上下文中,可能没有数学表达式,所以可以忽略。 生成相关问题:3个相关问题。 相关问题想法: 1. 如何配置多个topic的消费者组? 2. 如何处理来自不同topic的消息? 3. Spring Cloud Stream中如何实现消息过滤? 问题应相关。 </think> 基于您的问题,我将在Spring Cloud Stream框架下,详细介绍如何使用 `spring-cloud-starter-stream-kafka` 实现同时消费多个Kafka topic的方法。Spring Cloud Stream通过绑定器(Binder)抽象消息中间件(如Kafka),支持消费者订阅多个topic。核心是通过配置文件指定多个topic名称,并确保消费者逻辑正确处理消息。以下是逐步实现方法,确保可靠性和清晰结构。 ### 实现步骤 #### 1. **添加依赖** 首先,在您的Spring Boot项目中添加 `spring-cloud-starter-stream-kafka` 依赖。Maven用户可以在 `pom.xml` 中添加: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-kafka</artifactId> <version>3.1.3</version> <!-- 请根据您的Spring Cloud版本调整 --> </dependency> ``` - 这个依赖提供了Kafka绑定器支持,让您能轻松集成Kafka消息驱动[^1]。 #### 2. **配置消费者绑定多个topic** 在 `application.yml`(或 `application.properties`)中配置消费者绑定到多个topic。使用 `spring.cloud.stream.bindings.<channel-name>.destination` 属性,以逗号分隔多个topic名称。例如: ```yaml spring: cloud: stream: bindings: input-in-0: # 输入通道名称,基于函数式编程命名 destination: topic1,topic2 # 指定多个topic,逗号分隔 group: my-consumer-group # 消费者组名,确保分区消费 content-type: application/json # 消息格式 kafka: binder: brokers: localhost:9092 # Kafka broker地址 auto-create-topics: true # 如果topic不存在,自动创建 ``` - **解释**: - `destination: topic1,topic2`:表示消费者同时订阅 `topic1` 和 `topic2`。Spring Cloud Stream会自动创建对应的订阅关系。 - `group: my-consumer-group`:消费者组名,用于Kafka的分组消费机制。同一组内的消费者平均分配topic分区[^2]。 - 如果需要更细粒度控制(如不同topic使用不同配置),可以使用 `spring.cloud.stream.bindings.<channel-name>.destinations`(复数形式),但多数场景下 `destination` 已足够。 - 注意:Kafka topic的分区数会影响并发性能,建议提前创建topic并设置适当分区数(如使用Kafka命令行工具调整)[^2]。 #### 3. **编写消费者代码** 使用函数式编程风格(Spring Cloud Stream推荐方式)定义消费者。创建一个Spring Bean作为消息处理器,处理来自多个topic的消息。示例代码如下: ```java import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import java.util.function.Consumer; @Component public class MultiTopicConsumer { @Bean public Consumer<String> input() { // 方法名需与配置中的binding名称匹配(如 input-in-0) return message -> { // 处理消息逻辑:这里简单打印,实际业务可解析JSON或处理数据 System.out.println("Received message from multiple topics: " + message); // 可根据消息来源topic自定义处理,例如: // if (message.startsWith("topic1")) { ... } }; } } ``` - **解释**: - 方法名 `input()` 对应配置中的 `input-in-0`(函数式编程默认命名规则为 `<functionName>-in-<index>`)。 - 消费者逻辑在 `Consumer<String>` 中定义,消息体类型为 `String`(如果消息是JSON,可使用 `@Bean public Consumer<Message<MyData>>` 并添加反序列化配置)。 - 消息会自动从所有配置的topic中消费,无需在代码中显式指定topic。 - 如果您需要区分消息来源topic,可以在消息头中获取topic信息: ```java import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; @Bean public Consumer<Message<String>> input() { return message -> { String payload = message.getPayload(); String topic = (String) message.getHeaders().get("kafka_receivedTopic"); System.out.println("Received from topic: " + topic + ", message: " + payload); // 业务逻辑基于topic分支处理 }; } ``` ### 关键注意事项 - **并发与分区**:Kafka消费者组会自动平衡多个topic的分区。确保 `group` 配置一致,以支持分组消费。如果某个topic分区数变化(如从2增加到4),消费者会自动重新平衡[^2]。 - **错误处理**:添加死信队列(DLQ)配置处理消费失败的消息: ```yaml spring: cloud: stream: bindings: input-in-0: consumer: max-attempts: 3 # 重试次数 dlq-name: my-dlq-topic # 死信topic ``` - **性能优化**:在高并发场景下,增加消费者实例数(如启动多个服务副本),Kafka会根据分区数自动分配负载。 - **测试验证**:使用Kafka命令行工具或生产者代码发送消息到 `topic1` 和 `topic2`,观察消费者日志是否正常处理。 通过以上步骤,您可以高效实现同时消费多个Kafka topic的需求。Spring Cloud Stream的抽象层简化了配置,同时保持Kafka原生特性(如分区消费和消息顺序)[^1][^2]。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值