
# Kafka客户端使用建议
#### consumer使用建议
1. consumer的owner线程需确保不会异常退出，避免客户端无法发起消费请求，阻塞消费。
2. 确保处理完消息后再做消息commit，避免业务消息处理失败，无法重新拉取处理失败的消息。
3. 通常不建议对每条消息都进行commit，如果对每条消息都进行了commit，会导致OFFSET_COMMIT请求过多，进而导致CPU使用率过高。例如：如果一个消费请求拉取1000条消息，每条都commit，则commit请求TPS是消费的1000倍，消息体越小，这个比例越大。建议隔一定条数或时间，批量commit，或打开enable.auto.commit，这样设置会存在一个缺点，即在客户端故障时，可能丢失一部分缓存的消费进度，导致重复消费。请根据业务实际情况，设置批量commit。
4. consumer不能频繁加入和退出group，频繁加入和退出，会导致consumer频繁做rebalance，阻塞消费。
5. 同一消费组内consumer数量不能超过该消费组订阅的分区总数，否则会有consumer拉取不到消息。
6. consumer需周期poll，维持和server的心跳，避免心跳超时，导致consumer频繁加入和退出，阻塞消费。
7. consumer拉取的消息本地缓存应有大小限制，避免OOM（Out of Memory）。
8. consumer session设置为30秒，session.timeout.ms=30000。
9. Kafka不能保证消费重复的消息，业务侧需保证消息处理的幂等性。
10. 消费线程退出要调用consumer的close方法，避免同一个组的其他消费者阻塞session.timeout.ms的时间。
11. 消费组名称开头不使用特殊字符（如#），使用特殊字符可能会导致云监控无法展示此消费组的监控数据。
12. 在消费逻辑中处理AuthorizationException，设置重试消费。如在SpringKafka中，可以在配置文件中增加以下配置。
    ```
    # 设置授权异常重试间隔为10秒
    spring.kafka.listener.authorizationExceptionRetryInterval=10000
    ```
    
 
#### producer使用建议
1. 同步复制客户端需要配合使用：acks=all
2. 配置发送失败重试：retries=10
3. 配置发送重试间隔：retry.backoff.ms=1000
4. 发送优化：对于时延敏感的信息，设置linger.ms=0。对于时延不敏感的信息，设置linger.ms在100\~1000之间。
5. 生产端的JVM内存要足够，避免内存不足导致发送阻塞。
6. 时间戳设置为与当地时间一致，避免时间戳为未来时间导致消息无法老化。
7. 尽量复用producer，不要频繁创建producer。当producer开启幂等时（生产者客户端3.0及之后的版本默认开启幂等），生产消息会在服务端创建生产者状态对象，若频繁创建producer，会导致服务端创建大量生产者状态对象后无法及时回收，服务端内存占用飙升，进而导致服务端性能急剧下降。如果不需要使用幂等功能，请将"enable.idempotence"设置为"false"。
8. 捕获AuthorizationException异常，建议在业务侧重试生产消息，可以采取有限重试及退避策略实现自愈。
 
#### Topic使用建议
配置要求：推荐3副本，同步复制，最小同步副本数为2，且同步副本数不能等于Topic副本数，否则宕机1个副本会导致无法生产消息。
创建方式：支持选择是否开启Kafka自动创建Topic的开关。选择开启后，表示向一个未创建的Topic生产或消费消息时，系统会自动创建此Topic。
#### 其他建议
连接数限制：3000
消息大小：不能超过10MB
使用SASL_SSL协议访问Kafka：确保DNS具有反向解析能力，或者在hosts文件配置Kafka所有节点IP和主机名映射，避免Kafka client做反向解析，阻塞连接建立。
磁盘容量申请超过业务量 \* 副本数的2倍，即保留磁盘空闲50%左右。
业务进程JVM内存使用确保无频繁FGC，否则会阻塞消息的生产和消费。
