Java多kafka消费场景

导入jar包
<dependency>
      <groupId>org.springframework.kafka</groupId>
      <artifactId>spring-kafka</artifactId>
</dependency>
yaml配置

spring:
  kafka:
    bootstrap-servers: server
    consumer:
      group-id: 消费者你的groupId
      enable-auto-commit: false
      auto-offset-reset: earliest
      #用于链接带密码的kafka  配置,如果kafka没有密码需要注释掉
      properties:
        sasl.mechanism: PLAIN
        security.protocol: SASL_PLAINTEXT
        sasl.jaas.config: org.apache.kafka.common.security.plain.PlainLoginModule required username="用户" password="密码";
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      #根据需要配置生产者还是消费者
    #producer:
    listener:
      ack-mode: manual
      concurrency: 1

 

dpkafka:
  bootstrap-servers: server
  properties:
    sasl.mechanism: PLAIN
    security.protocol: SASL_PLAINTEXT
    sasl.jaas.config: org.apache.kafka.common.security.plain.PlainLoginModule required username="用户" password="密码";
  consumer:
    group-id: dp-master-original-dev
    auto-offset-reset: earliest
    auto-commit-interval: 100
    enable-auto-commit: false
    key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
    value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
  # Kafka Consumer Listener 监听器配置
  listener:
    ack-mode: manual_immediate #设置手动提交模式
    # missing-topics-fatal: false # 消费监听接口监听的主题不存在时,默认会报错。所以通过设置为 false ,解决报错
自定义Config

第一个kafka会被spring自动装配,所以只需要对kafka2进行配置重新定义Config即可。 

@Configuration
public class KafkaDpConfig {
 
    @Value("${spring.dpkafka.bootstrap-servers}")
    private String bootstrapServers;
    @Value("${spring.dpkafka.consumer.group-id}")
    private String groupId;
    @Value("${spring.dpkafka.consumer.enable-auto-commit}")
    private boolean enableAutoCommit;
 
    @Value("${spring.dpkafka.properties.security.protocol}")
    private String kafkaSecurityProtocol;
    @Value("${spring.dpkafka.properties.sasl.mechanism}")
    private String kafkaSASLMechanism;
    @Value("${spring.dpkafka.properties.sasl.jaas.config}")
    private String kafkaConsumerSASLJaasConfig;
 
    @Bean
    public KafkaTemplate<Integer, String> kafkaDmHubTemplate() {
        return new KafkaTemplate<>(producerFactory());
    }
 
    //此处最好手动指定数据源factory的bean名称,在消费者端会用到
    @Bean
    KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<Integer, String>> dpKafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<Integer, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        factory.setConcurrency(1);
        factory.getContainerProperties().setPollTimeout(3000);
        //设置批量消费
        factory.setBatchListener(false);
        factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
//      factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL);
        return factory;
    }
 
    private ProducerFactory<Integer, String> producerFactory() {
        return new DefaultKafkaProducerFactory<>(producerConfigs());
    }
 
    public ConsumerFactory<Integer, String> consumerFactory() {
        return new DefaultKafkaConsumerFactory<>(consumerConfigs());
    }
 
    private Map<String, Object> producerConfigs() {
        Map<String, Object> props = new HashMap<>();
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        props.put(ProducerConfig.RETRIES_CONFIG, 3);
        props.put(ProducerConfig.ACKS_CONFIG, "1");
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        return props;
    }
 
    private Map<String, Object> consumerConfigs() {
        Map<String, Object> props = new HashMap<>();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
        props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, enableAutoCommit);
        props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, 20);
        props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 100);
        props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 120000);
        props.put(ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG, 180000);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, kafkaSecurityProtocol);
        props.put(SaslConfigs.SASL_MECHANISM, kafkaSASLMechanism);
        props.put("sasl.jaas.config", kafkaConsumerSASLJaasConfig);
 
        return props;
    }
 
}
指定kafka生产通道
public class KafkaServiceImpl implements KafkaService {

	/** salesforce kafka通道*/
	@Resource
	private KafkaTemplate<String, String> kafkaTemplate;

	/** kafka通道*/
	@Resource(name="kafkaDmHubTemplate")
	private KafkaTemplate<String,String> kafkaDmHubTemplate;
	/**
	 * 创建kafka topic
	 *
	 * @param kafkaTopicDTO kafkaTopic
	 * @return 返回
	 */
	@Override
	public Boolean createTopic(KafkaTopicDTO kafkaTopicDTO) {
		return false;
	}

