当我使用Kafka的Java API时,如果我让主线程的睡眠时间少于2000ns,它就无法生成任何消息。我真的想知道为什么会这样?
这是我的制片人:
public class Producer {
private final KafkaProducer<String, String> producer;
private final String topic;
public Producer(String topic, String[] args) {
//......
//......
producer = new KafkaProducer<>(props);
this.topic = topic;
}
public void producerMsg() throws InterruptedException {
String data = "Apache Storm is a free and open source distributed";
data = data.replaceAll("[\\pP‘’“”]", "");
String[] words = data.split(" ");
Random _rand = new Random();
Random rnd = new Random();
int events = 10;
for (long nEvents = 0; nEvents < events; nEvents++) {
long runtime = new Date().getTime();
int lastIPnum = rnd.nextInt(255);
String ip = "192.168.2." + lastIPnum;
String msg = words[_rand.nextInt(words.length)];
try {
producer.send(new ProducerRecord<>(topic, ip, msg));
System.out.println("Sent message: (" + ip + ", " + msg + ")");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
Producer producer = new Producer(Constants.TOPIC, args);
producer.producerMsg();
//If I write Thread.sleep(1000),It will not work!!!!!!!!!!!!!!!!!!!!
Thread.sleep(2000);
}
}
欣赏
答案 0 :(得分:0)
您可以显示用于配置Producer的道具吗?我只是猜测它可能......
在producerMsg()中,您使用异步方式来使用生成器,所以只需要生成器.send(),这意味着将消息放入内部缓冲区以生成稍后将发送的批处理。生产者有一个内部线程从缓冲区获取并发送批处理。也许只有1000毫秒不足以达到生产者真正发送消息的条件(参见batch.size和linger.ms),主应用程序结束,生产者死亡而不发送消息。给它更多的时间(2000毫秒),它的工作原理。顺便说一句,我没有尝试过代码。
所以理由似乎是你的:
props.put("linger.ms", 1000);
与你的睡眠相匹配。因此,生产者将在1000毫秒后开始发送消息,因为批次尚未满(batch.size为16 MB)。同时,主线程在休眠1秒后结束,并且生产者不发送消息。你必须使用较低的linger.ms时间。