spring-boot-route(十四)整合Kafka

简介: kafka是用Scala和Java语言开发的,高吞吐量的分布式消息中间件。高吞吐量使它在大数据领域具有天然的优势,被广泛用来记录日志。

在上一章中SpringBoot整合RabbitMQ,已经详细介绍了消息队列的作用,这一种我们直接来学习SpringBoot如何整合kafka发送消息。

kafka简介

kafka是用Scala和Java语言开发的,高吞吐量的分布式消息中间件。高吞吐量使它在大数据领域具有天然的优势,被广泛用来记录日志。

kafka架构分析

注1:图中的红色箭头表示消息的流动过程,蓝色表示分区备份,绿色表示kafka集群注册到zookeeper。

注2:在kafka0.9版本之前,消费者消费消息的位置记录在zookeeper中,在0.9版本之后,消费消息的位置记录在kafka的一个topic上。

kafka名词简介

  1. Producer:消息生产者
  2. Consumer:消息消费者
  3. Consumer Group(CG):消费者组,一个topic可以有多个CG,每个Partition只会把消息发送给GG中的一个Consumer
  4. Broker:一台kafka服务器就是一个broker,一个broker有多个topic
  5. Topic:消息主题,消息分类,可看作队列
  6. Partition:分区,为了实现扩展,一个大的topic可能分布到多个broker上,一个topic可以分为多个partition,partition中的每条消息都会被分配一个有序的id(offset),每个partiton中的消息是有序的。
  7. Offset:kafka的存储文件都是按照offset.kafka来命名的,方便查找,第一个offset为0000000000.kafka。
  8. Leader:分区具有被备份,主分区
  9. Follower:从分区

1. 生产者分区策略

  1. 指定分区。
  2. 没有指定分区但有key值,将key的hash值与当前topic的分区个数进行取余得到分区。
  3. 如果既没有指定分区又没有指定key,第一次调用时随机生成一个整数(以后调用每次在这个整数上自增),将这个随机数与该topic的分区数取余得到分区。

2. 消息可靠性问题

采用ack确认机制来保证消息的可靠性。

kafka在发送消息后会同步到其他分区副本,等所有副本都接收到消息后,kafka才会发送ack进行确认。采用这种模式的劣势就是当其中一个副本宕机后,则消息生产者就不会收到kafka的ack。

kafka采用ISR来解决这个问题。

ISR:Leader维护的一个和leader保持同步的follower集合。

当ISR中的folower完成数据同步之后,leader就会向follower发送ack,如果follower长时间未向leader同步数据,则该follower就会被踢出ISR,该时间阀值的设置参数为replica.lag.time.max.ms,默认时间为10s,leader发生故障后,就会从ISR中选举新的leader。

注:本文所讲的kafka版本为0.11,在0.9版本以前成为ISR还有一个条件,就是同步消息的条数。

ack参数配置

0:生产者不等待broker的ack。

1:leader分区接收到消息向生产者发送ack。

-1(all):ISR中的leader和follower同步成功后,向生产者发送ack。

3. 消息一致性问题

假如leader中有10条消息,向两个follower同步数据,follower A同步了8条,follower B同步了9条。这时候leader宕机了,follower A和follower B中的消息是不一致的,剩下两个follower就会重新选举出一个leader。

  • LEO(log end offset):每个副本的最后一个offset
  • HW(high watermark):所有副本中最小的offset

为了保证数据的一致性,所有的follower会将各自的log文件高出HW的部分截掉,然后再从新的leader中同步数据。

4. 消息重复性问题

在kafka0.11版本中引入了一个新特性:幂等性。启用幂等性后,ack默认为-1。将生产者中的enable.idompotence设置为true,即启用了幂等性。

开启幂等性的Producer在初始化的时候会被分配一个PID,发往同一Partition的消息会附带Sequence Number。Broker端会对<PID,Partition,SeqNumber>做缓存,当具有相同主键的消息提交时,Broker只会缓存一条。但是每次重启PID就会发生变化,因此只能保证一次会话同一分区的消息不重复。

5. 消费者组分区分配策略

kafka有两种分配策略,一种是RoundRobin,另一种是Range

RoundRobin是按照消费者组以轮询的方式去给消费者分配分区的方式,前提条件是消费者组中的消费者需要订阅同一个topic。

Range是kafka默认的分配策略,它是通过当前的topic按照一定范围来分配的,假如有3个分区,消费者组有两个消费者,则消费者A去消费1和2分区,消费者B去消费3分区。

6. 消费者offset维护

Kafka 0.9 版本之前,consumer默认将offset保存在zookeeper中,0.9 版本开始,offset保存在kafka的一个内置topic中,该topic为_consumer_offsets

7. 生产者事务

为了实现跨分区会话的事务,需要引入一个全局唯一的Tracscation ID,并将Producer 获得的PID与之绑定。这样当Producer重启后就可以通过正在进行的Transaction ID获得原来的PID。

为了管理Transcation ID,kafka引入了一个新的组件Transcation Coordinator。Producer就是通过和Transcation Coordinator交互获得Transction ID对应的任务状态。

Spring Boot 整合kafka

1. 引入kafka依赖

<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka</artifactId>
</dependency>

2. 配置kafka服务信息

