参考资料:《kafka权威指南》,作者薛命灯
----------------------------------------------------------------------我是分割线------------------------------------------------------------------------
1. kafka生产者-----》向kafka写入数据
发送消息主要有以下三种方式:
1.1 发送并忘记
特点:只管发送消息,并不关心消息是否发送成功(虽然大部分时候,消息都会发送成功),当发送失败的时候,生产者会尝试自动重发,这种方式可能会丢失一些消息。
代码示例:
first step:在服务端创建topic,进入任意一个节点的kafka根目录,执行:
bin/kafka-topics.sh --create --zookeeper dataServer-236:2181,dataServer-237:2181,dataServer-240:2181 --replication-factor 3 --partitions 3 --topic zhxTopic2
second step: java代码:
/**
* 生产者枚举类
* 官方参考文档:http://kafka.apache.org/documentation/#producerconfigs
*/
public enum ProducerConfigEnum {
BOOTSTRAP_SERVERS("192.168.1.236:9092,192.168.1.237:9092,192.168.1.240:9092", "kafka集群地址"),
KEY_SERIALIZER("org.apache.kafka.common.serialization.StringSerializer", "键的序列化方式"),
VALUE_SERIALIZER("org.apache.kafka.common.serialization.StringSerializer", "值的序列化方式");
private String value;
private String desc;
ProducerConfigEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
/**
* 生产者工具类
*/
public class ProduceUtil {
/**
* 获取kafka属性的Properties对象
* @return
*/
public static Properties getBasicKafkaProperties(){
Properties properties = new Properties();
properties.put("bootstrap.servers", ProducerConfigEnum.BOOTSTRAP_SERVERS.getValue());
properties.put("key.serializer", ProducerConfigEnum.KEY_SERIALIZER.getValue());
properties.put("value.serializer", ProducerConfigEnum.VALUE_SERIALIZER.getValue());
return properties;
}
}
/**
* 生产者接口
*/
public interface ZhxProducer {
/**
* 生产消息
*/
void produce();
}
/**
* 最简单的生产者:只发送消息,不关心是否发送成功
*/
public class SimpleProducer implements ZhxProducer {
public void produce() {
ProducerRecord<String, String> record = new ProducerRecord<String, String>("zhxTopic1", "hello!", "nice to see you.");
Producer producer = new KafkaProducer<String, String>(ProduceUtil.getBasicKafkaProperties());
try {
producer.send(record);
} catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
ZhxProducer zhxProducer = new SimpleProducer();
zhxProducer.produce();
}
}
1.2 同步发送
特点:使用send()方法发送消息,它会返回一个Future对象,我们可以调用起get()方法进行等待,就可以知道消息是否发送成功,进而可以根据实际业务做相应的处理。
代码示例:
/**
* 同步发送
*/
public class SyncProducer implements ZhxProducer {
public void produce() {
ProducerRecord<String, String> record = new ProducerRecord<String, String>("zhxTopic2", "ni hao.", "ni ye hao.");
Producer producer = new KafkaProducer<String, String>(ProduceUtil.getBasicKafkaProperties());
try {
//在这里,producer.send()方法返回一个Future对象,然后调用其get()方法等待kafka服务端的响应,如果服务器端返回错误,get()方法会抛出异常,
// 如果没有发生错误,我们会得到一个RecordMetadata对象,可以用谈来获取消息的偏移量
RecordMetadata recordMetadata = (RecordMetadata) producer.send(record).get();
System.out.println(recordMetadata);
} catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
SyncProducer syncProducer = new SyncProducer();
syncProducer.produce();
}
}
1.3 异步发送
特点:调用send()方法,并指定一个回调函数,服务器在返回响应时会自动调用该回调函数。
代码示例:
/**
* 异步发送消息
*/
public class UnSyncProducer implements ZhxProducer{
public void produce() {
ProducerRecord<String, String> record = new ProducerRecord<String, String>("zhxTopic2", "ni hao.", "ni ye hao.");
Producer producer = new KafkaProducer<String, String>(ProduceUtil.getBasicKafkaProperties());
try {
/*假设消息在应用程序和kafka集群之间一个来回需要10ms,如果同步发送每次都需要等待回应,那么发送100条消息就需要1秒,但如果只发送而不等待响应,那么发送
100条消息速度会快的多,大多数时候,对于生产者来说我们并不需要等待响应,尽管kafka会把目标主体、分区信息和消息偏移量发送回来,不过消息发送失败的时候,
我们需要捕获到异常并把它记录下来。*/
producer.send(record, new UnSyncProducerCallBack());
} catch (Exception e){
e.printStackTrace();
}
}
class UnSyncProducerCallBack implements Callback{
/*当消息发送成功的时候,该方法会被调用,exception为null,当发送失败的时候,exception会展示具体当错误信息,我们可以把错误信息记录下来,以后再做处理。*/
public void onCompletion(RecordMetadata metadata, Exception exception) {
System.out.println("回调---------------" + metadata);
System.out.println("回调---------------" + exception);
}
}
public static void main(String[] args) {
ZhxProducer zhxProducer = new UnSyncProducer();
zhxProducer.produce();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}