手拉手springboot整合kafka发送消息

|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 环境介绍 ||
| 技术栈 | ++springboot+mybatis-plus+mysql+rocketmq++ |
| 软件 | 版本 |
| mysql | 8 |
| IDEA | IntelliJ IDEA 2022.2.1 |
| JDK | 17 |
| Spring Boot | 3.1.7 |
| kafka | 2.13-3.7.0 |

创建topic时,若不指定topic的分区(Partition主题分区数)数量使,则默认为1个分区(partition)

springboot加入依赖kafka

java 复制代码
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>

加入spring-kafka依赖后,springboot自动装配好kafkaTemplate的Bean

application.yml配置连接kafka

java 复制代码
spring:
kafka:
bootstrap-servers: 192.168.68.133:9092

生产者

发送消息

java 复制代码
@Resource
private KafkaTemplate<String,String> kafkaTemplate;

@Test
void kafkaSendTest(){
kafkaTemplate.send("kafkamsg01","hello kafka");
}

消费者

接收消息

java 复制代码
@Component
public class KafkaConsumer {

@KafkaListener(topics = {"kafkamsg01","test"},groupId = "123")
public void consume(String message){
System.out.println("接收到消息:"+message);
}

}

若没有配置groupid

Failed to start bean 'org.springframework.kafka.config.internalKafkaListenerEndpointRegistry'; nested exception is java.lang.IllegalStateException: No group.id found in consumer config, container properties, or @KafkaListener annotation; a group.id is required when group management is used.

java 复制代码
@Component
public class KafkaConsumer {

@KafkaListener(topics = {"kafkamsg01","test"},groupId = "123")
public void consume(String message){
System.out.println("接收到消息:"+message);
}

}

想从第一条消息开始读取(若同组的消费者已经消费过该主题,并且kafka已经保存了该消费者组的偏移量,则设置auto.offset.reset设置为earliest不生效,需要手动修改偏移量或使用新的消费者组)

application.yml需要将auto.offset.reset设置为earliest

spring:

kafka:

bootstrap-servers: 192.168.68.133:9092

consumer:

auto-offset-reset: earliest

Earliest:将偏移量重置为最早的偏移量

Latest: 将偏移量重置为最新的偏移量

None: 没有为消费者组找到以前的偏移量,向消费者抛出异常

Exception: 向消费者抛出异常

重置消费者组偏移量

./kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --group 123 --topic kafkamsg01 --reset-offsets --to-earliest --execute

重置完成

Spring-kafka生产者发送消息

.send与sendDefault()方法都返回CompletableFuture<String<k,v>>;

CompletableFuture类用于异步编程,表示异步计算结果。该特征使得调用者不必等待操作完成就可以继续执行其他任务,从而提高引用的响应速度和吞吐量

java 复制代码
@Resource
private KafkaTemplate<String,String> kafkaTemplate;

@Test
void kafkaSendTest(){
kafkaTemplate.send("kafkamsg01","hello kafka");
}

发送Message

java 复制代码
@Test
void kafkaSendMessageTest1(){
//通过构建器模式创建Message
Message<String> message = MessageBuilder.withPayload("hello kafka send message")
.setHeader(KafkaHeaders.TOPIC,"kafkamsg01")
.build();
kafkaTemplate.send(message);
}

SendProducerRecord

String topic, Integer partition, Long timestamp, K key, V value, Iterable<Header> headers

java 复制代码
@Test
void kafkaSendProducerRecordTest1() {
//参数 String topic, Integer partition, Long timestamp, K key, V value, Iterable<Header> headers
Headers headers = new RecordHeaders();
headers.add("msg","123".getBytes(StandardCharsets.UTF_8));
ProducerRecord<String,String> record = new ProducerRecord(
"kafkaTopic01",
0,
System.currentTimeMillis(),
"key",
"hello kafka send message");
kafkaTemplate.send(record);
}

默认主题发送消息

yml配置默认主题

template:

default-topic: default-topic

