All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rebue.wheel.vertx.util.IdWorkerUtils Maven / Gradle / Ivy

There is a newer version: 3.5.45
Show newest version
package rebue.wheel.vertx.util;

import io.vertx.core.json.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import rebue.wheel.core.idworker.IdWorker3;

import java.util.List;

@Slf4j
public class IdWorkerUtils {

    public static IdWorker3 create3(Object thisObj, JsonObject config, CuratorFramework zkClient) {
        log.info("IdWorkerUtils.create3");
        final String options = config.getString("idworker");
        if (StringUtils.isBlank(options)) {
            log.info("默认为单机模式创建IdWorker3");
            return new IdWorker3();
        }

        String key = options.trim();

        // 解析key
        // 如果"nodeId"开头,且值为0~31,则是指定nodeId;
        // 如果"auto"或以"auto:"开头,则由zookeeper自动分配nodeId,"auto:"后面跟nodeIdBits的值
        if (key.startsWith("nodeId:")) {
            log.info("根据配置指定nodeId的方式创建IdWorker3");
            key = key.replaceFirst("nodeId:", "").trim();
            final int nodeId = Integer.parseInt(key);
            return new IdWorker3(nodeId);
        }

        log.info("从zookeeper获取nodeId的方式创建IdWorker3");
        Integer nodeIdBits;
        if (key.equals("auto")) {
            nodeIdBits = 5;
        } else if (key.startsWith("auto:")) {
            key = key.replaceFirst("auto:", "").trim();
            nodeIdBits = Integer.getInteger(key);
        } else {
            throw new RuntimeException("idworker值应该是整数、”auto“或以”auto:“开头的字符串");
        }

        final String packageName       = thisObj.getClass().getPackage().getName();
        final String className         = thisObj.getClass().getSimpleName();
        final String reducePackageName = packageName.replaceAll(".svc.impl.ex", "").replaceAll(".svc.impl", "");
        final String reduceClassName   = className.replaceAll("SvcImpl", "");
        final String zkNodePath        = "/idworker/" + reducePackageName + "/" + reduceClassName;

        Integer nodeId;
        try {
            LOOP:
            while (true) {
                log.debug("准备连接zookeeper获取路径全名: zkNodePath-{}", zkNodePath);
                final String zkNodeFullName;
                zkNodeFullName = zkClient.create()
                        .creatingParentsIfNeeded()
                        .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
                        .forPath(zkNodePath + "/id_");
                log.debug("连接zookeeper获取到的路径全名: {}", zkNodeFullName);
                final String zkNodeSimpleName = zkNodeFullName.substring(zkNodeFullName.lastIndexOf("/") + 1);
                nodeId = getNodeId(zkNodeFullName, nodeIdBits);
                final List zkNodes = zkClient.getChildren().forPath(zkNodePath);
                for (final String zkNodeSimpleNameTemp : zkNodes) {
                    if (zkNodeSimpleNameTemp.equals(zkNodeSimpleName)) {
                        continue;
                    }
                    final Integer nodeIdTemp = getNodeId(zkNodeSimpleNameTemp, nodeIdBits);
                    if (nodeIdTemp.equals(nodeId)) {
                        zkClient.delete().forPath(zkNodeFullName);
                        continue LOOP;
                    }
                }
                break;
            }
        } catch (Exception e) {
            log.error("连接zookeeper进行操作出现异常", e);
            throw new RuntimeException(e);
        }

        log.info("生成的nodeId为: {}", nodeId);
        return new IdWorker3(nodeId);
    }

    private static Integer getNodeId(final String path, final int nodeIdBits) {
        return Integer.parseInt(StringUtils.right(path, 10)) % (2 << nodeIdBits - 1);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy