闲聊kafka(三)

参考资料:《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();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值