springKafka 生产者、消费者,数据发送/接收

配置文件

# 指定kafka server的地址,集群配多个,中间,逗号隔开
spring.kafka.bootstrap-servers=
# 配置kafka 授权认证 --开始
spring.kafka.properties.sasl.mechanism=SCRAM-SHA-256
spring.kafka.properties.security.protocol=SASL_PLAINTEXT
spring.kafka.producer.properties.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="xxxx" password="xxxxx";
spring.kafka.consumer.properties.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="xxxx" password="xxxx";
# 配置kafka 授权认证 --结束
#重试次数
spring.kafka.producer.retries=3
# 重试间隔时间 (毫秒)
spring.kafka.producer.retry.backoff.ms=10000
#批量发送的消息数量
spring.kafka.producer.batch-size=1000
#32MB的批处理缓冲区
spring.kafka.producer.buffer-memory=335544320

#默认消费者组
spring.kafka.consumer.group-id=isms-group
#最早未被消费的offset
spring.kafka.consumer.auto-offset-reset=earliest
#批量一次最大拉取数据量
spring.kafka.consumer.max-poll-records=500
#自动提交时间间隔,单位ms
spring.kafka.consumer.auto-commit-interval=1000
#批消费并发量,小于或等于Topic的分区数
spring.kafka.consumer.batch.concurrency=2
import org.apache.kafka.clients.CommonClientConfigs;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.config.SaslConfigs;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.config.KafkaListenerContainerFactory;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaAdmin;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import org.springframework.kafka.listener.ContainerProperties;

import java.util.HashMap;
import java.util.Map;


@Configuration
public class KafkaConfiguration {

    @Value("${spring.kafka.bootstrap-servers}")
    private String bootstrapServers;

    @Value("${spring.kafka.producer.retries}")
    private Integer retries;
    @Value("${spring.kafka.producer.retry.backoff.ms}")
    private Integer retryBackoff;

    @Value("${spring.kafka.producer.batch-size}")
    private Integer batchSize;

    @Value("${spring.kafka.producer.buffer-memory}")
    private Integer bufferMemory;

    @Value("${spring.kafka.consumer.group-id}")
    private String groupId;

    @Value("${spring.kafka.consumer.auto-offset-reset}")
    private String autoOffsetReset;

    @Value("${spring.kafka.consumer.max-poll-records}")
    private Integer maxPollRecords;

    @Value("${spring.kafka.consumer.batch.concurrency}")
    private Integer batchConcurrency;

    @Value("${spring.kafka.consumer.auto-commit-interval}")
    private Integer autoCommitInterval;
    @Value("${spring.kafka.properties.security.protocol}")
    private String securityProtocol;
    @Value("${spring.kafka.properties.sasl.mechanism}")
    private String saslMechanism;
    @Value("${spring.kafka.producer.properties.sasl.jaas.config}")
    private String producerSaslJaasConfig;
    @Value("${spring.kafka.consumer.properties.sasl.jaas.config}")
    private String consumerSaslJaasConfig;

    /**
     *  生产者配置信息
     */
    @Bean
    public Map<String, Object> producerConfigs() {
        Map<String, Object> props = new HashMap<>();
        props.put(ProducerConfig.ACKS_CONFIG, "all");
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        props.put(ProducerConfig.RETRIES_CONFIG, retries);
        props.put(ProducerConfig.RETRY_BACKOFF_MS_CONFIG, retryBackoff);
        props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize);
        props.put(ProducerConfig.LINGER_MS_CONFIG, 1);
        props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory);
        props.put(ProducerConfig.TRANSACTION_TIMEOUT_CONFIG, 900000);
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        // 消息幂等开关,事务开启必须打开消息幂等,但是幂等可以单独使用
        props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true);
        props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, securityProtocol);
        props.put(SaslConfigs.SASL_MECHANISM, saslMechanism);
        props.put(SaslConfigs.SASL_JAAS_CONFIG, producerSaslJaasConfig);
        return props;
    }

    /**
     *  生产者工厂
     */
    @Bean
    public ProducerFactory<String, String> producerFactory() {
        return new DefaultKafkaProducerFactory<>(producerConfigs());
    }


    /**
     *  生产者模板
     */
    @Bean
    public KafkaTemplate<String, String> kafkaTemplate() {
        return  new KafkaTemplate<>(producerFactory());
    }


    @Bean
    public KafkaAdmin kafkaAdmin() {
        return new KafkaAdmin(kafkaTemplate().getProducerFactory().getConfigurationProperties());
    }

    /**
     *  消费者配置信息
     */
    @Bean
    public Map<String, Object> consumerConfigs() {
        Map<String, Object> props = new HashMap<>();
        props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, autoOffsetReset);
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, maxPollRecords);
        props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 600000);
        props.put(ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG, 300000);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        // 设置自动提交改成false
        props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
        props.put(ConsumerConfig.ALLOW_AUTO_CREATE_TOPICS_CONFIG,false);
        props.put(ConsumerConfig.MAX_POLL_INTERVAL_MS_CONFIG,60000);
        props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, securityProtocol);
        props.put(SaslConfigs.SASL_MECHANISM, saslMechanism);
        props.put(SaslConfigs.SASL_JAAS_CONFIG, consumerSaslJaasConfig);
        return props;
    }

    /**
     *  消费者批量工厂
     */
