Kafka的消息订阅

巅峰迎来虚伪的拥护,黄昏见证真正的信徒。

在介绍kafka之前,先来了解下消息队列

一、消息队列(Message Queue)

1、概述:

消息队列顾名思义就是存储消息的队列,也就是在传输过程中保存消息的容器。同时消息队列是分布式系统中重要的组件。比如,我们为了分析某个网站的用户行为,我们就需要记录下来用户的访问日志,一条条日志,一条条消息,然后把这些都存储到消息队列中。

消息队列的出现主要是为了解决应用的耦合、异步处理等问题。

那我们现在使用比较多的消息队列有RabbitMQ、ActiveMQ、ZeroMQ、MetaMq等,但很多时候消息队列不是一个永久性当然我们这次要介绍的Kafak也是属于消息队列的。

2、 消息队列应用的场景
  • 异步处理
  • 应用耦合
  • 限流削峰
  • 消息驱动的系统
3、消息队列的模式
  • 点对点模式

  • 发布订阅模式

二、Kafka

1、概述:

kafka是一个分布式的、支持分区的(patition)、多副本的,是一个基于zookeeper协调的分布式消息系统。

2、kafka的特性
  • 高吞吐量、低延迟
  • 可拓展性
  • 持久性、可靠性
  • 容错性
  • 高并发

3、生产者程序的开发

1、创建一个生产者对象KafkaProducer
2、调用send方法发送消息(ProducerRecord,封装是Key-value键值对)
3、调用Future.get表示等待服务端的响应。
4、关闭生产者

  • bootstrap.servers:kafka的服务器地址。
  • acks:表示当生产者生产数据到kafka中,kafka会以什么样的策略返回。
  • key.serializer:kafka的消息是以可以、value键值对存储的,而且生产者生产的消息是在网络上传到的,这里指的就是StringSerializer方式,就是以字符创方式发送的(其他的一些序列化框架:Goole ProtoBuf\Avro)
  • value.serializer:同上
public class KafkaProduceTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        创建用于 连接kafka的properties的配置
        Properties props=new Properties();
        props.put("bootstrap.servers","localhost:9092");
        props.put("acks","all");  					props.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");
//        创建一个生产者对象
        KafkaProducer<String, String> KafkaProducer = new KafkaProducer<String, String>(props);
//        发送1-100的消息到指定topic
        for (int i=0;i<100;i++){
//            构建一条消息。直接NEW produceRcord
            ProducerRecord<String, String> producerRecord= new ProducerRecord<String, String>("test", null, i + "");
            Future<RecordMetadata> future = KafkaProducer.send(producerRecord);
//            调用future的get方法等待响应
            future.get();
            System.out.println("第"+i+"条消息写入成功!");
        }
//        关闭生产者
        KafkaProducer.close();

    }

4、消费者程序的开发

  • group.id :消费者组的概念,可以在一个消费者组中包含多个消费者,如果若干个group.id是一样的,表示他们在一个组中,一个消费者者是共同消费kafka中topic的数据。
  • kafka是一种拉消息模式的消息队列,在消费者中会有一个offset,表示从哪条消息开始拉取数据。
  • kafkaConsumer.poll:kafka的消费者API是一批一批数据的拉取。
public class KafkaConsumerTest {
    public static void main(String[] args) {
//        创建kafka消费者配置
        Properties props=new Properties();
        props.setProperty("bootstrap.servers","localhost:9092");
//        消费者组(可以使用消费者组将若干个消费者组织到一起,)共同消费kafka中topic的数据。
//        每一个消费者需要指定一个消费者组,如果消费者组的组名是一样,表示这几个消费者是一个组中的
        props.setProperty("group.id","test");
//        自动提交offest
        props.setProperty("enable.auto.commit","true");
//        自动提交offest的时间间隔
        props.setProperty("auto.commit.interval.ms","1000");
//        拉取key、value数据
        props.setProperty("key.deserializer","org.apache.kafka.common.serialization.StringDeserializer");
        props.setProperty("value.deserializer","org.apache.kafka.common.serialization.StringDeserializer");

//                创建kafka消费者
        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<>(props);
//        订阅要消费的主题,
//        指定消费者是从哪个topic中拉取数据
        kafkaConsumer.subscribe(Arrays.asList("test"));
//        使用一个whil循环,不断的从kafka中的topic中拉取数据
        while (true){
            ConsumerRecords<String, String> consumerRecords = kafkaConsumer.poll(Duration.ofSeconds(5));
//            将记录的(record)中的offest  、key、value都打印出来
            for (ConsumerRecord<String, String> consumerRecord : consumerRecords) {
//                主题
                String topic = consumerRecord.topic();
//                offest:这条消息处于kafka分区中的哪个位置
                long offset = consumerRecord.offset();
//                key/value
                String key = consumerRecord.key();
                String value = consumerRecord.value();
                System.out.println(" topic: "+ topic +" offset: "+ offset +" key: "+ key +" value: "+ value);

            }
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

至此y

无论你在哪里,我都在这里

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值