1.概述
继上文在CentOS环境下安装kafka并进行消费者与生产者案例演示,本文将演示在CentOS环境下集群的构建。Kafka 本身支持两种模式的集群搭建:(1)多台机器构建的多机集群(2)单机上运行多个broker实例的集群。本文首先将构建单机多broker的集群,其次介绍搭建过程中可能遇到的一些问题以及解决方案,最后介绍在Springboot环境下连接kafka并向其中发送消息。
2.单机多broker集群搭建
2.1 修改server.properties
首先,在上文的基础上,修改server.properties的配置,具体操作如下:
vi config/server-2.properties
修改配置为:
broker.id=1
log.dirs=/root/kafka_2.12-2.5.0/data
listeners=PLAINTEXT://0.0.0.0:9092
advertised.listeners=PLAINTEXT://CentOSIP:9092
listeners设置为0.0.0.0是有原因的,如果设置为localhost,则后面在用springboot连接时,会报错,后面再细分析。server.properties主要修改成这样,CentOSIP是你所在的centos环境ip端口号。
2.2 设置不同broker的id
为了演示效果,这里将设置3个不同的broker,复制2份server.properties,并分别命名为server-2.properties和server-3.properties,然后分别修改对应配置,具体操作指令如下:
cp config/server.properties config/server-2.properties
修改server-2.properties的配置为:
broker.id=2
log.dirs=/root/kafka_2.12-2.5.0/data/kafka/logs-2
listeners=PLAINTEXT://0.0.0.0:9093
advertised.listeners=PLAINTEXT://192.168.222.131:9093
复制server.properties并命名为server-3.properties:
cp config/server.properties config/server-3.properties
修改server-3.properties的配置为:
broker.id=3
log.dirs=/root/kafka_2.12-2.5.0/data/kafka/logs-3
listeners=PLAINTEXT://0.0.0.0:9094
advertised.listeners=PLAINTEXT://192.168.222.131:9094
至此,主要的配置文件都已经修改完成。
2.3 分别启动对应分区server
启动三个shell命令窗口,在不同的窗口执行如下命令:
bin/kafka-server-start.sh config/server.properties
bin/kafka-server-start.sh config/server-2.properties
bin/kafka-server-start.sh config/server-3.properties
启动成功后结果如下:
2.4 启动消费者与生产者
分别启动三个shell窗口,用来执行以下启动生产者命令,启动命令如下:
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic demo
bin/kafka-console-producer.sh --broker-list localhost:9093 --topic demo
bin/kafka-console-producer.sh --broker-list localhost:9094 --topic demo
消费者启动完成后,再分别启动三个shell窗口,用来启动消费者,具体如下:
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic demo --from-beginning
bin/kafka-console-consumer.sh --bootstrap-server localhost:9093 --topic demo --from-beginning
bin/kafka-console-consumer.sh --bootstrap-server localhost:9094 --topic demo --from-beginning
因为订阅的是同一个主题,所以无论在哪个生产者里生产消息,所有的消费者都会获得内容。具体的案例如下:
3.springboot连接kafka并插入数据
3.1 引入pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
3.2 编写配置文件类KafkaProducerConfig
@Configuration
@EnableKafka
public class KafkaProducerConfig {
@Value("${spring.kafka.producer.bootstrap-servers}")
private String servers;
@Value("${spring.kafka.producer.retries}")
private int retries;
@Value("${spring.kafka.producer.batch.size}")
private int batchSize;
@Value("${spring.kafka.producer.linger}")
private int linger;
@Value("${spring.kafka.producer.buffer.memory}")
private int bufferMemory;
@Value("${spring.kafka.producer.key-serializer}")
private String keyDeserializer;
@Value("${spring.kafka.producer.value-serializer}")
private String valueDeserializer;
public Map<String, Object> producerConfigs() {
Map<String, Object> props = new HashMap<>();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, servers);
props.put(ProducerConfig.RETRIES_CONFIG, retries);
props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize);
props.put(ProducerConfig.LINGER_MS_CONFIG, linger);
props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, keyDeserializer);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, valueDeserializer);
return props;
}
public ProducerFactory<String, String> producerFactory() {
return new DefaultKafkaProducerFactory<>(producerConfigs());
}
@Bean
public KafkaTemplate<String, String> kafkaTemplate() {
return new KafkaTemplate<String, String>(producerFactory());
}
}
3.3 在application.properties中配置kafka信息
spring.kafka.producer.bootstrap-servers=CentOSIP:9092 //CentOSIP是你虚拟机的IP地址
spring.kafka.producer.retries=0
spring.kafka.producer.batch.size=4096
spring.kafka.producer.linger=1
spring.kafka.producer.buffer.memory=40960
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.consumer.bootstrap-servers=CentOSIP.9092
3.4 编写controller测试
测试方式可以根据个人喜好编写,也可以编写单元测试。
在postman中进行测试,发送信息如下:
在任意一个消费者shell窗口可以查看到发送的消息:
4.踩坑记录
4.1 server.properties的配置
在刚开始的配置文件中,我配置的listeners为:
listeners=PLAINTEXT://localhost:9093
于是在用程序发送消息时,总是报如下错误:
Connection to node -1 (192.168.212.131:9092) could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)
WARN [Producer clientId=console-producer] Connection to node -1 (192.168.212.131:9092) could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)
经过多方排查,才发现时ip配置的原因,在配置上述ip为0.0.0.0时,意味着接收所有机器对9092端口的访问,记得开启centos防火墙。
5.小结
kafka单机多broker案例只是演示一下,在生产中肯定是多台机器来构建集群,这样消息会有不同的副本存放到不同服务器上,只要不是大面积的服务器宕机,整个服务都将会是稳定的,单机一旦挂掉就G了。
6.参考文章
http://www.54tianzhisheng.cn/2018/01/04/Kafka/