简体   繁体   English

如何在 spring-boot 应用程序启动期间创建许多 kafka 主题?

[英]How can I create many kafka topics during spring-boot application start up?

I have this configuration:我有这个配置:

@Configuration
public class KafkaTopicConfig {

    private final TopicProperties topics;

    public KafkaTopicConfig(TopicProperties topics) {
        this.topics = topics;
    }

    @Bean
    public NewTopic newTopicImportCharge() {
        TopicProperties.Topic topic = topics.getTopicNameByType(MessageType.IMPORT_CHARGES.name());
        return new NewTopic(topic.getTopicName(), topic.getNumPartitions(), topic.getReplicationFactor());
    }

    @Bean
    public NewTopic newTopicImportPayment() {
        TopicProperties.Topic topic = topics.getTopicNameByType(MessageType.IMPORT_PAYMENTS.name());
        return new NewTopic(topic.getTopicName(), topic.getNumPartitions(), topic.getReplicationFactor());
    }

    @Bean
    public NewTopic newTopicImportCatalog() {
        TopicProperties.Topic topic = topics.getTopicNameByType(MessageType.IMPORT_CATALOGS.name());
        return new NewTopic(topic.getTopicName(), topic.getNumPartitions(), topic.getReplicationFactor());
    }
}

I can add 10 differents topics to TopicProperties .我可以向TopicProperties添加 10 个不同的主题。 And I don't want create each similar bean manually.而且我不想手动创建每个类似的 bean。 Does some way exist for create all topic in spring-kafka or only spring ?是否存在某种方法可以在spring-kafka或仅spring 中创建所有主题?

Use an admin client directly; 直接使用管理客户端; you can get a pre-built properties map from Boot's KafkaAdmin . 你可以从Boot的KafkaAdmin获得一个预建的属性映射。

@SpringBootApplication
public class So55336461Application {

    public static void main(String[] args) {
        SpringApplication.run(So55336461Application.class, args);
    }

    @Bean
    public ApplicationRunner runner(KafkaAdmin kafkaAdmin) {
        return args -> {
            AdminClient admin = AdminClient.create(kafkaAdmin.getConfig());
            List<NewTopic> topics = new ArrayList<>();
            // build list
            admin.createTopics(topics).all().get();
        };
    }
}

EDIT 编辑

To check if they already exist, or if the partitions need to be increased, the KafkaAdmin has this logic... 要检查它们是否已存在,或者是否需要增加分区, KafkaAdmin具有此逻辑...

private void addTopicsIfNeeded(AdminClient adminClient, Collection<NewTopic> topics) {
    if (topics.size() > 0) {
        Map<String, NewTopic> topicNameToTopic = new HashMap<>();
        topics.forEach(t -> topicNameToTopic.compute(t.name(), (k, v) -> t));
        DescribeTopicsResult topicInfo = adminClient
                .describeTopics(topics.stream()
                        .map(NewTopic::name)
                        .collect(Collectors.toList()));
        List<NewTopic> topicsToAdd = new ArrayList<>();
        Map<String, NewPartitions> topicsToModify = checkPartitions(topicNameToTopic, topicInfo, topicsToAdd);
        if (topicsToAdd.size() > 0) {
            addTopics(adminClient, topicsToAdd);
        }
        if (topicsToModify.size() > 0) {
            modifyTopics(adminClient, topicsToModify);
        }
    }
}

private Map<String, NewPartitions> checkPartitions(Map<String, NewTopic> topicNameToTopic,
        DescribeTopicsResult topicInfo, List<NewTopic> topicsToAdd) {

    Map<String, NewPartitions> topicsToModify = new HashMap<>();
    topicInfo.values().forEach((n, f) -> {
        NewTopic topic = topicNameToTopic.get(n);
        try {
            TopicDescription topicDescription = f.get(this.operationTimeout, TimeUnit.SECONDS);
            if (topic.numPartitions() < topicDescription.partitions().size()) {
                if (LOGGER.isInfoEnabled()) {
                    LOGGER.info(String.format(
                        "Topic '%s' exists but has a different partition count: %d not %d", n,
                        topicDescription.partitions().size(), topic.numPartitions()));
                }
            }
            else if (topic.numPartitions() > topicDescription.partitions().size()) {
                if (LOGGER.isInfoEnabled()) {
                    LOGGER.info(String.format(
                        "Topic '%s' exists but has a different partition count: %d not %d, increasing "
                        + "if the broker supports it", n,
                        topicDescription.partitions().size(), topic.numPartitions()));
                }
                topicsToModify.put(n, NewPartitions.increaseTo(topic.numPartitions()));
            }
        }
        catch (@SuppressWarnings("unused") InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        catch (TimeoutException e) {
            throw new KafkaException("Timed out waiting to get existing topics", e);
        }
        catch (@SuppressWarnings("unused") ExecutionException e) {
            topicsToAdd.add(topic);
        }
    });
    return topicsToModify;
}

Currently we can just use KafkaAdmin.NewTopics目前我们只能使用KafkaAdmin.NewTopics

Spring Doc 春季文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Spring-Boot中启动Main-Class? - How can I start a Main-Class in Spring-Boot? 如何在 Spring-Boot 的生产过程中覆盖 application.properties? - How to override application.properties during production in Spring-Boot? spring-boot应用程序无法启动 - spring-boot application fails to start 弹簧启动期间,tomcat数据源未检查有效连接? - tomcat datasource not checking for valid connection during spring-boot start up? 如何通过Spring-boot处理越来越多的STOMP主题 - How to handle growing number of STOMP topics with Spring-boot 我无法创建我的自定义 spring-boot 启动器 - I can't create my custom spring-boot starter 如何初始化 firebase 托管在谷歌应用引擎上的 spring-boot 应用程序 - How can I initialize firebase a spring-boot application hosted on google app-engine 为什么我可以使用 mvn spring-boot:run 启动我的应用程序而 IntelliJ run 不起作用? - Why can I start my application using mvn spring-boot:run while IntelliJ run doen´t work? 如何访问在Tomcat上部署的静态Spring-boot应用程序时解决此IlleagalstateException问题? - How can I fix this IlleagalstateException on accessing restful spring-boot application deployed on Tomcat? 如何在 Spring-boot 应用程序中获取上下文路径和 info.info? - How can I get context-path and info.info in a Spring-boot application?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM