前言
kafka 是一个消息队列产品,基于 Topic partitions 的设计,能达到非常高的消息发送处理性能。Spring 创建了一个项目 Spring-kafka,封装了 Apache 的 Kafka-client,用于在 Spring 项目里快速集成 kafka。除了简单的收发消息外,Spring-kafka 还提供了很多高级功能,下面我们就来一一探秘这些用法。
简单集成
引入依赖
-
<dependency>
-
<groupId>org.springframework.kafka</groupId>
-
<artifactId>spring-kafka</artifactId>
-
<version>2.2.6.RELEASE</version>
-
</dependency>
添加配置
-
spring.kafka.producer.bootstrap-servers=127.0.0.1:9092
测试发送和接收
-
/**
-
* @author: kl @kailing.pub
-
* @date: 2019/5/30
-
*/
-
@SpringBootApplication
-
@RestController
-
public class Application {
-
-
private final Logger logger = LoggerFactory.getLogger(Application.class);
-
-
public static void main(String[] args) {
-
SpringApplication.run(Application.class, args);
-
}
-
-
@Autowired
-
private KafkaTemplate<Object, Object> template;
-
-
@GetMapping("/send/{input}")
-
public void sendFoo(@PathVariable String input) {
-
this.template.send("topic_input", input);
-
}
-
@KafkaListener(id = "webGroup", topics = "topic_input")
-
public void listen(String input) {
-
logger.info("input value: {}" , input);
-
}
-
}
启动应用后,在浏览器中输入:http://localhost:8080/send/kl。就可以在控制台看到有日志输出了:input value: "kl"。基础的使用就这么简单。发送消息时注入一个 KafkaTemplate,接收消息时添加一个 @KafkaListener 注解即可。
Spring-kafka-test 嵌入式 Kafka Server
不过上面的代码能够启动成功,前提是你已经有了 Kafka Server 的服务环境,我们知道 Kafka 是由 Scala + Zookeeper 构建的,可以从官网下载部署包在本地部署。但是,我想告诉你,为了简化开发环节验证 Kafka 相关功能,Spring-Kafka-Test 已经封装了 Kafka-test 提供了注解式的一键开启 Kafka Server 的功能,使用起来也是超级简单。本文后面的所有测试用例的 Kafka 都是使用这种嵌入式服务提供的。
引入依赖
-
<dependency>
-
<groupId>org.springframework.kafka</groupId>
-
<artifactId>spring-kafka-test</artifactId>
-
<version>2.2.6.RELEASE</version>
-
<scope>test</scope>
-
</dependency>
启动服务
下面使用 Junit 测试用例,直接启动一个 Kafka Server 服务,包含四个 Broker 节点。
-
@RunWith(SpringRunner.class)
-
@SpringBootTest(classes = ApplicationTests.class)
-
@EmbeddedKafka(count = 4,ports = {9092,9093,9094,9095})
-
public class ApplicationTests {
-
@Test
-
public void contextLoads()throws IOException {
-
System.in.read();
-
}
-
}
如上:只需要一个注解 @EmbeddedKafka 即可,就可以启动一个功能完整的 Kafka 服务,是不是很酷。默认只写注解不加参数的情况下,是创建一个随机端口的 Broker,在启动的日志中会输出具体的端口以及默认的一些配置项。不过这些我们在 Kafka 安装包配置文件中的配置项,在注解参数中都可以配置,下面详解下 @EmbeddedKafka 注解中的可设置参数 :
-
value:broker 节点数量
-
count:同 value 作用一样,也是配置的 broker 的节点数量
-
controlledShutdown:控制关闭开关,主要用来在 Broker 意外关闭时减少此 Broker 上 Partition 的不可用时间
Kafka 是多 Broker 架构的高可用服务,一个 Topic 对应多个 partition,一个 Partition 可以有多个副本 Replication,这些 Replication 副本保存在多个 Broker,用于高可用。但是,虽然存在多个分区副本集,当前工作副本集却只有一个,默认就是首次分配的副本集【首选副本】为 Leader,负责写入和读取数据。当我们升级 Broker 或者更新 Broker 配置时需要重启服务,这个时候需要将 partition 转移到可用的 Broker。下面涉及到三种情况
-
直接关闭 Broker:当 Broker 关闭时,Broker 集群会重新进行选主操作,选出一个新的 Broker 来作为 Partition Leader,选举时此 Broker 上的 Partition 会短时不可用
-
开启 controlledShutdown:当 Broker 关闭时,Broker 本身会先尝试将 Leader 角色转移到其他可用的 Broker 上
-
使用命令行工具:使用 bin/kafka-preferred-replica-election.sh,手动触发 PartitionLeader 角色转移
-
ports:端口列表,是一个数组。对应了 count 参数,有几个 Broker,就要对应几个端口号
-
brokerProperties:Broker 参数设置,是一个数组结构,支持如下方式进行 Broker 参数设置:
-
@EmbeddedKafka(brokerProperties = {"log.index.interval.bytes = 4096","num.io.threads = 8"})
-
okerPropertiesLocation:Broker 参数文件设置
功能同上面的 brokerProperties,只是 Kafka Broker 的可设置参数达 182 个之多,都像上面这样配置肯定不是最优方案,所以提供了加载本地配置文件的功能,如:
-
@EmbeddedKafka(brokerPropertiesLocation = "classpath:application.properties")
创建新的 Topic
默认情况下,如果在使用 KafkaTemplate 发送消息时,Topic 不存在,会创建一个新的 Topic,默认的分区数和副本数为如下 Broker 参数来设定