kafka最佳实践

常用参数最佳配置

# kafka集群地址,可以多个
spring.kafka.bootstrap-servers=127.0.0.1:9092
#=============== kafka-provider =======================
#0:生产者将不会等待来自服务器的任何确认,不建议用,很可能丢消息
#1:服务端leader本地日志写入成功后返回
#all:服务端leader将等待数据副本完全同步后再返回
spring.kafka.producer.acks=1

#建议调成1~3适当规避网络抖动,再多容易引起在故障时引起雪崩
#但要确保消费者消费逻辑幂等性
spring.kafka.producer.retries=1

# 每次批量发送消息的数量
spring.kafka.producer.batch-size=16384
#生产者可用于缓冲等待发送到服务器的消息的内存总字节数
spring.kafka.producer.buffer-memory=33554432

#Kafka都是内网在消息大小不至于影响性能之前别乱调
spring.kafka.producer.compression-type=none

spring.kafka.producer.topic.default=shuimuhanchen
# 指定消息key和消息体的编解码方式
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer

#=============== kafka-consumer =======================
# 指定默认消费者group id
spring.kafka.consumer.group-id=shuimuhanchen

#需要改成false,由Spring Kafka框架来管理提交,这是使用框架的最大意义,交给spring.kafka.listener.ack-mod管理
spring.kafka.consumer.enable-auto-commit=false

#自动提交的间隔,如果上面enable-auto-commit是false了,这个值就没意义了,可以忽略
spring.kafka.consumer.auto-commit-interval=1000s

#如果在服务端没有当前groupId的offset,如何初始化,踩坑过最多的配置,好几次都是因为earliest引起消息重放导致消费堆积,强烈建议遵循”先上线消费端,再上线生产端“的上线顺序,pouch项目因为配成了earliest引起消息重放导致消息堆积
spring.kafka.consumer.auto-offset-reset=latest

#消费者每次最大拉取消息条数建议适当调小,特别是消费逻辑本身就比较耗时的情况下
spring.kafka.consumer.max-poll-records=100

# 指定消息key和消息体的编解码方式
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer

#=============== kafka-监听器 =======================
#Spring Kafka监听器的ACK模型,看需选取,一般默认值batch就够了,主要是在吞吐量、实时性两个方面达成平衡,MANUAL的使用确保自己可以hold的住,原生参数enable-auto-commit为true的时候这个参数没有意义
#
#RECORD:每ACK一条立即提交一次
#
#BATCH:拉取到的消息都ACK后批量提交
#
#TIME:距上次提交一定时间后提交
#
#COUNT:ACK达到一定个数后提交
#
#COUNT_TIME:时间&个数阈值都会触发提交
#
#MANUAL:ACK由Listener代码手动控制,提交行为同BATCH
#
#MANUAL_IMMEDIATE:ACK由Listener代码手动控制,提交行为同RECORD
spring.kafka.listener.ack-mode=batch

#单次消息拉取的超时时间,结合max-poll-records和消息大小考量,别超时就行
spring.kafka.listener.poll-timeout=3000ms

#每个监听器启动的消费者的数量(默认3),每个消息分片只能被同一个消费组中的一个消费者消费,所以这个参数取决于你的机器数量和分区数量,这个参数略大于等于 分片数/机器节点数 就可以
#例如:Kafka Topic分片5个,有3台机器消费,设置成2就行
spring.kafka.listener.concurrency=1

消息发送

 BaseKafkaMessage<String> msg = new BaseKafkaMessage<>();
 msg.setMsgType(EnumMessageType.SELF_MSG.getType());
 msg.setData("test");
 kafkaTemplate.send(defaultTopic, JSON.toJSONString(msg));

生产者发送的几种使用场景:

// 往默认Topic发送一条只有value的消息
kafkaTemplate.sendDefault(T value)
 
// 往默认Topic发送一条带key的消息,key参数用来哈希,分配partition使用。一般我们不传key,默认用round-robin轮询负载均衡算法来选partition。
kafkaTemplate.sendDefault(K key, T value)
 
// 指定Topic发送消息
kafkaTemplate.send(String topic, ......)
 
// 指定Topic和分区发送消息
kafkaTemplate.send(String topic, Integer partition, ......)

消息消费

@Component
public class defaultConsumer {

    private static Logger LOG = LoggerFactory.getLogger(defaultConsumer.class);

    @KafkaListener(topics = "${spring.kafka.producer.topic.default}")
    public void handlerMessage(String msg) {

        try {
            BaseKafkaMessage baseKafkaMessage = JSONObject.parseObject(msg, BaseKafkaMessage.class);
            if(baseKafkaMessage == null
                    || !EnumMessageType.SELF_MSG.getType().equals(baseKafkaMessage.getMsgType())
                    || baseKafkaMessage.getData() == null){
                return;
            }
            String msgData = (String)baseKafkaMessage.getData();
            System.out.println(msgData);
            LOG.info("消费消息:msg={}", msg);
        } catch (Exception e) {
            LOG.error("epx handle filed.{}", e);
        }
    }
}

消费者消费的几种使用场景:

// 单条消息消费,方法执行完后自动ACK
public void consume(ConsumerRecord<K, V> data){
    ...
}
 
// 上面的简化情况,适用于没有key的场景
public void consume(V value){
    ...
}
 
// 单条消息消费,消费逻辑中手动ACK,请确认spring.kafka.listener.ack-mode为手动模式
public void consume(V value, Acknowledgment ack){
    ...
    ack.acknowledge();
}
 
// 批量消息消费,消费逻辑中手动ACK,请确认spring.kafka.listener.ack-mode为手动模式
public void consumeBatch(List<ConsumerRecord<K, V>> data, Acknowledgment ack){
    ...
    ack.acknowledge();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值