/*    @Bean
    public KafkaListenerContainerFactory<?> batchFactory() {
        ConcurrentKafkaListenerContainerFactory<Integer, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(new DefaultKafkaConsumerFactory<>(consumerConfigs()));
        //设置并发量,小于或等于Topic的分区数
        factory.setConcurrency(batchConcurrency);
        factory.getContainerProperties().setPollTimeout(3000);
        factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
        //设置为批量消费,每个批次数量在Kafka配置参数中设置ConsumerConfig.MAX_POLL_RECORDS_CONFIG
        factory.setBatchListener(true);

        return factory;
    }*/

    /**
     * 单个消费者
     * @return
     */
    @Bean
    public KafkaListenerContainerFactory<?> singleConsumerFactory() {
        ConcurrentKafkaListenerContainerFactory<Integer, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(new DefaultKafkaConsumerFactory<>(consumerConfigs()));
        factory.setConcurrency(1);
        factory.getContainerProperties().setPollTimeout(3000);
        factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
        return factory;
    }

    @Bean
    public KafkaConsumer<String,String> customKafkaConsumer(){
        return new KafkaConsumer<String, String>(consumerConfigs());
    }
}

生产者

@Component
public class SendMessageToKafka {

    private static final Logger log = LoggerFactory.getLogger(SendMessageToKafka.class);

    @Resource
    private KafkaTemplate<String,String> kafkaTemplate;


    public void sendToKafka(String message,String topicName){
        try {
            String topicDesc = TopicNameEnum.getDescByTopicName(topicName);
            SendResult<String, String> sendResult = kafkaTemplate.send(topicName, null, message).get(60, TimeUnit.SECONDS);
            if(sendResult.getRecordMetadata() != null){
                log.info("topic对象【{}】发送kafka成功,:{},message sent,topic:{}, partition={}, offset={}",topicDesc,sendResult.getProducerRecord().topic(), sendResult.getRecordMetadata().partition(),
                        sendResult.getRecordMetadata().offset());
            }else {
                log.warn("topic对象【{}】消息发送kafka失败,topic:{},进行重试。。",topicDesc, topicName);
                // 当kafka发送失败后,进行重试3次。
                FunctionResponse<Boolean> response = FunctionUtil.retryExecute(() -> {
                    try {
                        SendResult<String, String> kafkaResult = kafkaTemplate.send(topicName, null, message).get(60, TimeUnit.SECONDS);
                        if(kafkaResult.getRecordMetadata() != null){
                            return new FunctionResponse<>(true);
                        }else {
                            return new FunctionResponse<>(false);
                        }
                    } catch (Exception e) {
                        return new FunctionResponse<>(false);
                    }
                }, 3, 2000);

                if(!response.getResult()) {
                    log.error("topic对象【{}】 message sent,topic:{},最终重试发送失败:{}", topicDesc,topicName, message);
                }
            }
        } catch (Exception e) {
            log.error("topic【{}】写入kafka失败,{}",topicName,e);
        }
    }

}

消费者

@Component
public class CoreCommandListener {

    private static final Logger log = LoggerFactory.getLogger(CoreCommandListener.class);


