** 2019-11-21 16:04:11 **
终于想起了我有博客...最近好不容易忙完巡检模块,想写点什么。
之前公司订餐系列模块用到了kafka,整理一些配置和使用把。
一.整理的一些bootstrap.yml配置
都是网上啊啥找的一些配置信息,可以参考使用。 具体的优化啊,高级配置的话还是参照官网kafka去琢磨加深把。
kafka:
bootstrap-servers: 192.168.1.1 #你kafka服务器地址
#生产者的配置,大部分我们可以使用默认的,这里列出几个比较重要的属性
producer:
#每批次发送消息的数量
batch-size: 16
#设置大于0的值将使客户端重新发送任何数据,一旦这些数据发送失败。
#注意,这些重试与客户端接收到发送错误时的重试没有什么不同。允许重试将潜在的改变数据的顺序,
#如果这两个消息记录都是发送到同一个partition,则第一个消息失败第二个发送成功,则第二条消息会比第一条消息出现要早。
retries: 0
#producer可以用来缓存数据的内存大小。如果数据产生速度大于向broker发送的速度,
#producer会阻塞或者抛出异常,以“block.on.buffer.full”来表明。
#这项设置将和producer能够使用的总内存相关,但并不是一个硬性的限制,
#因为不是producer使用的所有内存都是用于缓存。一些额外的内存会用于压缩(如果引入压缩机制),同样还有一些用于维护请求。
buffer-memory: 33554432
acks: all
#key序列化方式
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
#消费者的配置
consumer:
#Kafka中没有初始偏移或如果当前偏移在服务器上不再存在时,默认区最新 ,有三个选项 【latest, earliest, none】
auto-offset-reset: latest
#是否开启自动提交
enable-auto-commit: false
#自动提交的时间间隔
auto-commit-interval: 100
#key的解码方式
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
#value的解码方式
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
#在/usr/local/etc/kafka/consumer.properties中有配置
group-id: consumerGroup #【你自己配置的】
二.Kafka生产者
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.ProducerListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 生产者
*
* @author aman
* @date 2019/10/26
*/
@Slf4j
@Component
@AllArgsConstructor
public class OrderSendMsgByKafka {
private KafkaTemplate<String, String> kafkaTemplate;
private final RepastOrderService repastOrderService;
private static final String TOPIC_NAME = "CloudSchoolRepast";
/**
* 定时任务每天一点发送每天的订餐信息
*/
@Scheduled(cron = "0 0 1 * * ?")
public void sendOrderMessageByKafka() {
/**
* 发送数据到消息队列
* send有多个重载方法
*/
try {
kafkaTemplate.send(TOPIC_NAME, 0, "data", JSON.toJSONString(order));
} catch (Exception e) {
log.error("发送异常try : 主题名称topic = {}, 异常exception = {}", TOPIC_NAME);
}
//消息发送的监听器,用于回调返回信息
kafkaTemplate.setProducerListener(new ProducerListener<String, String>() {
/**
* 成功后调用
* @param topic 主题
* @param partition 目标分区
* @param key 键
* @param value 值
* @param recordMetadata 发送成功的结果
*/
@Override
public void onSuccess(String topic, Integer partition, String key, String value, RecordMetadata recordMetadata) {
log.info("发送成功 : 主题名称topic = {}, 分区partition = {}, 键key = {}, 值value = {}, recordMetadata = {}", topic, partition, key, value, recordMetadata);
}
/**
* 失败后调用, ProducerRecord被覆盖后不调用
* @param topic 主题
* @param partition 目标分区
* @param key 键
* @param value 值
* @param exception 异常
*/
@Override
public void onError(String topic, Integer partition, String key, String value, Exception exception) {
log.error("发送异常onError : 主题名称topic = {}, 分区partition = {}, 键key = {}, 值value = {}, 异常exception = {}", topic, partition, key, value, exception);
}
});
}
}
三.Kafka消费者
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.annotation.TopicPartition;
import org.springframework.stereotype.Component;
import java.util.Optional;
/**
* Kafka消费者
*
* @author caoxiang
* @date 20119/10/26
*/
@Component
@Slf4j
@AllArgsConstructor
public class RepastConsumer {
private static final String TOPIC_NAME = "CloudSchoolRepast";
private final RepastOrderService repastOrderService;
@KafkaListener(id = "RepastConsumerAfter", topicPartitions = {@TopicPartition(topic = TOPIC_NAME, partitions = {"1"})})
public void listen(ConsumerRecord<?, ?> record) {
/**
* 如果record.value()为空,返回空的Optional,
* 否则返回一个value值为record.value()的Optional
*/
Optional<?> kafkaMessage = Optional.ofNullable(record.value());
log.info("Receiver record = {}", record);
/**
* 判断Optional的value值是否为空
*/
if (kafkaMessage.isPresent()) {
/**
* 获取Optional的value值 List<OrderBySendKafka>
*/
Object message = kafkaMessage.get();
log.info("Receiver message = {}", message);
}
}
}