发送消息

-- Start

在上个例子中(有多个broker的例子),我们使用了脚本来发送消息,来吧,让我们来自己写点代码来发送消息。首先还是按照上个例子,先启动 ZooKeeper 和 启动 Kafka borker。

1. 创建 Maven 工程

首先在 Eclipse 中创建一个 Maven 工程,如果你还不了解如何创建 Maven 工程,请点击此处。创建 Maven 工程后,把下面的依赖添加到你的 POM 中。

<dependency>
	<groupId>org.apache.kafka</groupId>
	<artifactId>kafka-clients</artifactId>
	<version>0.8.2.2</version>
</dependency>


2. 编写发送消息代码

下面的代码发送消息到 topic1 中。

package com.shangbo.app.Kafka;

import java.util.Properties;
import java.util.concurrent.Future;

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.clients.producer.RecordMetadata;

public class KafkaTest {
	
	public static void main(String[] args) throws Exception {
		// <String, String>, 第一个String指的是消息 key 的类型. 第二个String 指的是消息的类型
		KafkaProducer<String, String> producer = new KafkaProducer<String, String>(producerConfig());

		// 发送消息到 topic1
		ProducerRecord msg1 = new ProducerRecord("topic1", "This is test message1");
		Future<RecordMetadata> sendOut1 = producer.send(msg1); // 异步发送消息
		RecordMetadata msg1Metadata = sendOut1.get(); // 得到返回的结果
		System.out.println("The message sent to topic:" + msg1Metadata.topic() + ", partition:" + msg1Metadata.partition() + 
				", offset:" + msg1Metadata.offset()); // 每条消息在log中都有一个唯一编号 offset, 我们可以通过 offset 来获取指定你想要的消息

		// 发送消息到 topic1, partition 0,同时指定消息键和值
		ProducerRecord msg2 = new ProducerRecord("topic1", 0, "message key", "message value");
		Future<RecordMetadata> sendOut2 = producer.send(msg2); // 异步发送消息
		RecordMetadata msg2Metadata = sendOut2.get(); // 得到返回的结果
		System.out.println("The message sent to topic:" + msg2Metadata.topic() + ", partition:" + msg2Metadata.partition() + 
				", offset:" + msg2Metadata.offset());
	}

	// 配置信息应该保存在 xml 配置文件中
	private static Properties producerConfig() {
		Properties props = new Properties();

		// 指定要连接的 broker, 不需要列出所有的 broker,但建议至少列出 2 个,以防某个 broker 挂了
		props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092,localhost:9093,localhost:9094");

		// 如果连接失败,重试之前的等待时间,默认 10 毫秒
		props.put(ProducerConfig.RECONNECT_BACKOFF_MS_CONFIG, "10");

		// 第一次连接时,获取 topic 超时时间,默认值 60000 毫秒(1分钟)
		props.put(ProducerConfig.METADATA_FETCH_TIMEOUT_CONFIG, "60000");

		// topic 有可能改变,指定刷新 topic 的时间,默认 300000 毫秒(5分钟)
		props.put(ProducerConfig.METADATA_MAX_AGE_CONFIG, "300000");

		// 指定是否需要 broker 反馈消息已经收到
		// 0 表示不需要 broker 反馈
		// 1 是默认值,表示 leader broker 收到了消息
		// all 表示 所有 broker 都收到了消息
		// 也支持 2,3,4.. 等,基于你的 replication-factor 数量
		props.put(ProducerConfig.ACKS_CONFIG, "1");

		// 如果没有得到反馈消息的数量超过下面的配置,则阻塞
		props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "100");

		// 等待 broker 反馈消息的时间,超时报错,默认值是 30000 毫秒(30秒)
		props.put(ProducerConfig.TIMEOUT_CONFIG, "30000");

		// 如果发送消息失败,重试的次数,默认0 次,重试可能导致消息顺序不一致
		props.put(ProducerConfig.RETRIES_CONFIG, "0");

		// 如果发送消息失败,重试等待时间,默认值是 100 毫秒
		props.put(ProducerConfig.RETRY_BACKOFF_MS_CONFIG, "100");

		// 发送消息时使用内存大小,默认 33554432 bytes (32M)
		props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, "33554432");

		// kafka 是按批次发送消息,下面指定每批次消息的内存大小,默认值 16384 bytes(16K)
		props.put(ProducerConfig.BATCH_SIZE_CONFIG, "16384");

		// 接收数据时 TCP 内存大小,默认值 32768 bytes(32K)
		props.put(ProducerConfig.RECEIVE_BUFFER_CONFIG, "32768");

		// 发送数据时 TCP 内存大小,默认值 131072 bytes(128K)
		props.put(ProducerConfig.SEND_BUFFER_CONFIG, "131072");

		// kafka 是按批次发送消息,如果消息没有达到一个批次,最大等待时间。类似公交车 10 分钟一班,满员即发。
		props.put(ProducerConfig.LINGER_MS_CONFIG, "0");

		// 如果内存耗尽,true(默认值) 阻塞,false 抛出错误
		props.put(ProducerConfig.BLOCK_ON_BUFFER_FULL_CONFIG, "true");

		// kafka 是按批次发送消息,下面指定最大消息条数,默认值是 1048576 条
		props.put(ProducerConfig.MAX_REQUEST_SIZE_CONFIG, "1048576");

		// 指定是否压缩,none 不压缩(默认值),gzip,snappy
		props.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, "none");

		// 用来追踪客户端请求,默认值是 ""
		props.put(ProducerConfig.CLIENT_ID_CONFIG, "shangbo-test");

		// 因为消息要跨 JVM 传输,所以需要指定指定序列化器,注意序列化器要和消息的格式相符
		props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");

		// 消息 key 序列化器
		props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");

		// ProducerConfig.METRIC_REPORTER_CLASSES_CONFIG "metric.reporters"
		// ProducerConfig.METRICS_NUM_SAMPLES_CONFIG "metrics.num.samples"
		// ProducerConfig.METRICS_SAMPLE_WINDOW_MS_CONFIG
		// "metrics.sample.window.ms"

		return props;
	}
}

-- 更多参见:Kafka 精萃
-- 声 明:转载请注明出处
-- Last Edited on 2014-10-13
-- Written by ShangBo on 2014-09-03
-- End

你可能感兴趣的:(source,open)