	/**
	 * 给指定topic发消息
	 *
	 * @param topic 主题
	 * @param baseEntity 消息
	 */
	@Override
	public void sendMessage(String topic, JSONObject baseEntity) {
		kafkaTemplate.send(TopicConstant.CEN, JSON.toJSONString(baseEntity));
	}

	/**
	 * 给指定topic发消息(通道)
	 *  @param topic      主题
	 * @param baseEntity 消息
     */
	@Override
	public void sendDmHubMessage(String topic, Object baseEntity) {
		kafkaDmHubTemplate.send(topic, JSON.toJSONString(baseEntity));
	}
}
kafka监听消费

使用@KafkaListener注解监听,此处containerFactory填写刚才定义的@Bean factory名称。

//设置批量消费 factory.setBatchListener(true);
@KafkaListener(topics = XXX,containerFactory ="dpKafkaListenerContainerFactory")
	public void listenCustomer(List<String> records, Acknowledgment ack) {
		try {
			long start=System.currentTimeMillis();
			AtomicReference<Object> response = new AtomicReference<>();
			records.forEach(record -> {
				...
			});
		}catch (Exception e){
			log.error("消费数据异常:{}",e.getMessage());
		}finally {
			ack.acknowledge();
		}
	}
//factory.setBatchListener(false);设置的不是批量消费
@KafkaListener(topics = "XXX", containerFactory = "dpKafkaListenerContainerFactory")
	public void listenCustomer(ConsumerRecord<String, String> consumerRecord, Acknowledgment ack) {
		try {
			long start=System.currentTimeMillis();
			AtomicReference<Object> response = new AtomicReference<>();
			String value = consumerRecord.value();
		
		}catch (Exception e){
			log.error(e.getMessage(), consumerRecord.value());
		}finally {
			ack.acknowledge();
		}
	}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
手把手视频详细讲解项目开发全过程,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 课程简介 细致简介了消息队列在大数据的应用场景Kafka集群搭建、Kafka操作,基准测试、架构、编程、结合Kafka Eagle简介原理等 课程亮点 1,知识体系完备,从小白到大神各阶段读者均能学有所获。 2,生动形象,化繁为简,讲解通俗易懂。 3,结合工作实践及分析应用,培养解决实际问题的能力。 4,企业级方案设计,完全匹配工作场景。 适用人群 1、对大数据感兴趣的在校生及应届毕业生。 2、对目前职业有进一步提升要求,希望从事大数据行业高薪工作的在职人员。 3、对大数据行业感兴趣的相关人员。 课程内容 第一章 简介 1.1 消息队列简介 1.2 Kafka简介 1.3 Kafka的优势 1.4 哪些公司在使用Kafka 1.5 Kafka生态圈介绍 1.6 Kafka版本 第二章 环境搭建 2.1 搭建Kafka集群 2.2 目录结构分析 2.3 Kafka一键启动/关闭脚本 第三章 基础操作 3.1 创建topic 3.2 生产消息到Kafka 3.3 从Kafka消费消息 3.4 使用Kafka Tools操作Kafka 第四章 Kafka基准测试 第五章 Java编程操作Kafka 5.1 同步生产消息到Kafka中 5.2 从Kafka的topic中消费消息 5.3 异步使用带有回调函数方法生产消息 第六章 架构 6.1 Kafka重要概念 6.2 消费者组 第七章. Kafka生产者幂等性与事务 38 7.1 幂等性 第八章 分区和副本机制 8.1 生产者分区写入策略 8.2 消费者组Rebalance机制 8.3 消费者分区分配策略 8.4 副本机制 第九章 高级(High Level)API与低级(Low Level)API 9.1 高级API 9.2 低级API 9.3 手动消费分区数据 第十章 监控工具Kafka-eagle介绍 10.1 Kafka-Eagle简介 10.2 安装Kafka-Eagle 10.3 Kafka度量指标 第十一章 Kafka原理 11.1 分区的leader与follower 11.2 Kafka生产、消费数据工作流程 11.3 Kafka的数据存储形式 11.4 消息不丢失机制 11.5 数据积压 第十二章 Kafka中数据清理(Log Deletion) 12.1 日志删除 12.2 日志压缩(Log Compaction)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值