    @KafkaListener(topics = {"topic名称"},containerFactory="singleConsumerFactory")
    private void commandConsumer(ConsumerRecord<Object,String> consumerRecord, Acknowledgment ack){
        DcpMessage message = JSONObject.parseObject(consumerRecord.value(),DcpMessage.class);
        log.info("offset:{},partition:{},消费到指令数据:{}",consumerRecord.offset(),consumerRecord.partition(),message);

        //手动提交
        ack.acknowledge();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot是一款用于简化Spring应用程序开发的框架,而Kafka是一款高性能的分布式消息系统。在Spring Boot中整合Kafka可以实现多生产者消费者的功能。 首先,我们需要在pom.xml文件中添加Kafka的依赖: ``` <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> ``` 接下来,我们需要配置Kafka的相关信息。在application.properties文件中添加Kafka的相关配置项,包括Kafka服务器地址、生产者消费者的配置等。 然后,我们需要创建生产者消费者的类。对于生产者,可以使用KafkaTemplate来发送消息,通过指定Topic名称和消息内容来发送消息: ```java @Autowired private KafkaTemplate<String, String> kafkaTemplate; public void sendMessage(String topic, String message) { kafkaTemplate.send(topic, message); } ``` 对于消费者,我们可以使用@KafkaListener注解来订阅指定的Topic,然后通过处理方法来处理接收到的消息: ```java @KafkaListener(topics = "topic-name") public void receiveMessage(String message) { // 处理接收到的消息 } ``` 最后,我们需要在应用程序启动时配置Kafka的相关配置。可以使用@Configuration注解来定义一个配置类,并在类中配置Kafka的相关信息。然后,在应用程序启动时,通过@SpringBootApplication注解来扫描配置类。 通过以上的步骤,我们就可以实现Spring Boot与Kafka的整合,并实现多生产者消费者的功能。当有新的消息发送Kafka的Topic时,消费者将能够接收到并进行相应的处理。 ### 回答2: Spring Boot是一个开源的Java框架,可用于快速开发基于Spring的应用程序。而Kafka是一个分布式的流处理平台,它能够将大量数据流进行高效地处理和传输。 在Spring Boot中整合Kafka,可以实现多生产者和多消费者的功能。首先,在项目的pom.xml文件中添加Kafka相关的依赖,例如: ``` <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> ``` 然后,在application.properties文件中配置Kafka的连接信息,包括Kafka的地址、端口等: ``` spring.kafka.bootstrap-servers=localhost:9092 ``` 接下来,创建生产者的代码。在Spring Boot中,可以使用KafkaTemplate来发送消息。例如,通过向topic发送消息: ``` @Autowired private KafkaTemplate<String, String> kafkaTemplate; public void sendMessage(String message) { kafkaTemplate.send("topicName", message); } ``` 创建消费者的代码也很简单。在Spring Boot中,可以使用@KafkaListener注解来监听特定的topic,并在接收到消息时执行相应的方法。例如: ``` @KafkaListener(topics = "topicName", groupId = "groupId") public void receiveMessage(String message) { // 处理接收到的消息 } ``` 最后,为了支持多个生产者消费者,可以在配置文件中配置多个topic和groupId。每个生产者消费者可以发送接收不同的topic消息,并使用不同的groupId进行消费。这样就实现了Spring Boot中多生产者和多消费者的整合。 通过以上步骤,我们就可以在Spring Boot中实现Kafka的多生产者和多消费者功能。无论是发送消息还是接收消息,都可以得到很好的扩展和灵活性。 ### 回答3: 在Spring Boot中整合Kafka实现多生产者和多消费者的过程相对简单。首先,我们需要在pom.xml文件中添加Kafka的依赖: ```xml <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> ``` 接下来,我们需要在application.properties或application.yml配置文件中配置Kafka的相关属性,包括Kafka服务器地址、端口、消费者生产者的配置等。 接下来,我们可以创建一个生产者实例来发送消息: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Component; @Component public class KafkaProducer { @Autowired private KafkaTemplate<String, String> kafkaTemplate; public void sendMessage(String topic, String message) { kafkaTemplate.send(topic, message); } } ``` 通过使用注入的KafkaTemplate实例,我们可以调用send方法来发送消息到指定的主题。 然后,我们可以创建一个消费者实例来接收消息: ```java import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Component; @Component public class KafkaConsumer { @KafkaListener(topics = "topicName") public void receiveMessage(String message) { System.out.println("Received message: " + message); } } ``` 通过使用@KafkaListener注解来监听指定的主题,当有消息到达时,Kafka会自动调用receiveMessage方法来处理接收到的消息。 如果我们需要使用多个生产者消费者,只需要在相应的类上添加不同的注解和配置即可。 综上所述,通过Spring Boot的Kafka整合,我们可以轻松实现多个生产者和多个消费者之间的消息传递。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值