• SpringBoot 整合 Spring-Kafka


    一、添加pom文件

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

    二、配置文件修改

    server:
      port: 8080
    
    logging:
      config: classpath:logback.xml
    
    spring:
      kafka:
        bootstrap-servers: 139.196.181.97:9092,139.196.181.97:9093,139.196.181.97:9094
    
        producer:
          # 消息重发的次数。 配置事务的话:如果用户显式地指定了 retries 参数,那么这个参数的值必须大于0
          retries: 1
          #一个批次可以使用的内存大小
          batch-size: 16384
          # 设置生产者内存缓冲区的大小。
          buffer-memory: 33554432
          # 键的序列化方式
          key-serializer: org.apache.kafka.common.serialization.StringSerializer
          # 值的序列化方式
          value-serializer: org.apache.kafka.common.serialization.StringSerializer
          #配置事务的话:如果用户显式地指定了 acks 参数,那么这个参数的值必须-1 all
          acks: all
          #事务id
          transaction-id-prefix: xdclass-tran-
    
        consumer:
          # 自动提交的时间间隔 在spring boot 2.X 版本是值的类型为Duration 需要符合特定的格式,如1S,1M,2H,5D
          auto-commit-interval: 1S
    
          # 该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理:
          auto-offset-reset: earliest
    
          # 是否自动提交偏移量,默认值是true,为了避免出现重复数据和数据丢失,可以把它设置为false,然后手动提交偏移量
          enable-auto-commit: false
    
          # 键的反序列化方式
          key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
          # 值的反序列化方式
          value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
    
        listener:
          #手工ack,调用ack后立刻提交offset
          ack-mode: manual_immediate
          #容器运行的线程数
          concurrency: 4

    三、发送消息

    private static final String TOPIC_NAME = "user.register.topic";
    
    @Autowired
    private KafkaTemplate<String, Object> kafkaTemplate;
    
    @GetMapping("/api/v1/{num}")
    public void sendMessage1(@PathVariable("num") String num) {
    
        kafkaTemplate.send(TOPIC_NAME, "这是一个消息,num=" + num).addCallback(success -> {
            String topic = success.getRecordMetadata().topic();
    
            int partition = success.getRecordMetadata().partition();
    
            long offset = success.getRecordMetadata().offset();
    
            System.out.println("发送成功:topic=" + topic + ", partition=" + partition + ",offset =" + offset);
    
        }, failure -> {
            System.out.println("发送消息失败:" + failure.getMessage());
        });
    }

    Kafka 从 0.11 版本开始引入了事务支持

    • 事务可以保证对多个分区写入操作的原子性
    • 操作的原子性是指多个操作要么全部成功,要么全部失败,不存在部分成功、部分失败的可能

    配置注意上面红色的字体

    /**
     * 注解方式的事务
     *
     * @param num
     */
    @GetMapping("/api/v1/tran1")
    @Transactional(rollbackFor = RuntimeException.class)
    public void sendMessage2(int num) {
        kafkaTemplate.send(TOPIC_NAME, "这个是事务消息 1 i=" + num);
        if (num == 0) {
            throw new RuntimeException();
        }
        kafkaTemplate.send(TOPIC_NAME, "这个是事务消息 2 i=" + num);
    }
    
    /**
     * 声明式事务
     *
     * @param num
     */
    @GetMapping("/api/v1/tran2")
    public void sendMessage3(int num) {
        kafkaTemplate.executeInTransaction(new KafkaOperations.OperationsCallback<String, Object, Object>() {
            @Override
            public Object doInOperations(KafkaOperations<String, Object> kafkaOperations) {
                kafkaOperations.send(TOPIC_NAME, "这个是事务消息 1 i=" + num);
    
                if (num == 0) {
                    throw new RuntimeException();
                }
                kafkaOperations.send(TOPIC_NAME, "这个是事务消息 2 i=" + num);
                return true;
            }
        });
    }

    四、消费消息代码

    @Component
    public class MQListener {
        @KafkaListener(topics = {"user.register.topic"}, groupId = "xdclass-gp3")
        public void onMessage(ConsumerRecord<?, ?> record, Acknowledgment ack,
                              @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
            System.out.println("消费消息:" + record.topic() + "----" + record.partition() + "----" + record.value());
            ack.acknowledge();
        }
    }
  • 相关阅读:
    Druid源码解析(六):PreparedStatementPool源码及使用场景分析 lcl
    PyScript:让Python在HTML中运行
    Java 16 新特性:record类
    Java 17 新特性:switch的模式匹配(Preview)
    基于阿里云 ASK 的 Istio 微服务应用部署初探
    Vue快速入门
    架构设计分析
    springbatch相关sql创建语句 mysql
    mysql多表关联时可能出错的地方,如搜索出的记录数据变少了。
    https://blog.csdn.net/hualusiyu/article/details/86498452?spm=1001.2014.3001.5502
  • 原文地址:https://www.cnblogs.com/jwen1994/p/14820902.html
Copyright © 2020-2023  润新知