java 复制代码
@Test
void kafkaSendDefaultTest01(){
kafkaTemplate.sendDefault(0,System.currentTimeMillis(),"key01","hello ");
}

发送Object消息

序列化默认为String

java 复制代码
@Resource
private KafkaTemplate<String,Object> kafkaTemplate1;
@Test
void kafkaSendObject(){
MessageM messageM =MessageM.builder().userID(123).sn("xo1111").desc("测试").build();
//分区是null,kafka自行决定消息发送到哪个分区
kafkaTemplate1.sendDefault(null,System.currentTimeMillis(),"key01",messageM);
}

Replica副本

Replica副本:为实现备份公共,保证集群中的某个节点发生故障时,确保节点上的partition数据不丢失,且kafka仍然能够正常运行。

Replica副本分为leader Replica和Follower Replica

leader:每个分区多个副本中的主副本,生产者发送数据以及消费者消费数据都来说leader副本。

Follower:每个分区多个副本中的从副本,实时从leader副本中同步数据,保持和leader副本数据同步,当leader副本发送故障,节点中的某个Follower副本会变成新的leader副本。

指定topic分区及副本

  • 通过脚本命令创建topic时指定分区和副本

--replication-factor需要小于等于节点个数,不能为0,默认为1

--replication-factor 1表示只有本身

--replication-factor 2 表示本身+副本

bash 复制代码
./kafka-topics.sh --create --topic testTopic --partitions 3 --replication-factor 2 --bootstrap-server 127.0.0.1:9092
  • 代码指定分区及副本

配置bean

java 复制代码
@Configuration
public class kafkaConfig {

    @Bean
    public NewTopic newTopic(){
        return new NewTopic("topic1", 3, (short) 2);
    }
}

分区策略

Kafak根据不同策略将数据分配到不同的分区

  • 默认分配策略:BuiltlnPartitioner
  • 轮询分配策略:RoundRobinPartitioner 接口:Partitioner
java 复制代码
@Configuration
public class kafkaConfig {

    //读取application.yml   bootstrap-servers
    @Value("${spring.kafka.bootstrap-servers}")
    private String bootstrapServers;

    //读取application.yml   bootstrap-servers
    @Value("${spring.kafka.producer.value-serializer}")
    private String valueSerializer;

    @Value("${spring.kafka.producer.key-serializer}")
    private String keySerializer;

    @Bean
    public KafkaTemplate<String,?> kafkaTemplate(){
        return new KafkaTemplate<>(producerFactory());
    }

    public Map<String,Object> producerConfigs(){
        Map<String,Object> props = new HashMap<>();
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,bootstrapServers);
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,valueSerializer);
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,keySerializer);
        props.put(ProducerConfig.PARTITIONER_CLASS_CONFIG, RoundRobinPartitioner.class);
        return props;
    }

    /**
     * 生产者工厂
     * @return
     */
    public ProducerFactory<String,?> producerFactory(){
        return new DefaultKafkaProducerFactory<>(producerConfigs());
    }

}
  • 手动指定
  • 自定义策略:自定义类实现Partitioner接口;

Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这种动作(网页,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。

相关推荐
darkdragonking31 分钟前
OpenEuler 22.03 不依赖zookeeper安装 kafka 3.3.2集群
kafka
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭9 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
AskHarries11 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
isolusion12 小时前
Springboot的创建方式
java·spring boot·后端
Yvemil713 小时前
《开启微服务之旅:Spring Boot Web开发举例》(一)
前端·spring boot·微服务
saynaihe14 小时前
安全地使用 Docker 和 Systemctl 部署 Kafka 的综合指南
运维·安全·docker·容器·kafka
星河梦瑾14 小时前
SpringBoot相关漏洞学习资料
java·经验分享·spring boot·安全
计算机学长felix15 小时前
基于SpringBoot的“交流互动系统”的设计与实现(源码+数据库+文档+PPT)
spring boot·毕业设计
.生产的驴15 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven
顽疲15 小时前
springboot vue 会员收银系统 含源码 开发流程
vue.js·spring boot·后端