org.apache.kafka
kafka_
s
c
a
l
a
.
v
e
r
s
i
o
n
<
/
a
r
t
i
f
a
c
t
I
d
>
<
v
e
r
s
i
o
n
>
{scala.version}</artifactId> <version>
scala.version</artifactId><version>{kafka.version}
org.apache.zookeeper
zookeeper
org.slf4j
slf4j-log4j12
log4j
log4j
2.必要参数配置
见代码库:com.heima.kafka.chapter2.KafkaProducerAnalysis
public static Properties initConfig() {
Properties props = new Properties();
// 该属性指定 brokers 的地址清单,格式为 host:port。清单里不需要包含所有的 broker 地址,
// 生产者会从给定的 broker 里查找到其它 broker 的信息。——建议至少提供两个 broker 的信息,因为一旦其中一个宕机,生产者仍然能够连接到集群上。
props.put(“bootstrap.servers”, brokerList);
// 将 key 转换为字节数组的配置,必须设定为一个实现了 org.apache.kafka.common.serialization.Serializer 接口的类,
// 生产者会用这个类把键对象序列化为字节数组。
// ——kafka 默认提供了 StringSerializer和 IntegerSerializer、 ByteArraySerializer。当然也可以自定义序列化器。
props.put(“key.serializer”, “org.apache.kafka.common.serialization.StringSerializer”);
// 和 key.serializer 一样,用于 value 的序列化
props.put(“value.serializer”, “org.apache.kafka.common.serialization.StringSerializer”);
// 用来设定KafkaProducer对应的客户端ID,默认为空,如果不设置KafkaProducer会自动 生成一个非空字符串。
// 内容形式如:“producer-1”
props.put(“client.id”, “producer.client.id.demo”);
return props;
}
Properties props = initConfig();
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
// KafkaProducer<String, String> producer = new KafkaProducer<>(props,
// new StringSerializer(), new StringSerializer());
//生成 ProducerRecord 对象,并制定 Topic,key 以及 value
ProducerRecord<String, String> record = new ProducerRecord<>(topic, “hello, Kafka!”);
try {
// 发送消息
producer.send(record);
}
3.发送类型
发送即忘记
producer.send(record)
同步发送
//通过send()发送完消息后返回一个Future对象,然后调用Future对象的get()方法等待kafka响应
//如果kafka正常响应,返回一个RecordMetadata对象,该对象存储消息的偏移量
// 如果kafka发生错误,无法正常响应,就会抛出异常,我们便可以进行异常处理
producer.send(record).get();
异步发送
producer.send(record, new Callback() {
public void onCompletion(RecordMetadata metadata, Exception exception) {
if (exception == null) {
System.out.println(metadata.partition() + “:” + metadata.offset());
}
}
});
4.序列化器
消息要到网络上进行传输,必须进行序列化,而序列化器的作用就是如此。
Kafka 提供了默认的字符串序列化器(org.apache.kafka.common.serialization.StringSerializer
),还有整型(IntegerSerializer
)和字节数组(BytesSerializer
)序列化器,这些序列化器都实现了接口(org.apache.kafka.common.serialization.Serializer
)基本上能够满足大部分场景的需求。
5.自定义序列化器
见代码库:com.heima.kafka.chapter2.CompanySerializer
/**
- 自定义序列化器
*/
public class CompanySerializer implements Serializer {
@Override
public void configure(Map configs, boolean isKey) {
}
@Override
public byte[] serialize(String topic, Company data) {
if (data == null) {
return null;
}
byte[] name, address;
try {
if (data.getName() != null) {
name = data.getName().getBytes(“UTF-8”);
} else {
name = new byte[0];
}
if (data.getAddress() != null) {
address = data.getAddress().getBytes(“UTF-8”);
} else {
address = new byte[0];
}
ByteBuffer buffer = ByteBuffer. allocate(4 + 4 + name.length + address.length);
buffer.putInt(name.length);
buffer.put(name);
buffer.putInt(address.length);
buffer.put(address);
return buffer.array();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new byte[0];
}
@Override
public void close() {
}
}
- 使用自定义的序列化器
见代码库:com.heima.kafka.chapter2.ProducerDefineSerializer
public class ProducerDefineSerializer {
public static final String brokerList = “localhost:9092”;
public static final String topic = “heima”;
public static void main(String[] args) throws ExecutionException, InterruptedException {
Properties properties = new Properties();
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, CompanySerializer.class.getName());
// properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
// ProtostuffSerializer.class.getName());
properties.put(“bootstrap.servers”, brokerList);
KafkaProducer<String, Company> producer = new KafkaProducer<>(properties);
Company company = Company.builder().name(“kafka”) .address(“北京”).build();
// Company company = Company.builder().name(“hiddenkafka”)
// .address(“China”).telphone(“13000000000”).build();
ProducerRecord<String, Company> record = new ProducerRecord<>(topic, company);
producer.send(record).get();
}
}
6.分区器
本身kafka有自己的分区策略的,如果未指定,就会使用默认的分区策略:
Kafka根据传递消息的key来进行分区的分配,即hash(key) % numPartitions
。如果Key相同的话,那么就会分配到统一分区。
源代码org.apache.kafka.clients.producer.internals.DefaultPartitioner
分析
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
List partitions = cluster.partitionsForTopic(topic);
int numPartitions = partitions.size();
if (keyBytes == null) {
int nextValue = this.nextValue(topic);
List availablePartitions = cluster.availablePartitionsForTopic(topic);
if (availablePartitions.size() > 0) {
int part = Utils.toPositive(nextValue) % availablePartitions.size();
return ((PartitionInfo)availablePartitions.get(part)).partition();
} else {
return Utils.toPositive(nextValue) % numPartitions;
}
} else {
return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
}
}
- 自定义分区器见代码库
com.heima.kafka.chapter2.DefinePartitioner
总结
在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了
加入社区:https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0
码的学习等等都是需要掌握的,我也把这些知识点都整理起来了
[外链图片转存中…(img-VoZLwu6A-1725687153528)]
[外链图片转存中…(img-kgnaFLHa-1725687153529)]
加入社区:https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0