配置文件解析

简单的zoo.cfg配置如下

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

这里重点分析server.x配置项的解析

/**
     * Parse a ZooKeeper configuration file
     * @param path the patch of the configuration file
     * @throws ConfigException error processing configuration
     */
    public void parse(String path) throws ConfigException {
        LOG.info("Reading configuration from: " + path);

        try {
            File configFile = (new VerifyingFileFactory.Builder(LOG)
                .warnForRelativePath()
                .failForNonExistingPath()
                .build()).create(path); // 根据配置文件路径实例化File对象

            Properties cfg = new Properties();
            FileInputStream in = new FileInputStream(configFile);
            try {
                cfg.load(in); // 读取配置文件
                configFileStr = path;
            } finally {
                in.close();
            }

            /* Read entire config file as initial configuration */
            initialConfig = new String(Files.readAllBytes(configFile.toPath()));

            parseProperties(cfg); // 解析配置文件
        } ...

        ...
    }
/**
     * Parse config from a Properties.
     * @param zkProp Properties to parse from.
     * @throws IOException
     * @throws ConfigException
     */
    public void parseProperties(Properties zkProp) throws IOException, ConfigException {
        ...
        for (Entry<Object, Object> entry : zkProp.entrySet()) {
            ... // 具体的配置项解析
        }
        ...
        
        // backward compatibility - dynamic configuration in the same file as
        // static configuration params see writeDynamicConfig()
        if (dynamicConfigFileStr == null) { // 上面的for循环中会对dynamicConfigFileStr进行赋值,但是配置文件中没有dynamicConfigFile项,同静态配置文件
            setupQuorumPeerConfig(zkProp, true);
            if (isDistributed() && isReconfigEnabled()) {
                // we don't backup static config for standalone mode.
                // we also don't backup if reconfig feature is disabled.
                backupOldConfig();
            }
        }
    }
void setupQuorumPeerConfig(Properties prop, boolean configBackwardCompatibilityMode) throws IOException, ConfigException {
        quorumVerifier = parseDynamicConfig(prop, electionAlg, true, configBackwardCompatibilityMode);
        setupMyId(); // 设置sid(myid)
        setupClientPort();
        setupPeerType();
        checkValidity();
    }
/**
     * Parse dynamic configuration file and return
     * quorumVerifier for new configuration.
     * @param dynamicConfigProp Properties to parse from.
     * @throws IOException
     * @throws ConfigException
     */
    public static QuorumVerifier parseDynamicConfig(Properties dynamicConfigProp, int eAlg, boolean warnings, boolean configBackwardCompatibilityMode) throws IOException, ConfigException {
        boolean isHierarchical = false;
        for (Entry<Object, Object> entry : dynamicConfigProp.entrySet()) {
            String key = entry.getKey().toString().trim();
            if (key.startsWith("group") || key.startsWith("weight")) {
                isHierarchical = true;
            } else if (!configBackwardCompatibilityMode && !key.startsWith("server.") && !key.equals("version")) {
                LOG.info(dynamicConfigProp.toString());
                throw new ConfigException("Unrecognised parameter: " + key);
            }
        }

        QuorumVerifier qv = createQuorumVerifier(dynamicConfigProp, isHierarchical); // 由于没有配置group或者weight,isHierarchical为false
		...
        return qv;
    }
private static QuorumVerifier createQuorumVerifier(Properties dynamicConfigProp, boolean isHierarchical) throws ConfigException {
        if (isHierarchical) {
            return new QuorumHierarchical(dynamicConfigProp);
        } else {
            /*
             * The default QuorumVerifier is QuorumMaj
             */
            //LOG.info("Defaulting to majority quorums");
            return new QuorumMaj(dynamicConfigProp);
        }
    }
public QuorumMaj(Properties props) throws ConfigException {
        for (Entry<Object, Object> entry : props.entrySet()) {
            String key = entry.getKey().toString();
            String value = entry.getValue().toString();

            if (key.startsWith("server.")) { // 解析server.x
                int dot = key.indexOf('.');
                long sid = Long.parseLong(key.substring(dot + 1)); // sid or myid
                QuorumServer qs = new QuorumServer(sid, value);
                allMembers.put(Long.valueOf(sid), qs);
                if (qs.type == LearnerType.PARTICIPANT) {
                    votingMembers.put(Long.valueOf(sid), qs); // leader or follower
                } else {
                    observingMembers.put(Long.valueOf(sid), qs); // observer
                }
            } else if (key.equals("version")) {
                version = Long.parseLong(value, 16);
            }
        }
        half = votingMembers.size() / 2;
    }
public QuorumServer(long sid, String addressStr) throws ConfigException {
            this.id = sid;
            LearnerType newType = null;
            String[] serverClientParts = addressStr.split(";"); // 长度为1
            String[] serverAddresses = serverClientParts[0].split("\\|"); // 长度为1
			...

            for (String serverAddress : serverAddresses) {
                String serverParts[] = ConfigUtils.getHostAndPort(serverAddress); // 通过冒号分割
                ...
                // server_config should be either host:port:port or host:port:port:type
                InetSocketAddress tempAddress;
                InetSocketAddress tempElectionAddress;
                try {
                    tempAddress = new InetSocketAddress(serverParts[0], Integer.parseInt(serverParts[1]));
                    addr.addAddress(tempAddress); // 数据同步使用的ip+port
                } ...
                try {
                    tempElectionAddress = new InetSocketAddress(serverParts[0], Integer.parseInt(serverParts[2]));
                    electionAddr.addAddress(tempElectionAddress); // 选举使用的ip+port
                } ...
				...
                this.hostname = serverParts[0]; // 表示的host
            }
			...
            setMyAddrs();
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值