在java中将文件导入zookeeper

问题描述 投票:2回答:2

我正在使用zookeeper进行java微服务的配置管理。为此,我使用apache curator和java zookeeper客户端。

当微服务初始化时,如何将配置文件(属性或json)导入zookeeper?

java apache-zookeeper configuration-management apache-curator
2个回答
1
投票

如果你想在zookeeper中加载配置,你应该使用curator framework。请参阅post,了解如何使用curator框架。

yml文件有一些基本代码示例(对于spring配置):

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.BoundedExponentialBackoffRetry;
import org.springframework.core.io.ClassPathResource;
import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

@Slf4j
public class LoadConfigsInZoo {
    // base path of your config
    // /CONFIG_PATH/APP_NAME,CONTEXT_NAME
    private static final String BASE_PATH = "/configuration/myApp";
    private static final String ZOO_URL = "localhost:2181";
    private static final String CONFIG_FILE = "bootstrap.yml";
    private final ObjectMapper objectMapper = new ObjectMapper();

    public static void main(String[] args) throws IOException {
        new LoadConfigsInZoo().loadConfig();
    }

    private void loadConfig() throws IOException {
        BoundedExponentialBackoffRetry retryPolicy =
                new BoundedExponentialBackoffRetry(100, 300, 10);
        Map<String, String> config = flattenInnerProperties("", getContentOfYaml(CONFIG_FILE));

        try (CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString(ZOO_URL)
                .retryPolicy(retryPolicy)
                .build()) {
            client.start();
            for (Map.Entry<String, String> entry : config.entrySet()) {
                String path = createPath(BASE_PATH, entry.getKey());
                try {
                    log.info("Try add node with name '{}'", path);
                    client.create()
                            .creatingParentsIfNeeded()
                            .forPath(path, entry.getValue().getBytes());
                    log.info("Node with name '{}' was created", path);
                } catch (Exception e) {
                    log.warn("Unable to create node by path: {}, exception: {}", path, e.getMessage());
                }
            }
        }
    }

    // need your own implementation for properties/json files
    @SuppressWarnings("unchecked")
    private Map<String, Object> getContentOfYaml(String path) throws IOException {
        Yaml yaml = new Yaml();
        try (InputStream in = new ClassPathResource(path).getInputStream()) {
            return yaml.loadAs(in, Map.class);
        }
    }

    @SuppressWarnings("unchecked")
    private Map<String, String> getContentOfProperties(String path) throws IOException {
        try (InputStream in = new ClassPathResource(path).getInputStream()) {
            Properties properties = new Properties();
            properties.load(in);
            return (Map) (properties);
        }
    }

    @SuppressWarnings("unchecked")
    private Map<String, String> getContentOfJson(String path) throws IOException {
        try (InputStream in = new ClassPathResource(path).getInputStream()) {
            return new ObjectMapper().readValue(in, HashMap.class);
        }
    }

    @SuppressWarnings("unchecked")
    private Map<String, String> flattenInnerProperties(String prefix, Map<String, Object> rootMap) {
        Map<String, String> result = new HashMap<>();
        for (Map.Entry<String, Object> entry : rootMap.entrySet()) {
            String newPrefix = prefix.isEmpty() ? entry.getKey() : prefix + "." + entry.getKey();
            Object value = entry.getValue();
            if (value instanceof Map) {
                result.putAll(flattenInnerProperties(newPrefix, (Map<String, Object>) value));
            } else if (value instanceof List) {
                result.putAll(flattenInnerListInProperties(newPrefix, (List) value));
            } else {
                result.put(newPrefix, String.valueOf(value));
            }
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    private Map<String, String> flattenInnerListInProperties(String prefix, List value) {
        int i = 0;
        Map<String, String> result = new HashMap<>();
        for (Object v : value) {
            String listKey = prefix + "[" + i + "]";
            if (v instanceof Map) {
                result.putAll(flattenInnerProperties(listKey, (Map) v));
            } else if (v instanceof List) {
                result.putAll(flattenInnerListInProperties(listKey, (List) v));
            } else {
                result.put(listKey, String.valueOf(v));
            }
            i++;
        }
        return result;
    }

    private String createPath(String basePath, String configName) {
        return basePath + "/" + configName.replaceAll("\\.", "/");
    }
}

0
投票

我遇到了类似的问题,我们使用zookeeper作为配置服务器,配置以yml格式存储在文件中。我没有根据yml文件动态编写用于创建znode层次结构的代码,而是找到了一个基于groovy的tool,基本上也是如此。

你需要安装groovy并运行如下

zookeeperdump.groovy -s localhost:2181 -c /config/application < dump.yml
© www.soinside.com 2019 - 2024. All rights reserved.