spring:
  kafka:
    # kafka服务地址
    bootstrap-servers: 47.104.155.182:9092
    producer:
      # 生产者消息key序列化方式
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      # 生产者消息value序列化方式
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
    consumer:
      # 消费者组
      group-id: test-consumer-group
      # 消费者消息value反序列化方式
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      # 消费者消息value反序列化方式
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

3. 消费者

@Component
@Slf4j
@KafkaListener(topics = {"first-topic"},groupId = "test-consumer-group")
public class Consumer {

    @KafkaHandler
    public void receive(String message){
        
        log.info("我是消费者,我接收到的消息是:"+message);
    }
}

4. 生产者

@RestController
public class Producer {

    @Autowired
    private KafkaTemplate kafkaTemplate;

    @GetMapping("send")
    public void send(){

        String message = "你好,我是Java旅途";
        // 第一个参数 topic
        // 第二个参数 消息
        kafkaTemplate.send("first-topic",message);
    }
}

本文示例代码已上传至github,点个star支持一下!

Spring Boot系列教程目录

spring-boot-route(一)Controller接收参数的几种方式

spring-boot-route(二)读取配置文件的几种方式

spring-boot-route(三)实现多文件上传

spring-boot-route(四)全局异常处理

spring-boot-route(五)整合swagger生成接口文档

spring-boot-route(六)整合JApiDocs生成接口文档

spring-boot-route(七)整合jdbcTemplate操作数据库

spring-boot-route(八)整合mybatis操作数据库

spring-boot-route(九)整合JPA操作数据库

spring-boot-route(十)多数据源切换

spring-boot-route(十一)数据库配置信息加密

spring-boot-route(十二)整合redis做为缓存

spring-boot-route(十三)整合RabbitMQ

spring-boot-route(十四)整合Kafka

spring-boot-route(十五)整合RocketMQ

spring-boot-route(十六)使用logback生产日志文件

spring-boot-route(十七)使用aop记录操作日志

spring-boot-route(十八)spring-boot-adtuator监控应用

spring-boot-route(十九)spring-boot-admin监控服务

spring-boot-route(二十)Spring Task实现简单定时任务

spring-boot-route(二十一)quartz实现动态定时任务

spring-boot-route(二十二)实现邮件发送功能

spring-boot-route(二十三)开发微信公众号

spring-boot-route(二十四)分布式session的一致性处理

spring-boot-route(二十五)两行代码实现国际化

spring-boot-route(二十六)整合webSocket

目录
相关文章
|
28天前
|
消息中间件 Java Kafka
什么是Apache Kafka?如何将其与Spring Boot集成?
什么是Apache Kafka?如何将其与Spring Boot集成?
66 5
|
1月前
|
消息中间件 Java Kafka
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
44 1
|
4月前
|
消息中间件 开发框架 Java
掌握这一招,Spring Boot与Kafka完美融合,顺序消费不再是难题,让你轻松应对业务挑战!
【8月更文挑战第29天】Spring Boot与Kafka集成广泛用于处理分布式消息队列。本文探讨了在Spring Boot中实现Kafka顺序消费的方法,包括使用单个Partition或消息Key确保消息路由到同一Partition,并设置Consumer并发数为1以保证顺序消费。通过示例代码展示了如何配置Kafka Producer和Consumer,并自定义Partitioner。为确保数据正确性,还建议在业务逻辑中增加顺序校验机制。
187 3
|
4月前
|
消息中间件 Java Kafka
|
4月前
|
消息中间件 Java Kafka
|
4月前
|
消息中间件 安全 Java
Spring Boot 基于 SCRAM 认证集成 Kafka 的详解
【8月更文挑战第4天】本文详解Spring Boot结合SCRAM认证集成Kafka的过程。SCRAM为Kafka提供安全身份验证。首先确认Kafka服务已启用SCRAM,并准备认证凭据。接着,在`pom.xml`添加`spring-kafka`依赖,并在`application.properties`中配置Kafka属性,包括SASL_SSL协议与SCRAM-SHA-256机制。创建生产者与消费者类以实现消息的发送与接收功能。最后,通过实际消息传递测试集成效果与认证机制的有效性。
191 4
|
5月前
|
消息中间件 Java Kafka
spring boot 整合kafka
spring boot 整合kafka
68 8
|
4月前
|
消息中间件 Kafka Java
Spring 框架与 Kafka 联姻,竟引发软件世界的革命风暴!事件驱动架构震撼登场!
【8月更文挑战第31天】《Spring 框架与 Kafka 集成:实现事件驱动架构》介绍如何利用 Spring 框架的强大功能与 Kafka 分布式流平台结合,构建灵活且可扩展的事件驱动系统。通过添加 Spring Kafka 依赖并配置 Kafka 连接信息,可以轻松实现消息的生产和消费。文中详细展示了如何设置 `KafkaTemplate`、`ProducerFactory` 和 `ConsumerFactory`,并通过示例代码说明了生产者发送消息及消费者接收消息的具体实现。这一组合为构建高效可靠的分布式应用程序提供了有力支持。
122 0
|
4月前
|
消息中间件 Java Kafka
SpringBoot Kafka SSL接入点PLAIN机制收发消息
SpringBoot Kafka SSL接入点PLAIN机制收发消息
42 0
|
5月前
|
消息中间件 Java Kafka
Spring Boot与Apache Kafka Streams的集成
Spring Boot与Apache Kafka Streams的集成