1.执行kafka的相关jar包 kafka-clients
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.0.0</version>
</dependency>
使用的kafka版本要与虚拟机中搭建的kafka版本一致,kafka的运行过程整体可视为producer流程(生产)和consumer流程(消费)。
2.kafka的消息是通过以topic(主题)为载体进行数据传递,每个topic的消息都有不同的分区,这样一方面消息的存储就不会收到单一服务器存储空间大小的限制,另一方面消息的处理也可以在多个服务器上并行。
在使用kafka传递消息之前要先创建一个topic,命令行操作如下:
[root@hdp2 ~]# kafka-topics.sh --zookeeper 192.168.0.xxx:2181 --create --topic test01 --replication-factor 1 --partitions 12
Created topic "test01".
作者已经在/etc/profile中配置了kafka的环境变量,若没有配置,则需要在/bin目录下运行topic脚本,即"bin/kafka-topics.sh"
kafka中的topic都是通过zookeeper进行管理的,此处需要调用到zookeeper,后面即zookeeper所在节点的IP地址和端口号,节点的主机名也可以。
通过--create命令进行创建topic,replication指定创建topic的副本数,该副本数的配置要小于或等于你的集群的节点数,--partition 用于指定创建topic的分区数。
当topic创建完成时,在kafka-log目录下(server.properties文件中自己配置的)就会生成对应topic名称、及相应分区数目的文件,文件中存放的是.index文件和.log文件。index文件用于记录consumer在消费的offset(偏移量)的移动位置以及元数据,log文件主要记录的是数据。
3.命令行操作
producer命令行操作如下:
[root@hdp2 opt]# kafka-console-producer.sh \
--broker-list 192.168.100.155:9092 \
--topic test01
>
在">"后面输入发送的信息即可在consumer端查看到相关信息
consumer命令操作如下:
[root@hdp2 opt]# kafka-console-consumer.sh \
--bootstrap-server 192.168.100.155:9092 \
--topic test01
查看kafka内某topic的偏移量
kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list 192.168.100.155:9092 --topic test01
4.API操作
producer的API操作
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;
import java.util.Properties;
public class Producer1 {
public static void main(String[] args) {
//创建kafka生产者的配置文件信息对象
Properties pro = new Properties();
//kafka集群(--broker-list)的地址
pro.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"192.168.100.155:9092");
//ack应答类型,此处all相当于-1,即把所有的follow副本写完再返回应答
pro.put(ProducerConfig.ACKS_CONFIG,"all");
//当producer发送数据失败时,会进行重试,此处配置的是重试的次数
pro.put(ProducerConfig.RETRIES_CONFIG,1);
//prodeucer发送数据采用批量发送的形式,此处配置批量大小,默认为16K
//当发送信息累计超过该数值时,消息就会被发送
pro.put(ProducerConfig.BATCH_SIZE_CONFIG,16384);
//key,value的序列化类
pro.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
StringSerializer.class.getName());
pro.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
StringSerializer.class.getName());
//创建生产者对象
KafkaProducer kp = new KafkaProducer<>(pro);
//发送数据
for (int i = 0; i < 10; i++) {
ProducerRecord pr = new ProducerRecord("mytest","内容" + i);
kp.send(pr);
}
//关闭资源
kp.close();
}
}
consumer的API操作
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;
import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;
public class Consumer1 {
public static void main(String[] args) {
Properties p = new Properties();
p.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"192.168.100.155:9092");
//是否开启自动提交功能
p.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,"true");
//消费者组ID,即由当前消费者组消费信息
p.put(ConsumerConfig.GROUP_ID_CONFIG,"test");
//自动提交的时间间隔
p.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG,"1000");
//earliest消费模式:
//当各分区有已提交的offset时,从提交的offset处开始消费
//当没有提交的offset时,从头开始消费
p.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,"earliest");
//消费key,value的反序列化
p.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
p.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,StringDeserializer.class.getName());
//创建消费者对象
KafkaConsumer<String,String> kc = new KafkaConsumer<>(p);
//订阅消息
kc.subscribe(Arrays.asList("test01"));
while (true) {
ConsumerRecords<String,String> cr = kc.poll(Duration.ofMillis(1000));
for (ConsumerRecord<String,String> crs:cr) {
System.out.println(crs.value());
}
}
}
}