Nacos源码适配达梦数据库

一、替换MySQL为达梦数据库

  1. 下载nacos源码,源码可以从GitHub或者Gitee上下载,建议使用Gitee,GitHub由于服务器在国外,下载速度较慢。
    GitHub下载地址:https://github.com/alibaba/nacos/releases/tag/2.1.2
    Gitee下载地址:https://gitee.com/mirrors/Nacos/tree/2.1.2
  2. 将源码导入IntelliJ IDEA中,选择好maven配置和jdk版本等待项目加载完成
  3. 安装protobuf插件, protocal Buffers(简称protobuf)是谷歌的一项技术,用于结构化的数据序列化、反序列化,常用于RPC 系统 和持续数据存储系统。
    在这里插入图片描述
  4. 使用Maven编译项目源码
    在这里插入图片描述
  5. 引入达梦数据库驱动,这里注意修改三个pom文件
  • 修改父工程下的pom文件,在<dependencyManagement></dependencyManagement>标签中注释掉MySQL的驱动依赖,加入达梦数据库驱动依赖,版本我们选择8.1.1.193,
    在这里插入图片描述
  • 修改naming模块下的pom文件,注释掉MySQL的驱动依赖,加入达梦数据库驱动依赖,版本自动从父工程继承,Maven父子继承关系不明白的可以看我的另一篇博文:深入理解微服务Maven父子项目构造以及项目打包部署

在这里插入图片描述

  • 修改config模块下的pom文件,注释掉MySQL的驱动依赖,加入达梦数据库驱动依赖
    在这里插入图片描述
  1. 修改console模块下的application.properties文件,更换掉mysql的配置,表空间名,用户名,密码根据自己数据库情况替换即可。console模块是整个nacos的启动入口
    在这里插入图片描述
#*************** Config Module Related Configurations ***************#
### If use DM as datasource:
spring.datasource.platform=dm
### Count of DB:
db.num=1
db.jdbcDriverName=dm.jdbc.driver.DmDriver
### Connect URL of DB:
db.url.0=jdbc:dm://localhost:5236/xxx?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8
db.user.0=xxx
db.password.0=xxx
  1. 修改distribution模块下的application.properties文件,修改方式和console模块一样。这个配置就是打包完成后的配置文件,因此,也需要修改。同时,启动脚本也在bin目录下。
    在这里插入图片描述
  2. 修改 nacos-config模块下的com.alibaba.nacos.config.server.service.datasource.ExternalDataSourceProperties.java文件,①增加jdbcDriverName字段,其值可以通过配置文件application.properties获取;②poolProperties.setDriverClassName(jdbcDriverName);在该处替换JDBC_DRIVER_NAME为jdbcDriverName
    在这里插入图片描述
    在这里插入图片描述
    完整的代码如下:
/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package com.alibaba.nacos.config.server.service.datasource;

import com.alibaba.nacos.common.utils.Preconditions;
import com.alibaba.nacos.common.utils.StringUtils;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.core.env.Environment;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.alibaba.nacos.common.utils.CollectionUtils.getOrDefault;

/**
 * Properties of external DataSource.
 *
 * @author Nacos
 */
public class ExternalDataSourceProperties {

//    private static final String JDBC_DRIVER_NAME = "dm.jdbc.driver.DmDriver";
    private String jdbcDriverName;
    private static final String TEST_QUERY = "SELECT 1";

    private Integer num;

    private List<String> url = new ArrayList<>();

    private List<String> user = new ArrayList<>();

    private List<String> password = new ArrayList<>();

    public String getJdbcDriverName() {
        return jdbcDriverName;
    }

    public void setJdbcDriverName(String jdbcDriverName) {
        this.jdbcDriverName = jdbcDriverName;
    }

    public void setNum(Integer num) {
        this.num = num;
    }

    public void setUrl(List<String> url) {
        this.url = url;
    }

    public void setUser(List<String> user) {
        this.user = user;
    }

    public void setPassword(List<String> password) {
        this.password = password;
    }

    /**
     * Build serveral HikariDataSource.
     *
     * @param environment {@link Environment}
     * @param callback    Callback function when constructing data source
     * @return List of {@link HikariDataSource}
     */
    List<HikariDataSource> build(Environment environment, Callback<HikariDataSource> callback) {
        List<HikariDataSource> dataSources = new ArrayList<>();
        Binder.get(environment).bind("db", Bindable.ofInstance(this));
        Preconditions.checkArgument(Objects.nonNull(num), "db.num is null");
        Preconditions.checkArgument(CollectionUtils.isNotEmpty(user), "db.user or db.user.[index] is null");
        Preconditions.checkArgument(CollectionUtils.isNotEmpty(password), "db.password or db.password.[index] is null");
        for (int index = 0; index < num; index++) {
            int currentSize = index + 1;
            Preconditions.checkArgument(url.size() >= currentSize, "db.url.%s is null", index);
            DataSourcePoolProperties poolProperties = DataSourcePoolProperties.build(environment);
            poolProperties.setDriverClassName(jdbcDriverName);
            poolProperties.setJdbcUrl(url.get(index).trim());
            poolProperties.setUsername(getOrDefault(user, index, user.get(0)).trim());
            poolProperties.setPassword(getOrDefault(password, index, password.get(0)).trim());
            HikariDataSource ds = poolProperties.getDataSource();
            ds.setConnectionTestQuery(TEST_QUERY);
            dataSources.add(ds);
            callback.accept(ds);
        }
        Preconditions.checkArgument(CollectionUtils.isNotEmpty(dataSources), "no datasource available");
        return dataSources;
    }

    interface Callback<D> {

        /**
         * Perform custom logic.
         *
         * @param datasource dataSource.
         */
        void accept(D datasource);
    }
}
  1. 修改 com/alibaba/nacos/config/server/constant/PropertiesConstant.java
    把 public static final String DM = "mysql"替换为 public static final String DM = “dm”,完整的代码如下:
/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.nacos.config.server.constant;

/**
 * PropertiesConstant.
 *
 * @author lixiaoshuang
 */
public class PropertiesConstant {

    public static final String NOTIFY_CONNECT_TIMEOUT = "notifyConnectTimeout";

    public static final String NOTIFY_SOCKET_TIMEOUT = "notifySocketTimeout";

    public static final String IS_HEALTH_CHECK = "isHealthCheck";

    public static final String MAX_HEALTH_CHECK_FAIL_COUNT = "maxHealthCheckFailCount";

    public static final String MAX_CONTENT = "maxContent";

    public static final String IS_MANAGE_CAPACITY = "isManageCapacity";

    public static final String IS_CAPACITY_LIMIT_CHECK = "isCapacityLimitCheck";

    public static final String DEFAULT_CLUSTER_QUOTA = "defaultClusterQuota";

    public static final String DEFAULT_GROUP_QUOTA = "defaultGroupQuota";

    public static final String DEFAULT_TENANT_QUOTA = "defaultTenantQuota";

    public static final String DEFAULT_MAX_SIZE = "defaultMaxSize";

    public static final String DEFAULT_MAX_AGGR_COUNT = "defaultMaxAggrCount";

    public static final String DEFAULT_MAX_AGGR_SIZE = "defaultMaxAggrSize";

    public static final String CORRECT_USAGE_DELAY = "correctUsageDelay";

    public static final String INITIAL_EXPANSION_PERCENT = "initialExpansionPercent";

    public static final String SPRING_DATASOURCE_PLATFORM = "spring.datasource.platform";

    public static final String DM = "dm";

    public static final String EMBEDDED_STORAGE = "embeddedStorage";

}

  1. 修改com/alibaba/nacos/config/server/utils/PropertyUtil.java,
    把 boolean useExternalDB = PropertiesConstant.MYSQL
    .equalsIgnoreCase(getString(PropertiesConstant.SPRING_DATASOURCE_PLATFORM, “”));
    setUseExternalDB(useExternalDB);
    修改为:
    boolean useExternalDB = PropertiesConstant.DM
    .equalsIgnoreCase(getString(PropertiesConstant.SPRING_DATASOURCE_PLATFORM, “”));
    setUseExternalDB(useExternalDB);
    PS:nacos本身也是个springboot项目,启动时会根据提前配置的信息选择性的进行容器化管理。这里添加这里的目的也是为了让我们之前修改的ExternalDataSourceProperties类配置生效在这里插入图片描述完整代码如下:
/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.nacos.config.server.utils;

import com.alibaba.nacos.config.server.constant.PropertiesConstant;
import com.alibaba.nacos.sys.env.EnvUtil;
import org.slf4j.Logger;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * Properties util.
 *
 * @author Nacos
 */
public class PropertyUtil implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    private static final Logger LOGGER = LogUtil.DEFAULT_LOG;

    private static int notifyConnectTimeout = 100;

    private static int notifySocketTimeout = 200;

    private static int maxHealthCheckFailCount = 12;

    private static boolean isHealthCheck = true;

    private static int maxContent = 10 * 1024 * 1024;

    /**
     * Whether to enable capacity management.
     */
    private static boolean isManageCapacity = true;

    /**
     * Whether to enable the limit check function of capacity management, including the upper limit of configuration
     * number, configuration content size limit, etc.
     */
    private static boolean isCapacityLimitCheck = false;

    /**
     * The default cluster capacity limit.
     */
    private static int defaultClusterQuota = 100000;

    /**
     * the default capacity limit per Group.
     */
    private static int defaultGroupQuota = 200;

    /**
     * The default capacity limit per Tenant.
     */
    private static int defaultTenantQuota = 200;

    /**
     * The maximum size of the content in the configuration of a single, unit for bytes.
     */
    private static int defaultMaxSize = 100 * 1024;

    /**
     * The default Maximum number of aggregated data.
     */
    private static int defaultMaxAggrCount = 10000;

    /**
     * The maximum size of content in a single subconfiguration of aggregated data.
     */
    private static int defaultMaxAggrSize = 1024;

    /**
     * Initialize the expansion percentage of capacity has reached the limit.
     */
    private static int initialExpansionPercent = 100;

    /**
     * Fixed capacity information table usage (usage) time interval, the unit is in seconds.
     */
    private static int correctUsageDelay = 10 * 60;

    /**
     * Standalone mode uses DB.
     */
    private static boolean useExternalDB = false;

    /**
     * Inline storage value = ${nacos.standalone}.
     */
    private static boolean embeddedStorage = EnvUtil.getStandaloneMode();

    public static int getNotifyConnectTimeout() {
        return notifyConnectTimeout;
    }

    public static void setNotifyConnectTimeout(int notifyConnectTimeout) {
        PropertyUtil.notifyConnectTimeout = notifyConnectTimeout;
    }

    public static int getNotifySocketTimeout() {
        return notifySocketTimeout;
    }

    public static void setNotifySocketTimeout(int notifySocketTimeout) {
        PropertyUtil.notifySocketTimeout = notifySocketTimeout;
    }

    public static int getMaxHealthCheckFailCount() {
        return maxHealthCheckFailCount;
    }

    public static void setMaxHealthCheckFailCount(int maxHealthCheckFailCount) {
        PropertyUtil.maxHealthCheckFailCount = maxHealthCheckFailCount;
    }

    public static boolean isHealthCheck() {
        return isHealthCheck;
    }

    public static void setHealthCheck(boolean isHealthCheck) {
        PropertyUtil.isHealthCheck = isHealthCheck;
    }

    public static int getMaxContent() {
        return maxContent;
    }

    public static void setMaxContent(int maxContent) {
        PropertyUtil.maxContent = maxContent;
    }

    public static boolean isManageCapacity() {
        return isManageCapacity;
    }

    public static void setManageCapacity(boolean isManageCapacity) {
        PropertyUtil.isManageCapacity = isManageCapacity;
    }

    public static int getDefaultClusterQuota() {
        return defaultClusterQuota;
    }

    public static void setDefaultClusterQuota(int defaultClusterQuota) {
        PropertyUtil.defaultClusterQuota = defaultClusterQuota;
    }

    public static boolean isCapacityLimitCheck() {
        return isCapacityLimitCheck;
    }

    public static void setCapacityLimitCheck(boolean isCapacityLimitCheck) {
        PropertyUtil.isCapacityLimitCheck = isCapacityLimitCheck;
    }

    public static int getDefaultGroupQuota() {
        return defaultGroupQuota;
    }

    public static void setDefaultGroupQuota(int defaultGroupQuota) {
        PropertyUtil.defaultGroupQuota = defaultGroupQuota;
    }

    public static int getDefaultTenantQuota() {
        return defaultTenantQuota;
    }

    public static void setDefaultTenantQuota(int defaultTenantQuota) {
        PropertyUtil.defaultTenantQuota = defaultTenantQuota;
    }

    public static int getInitialExpansionPercent() {
        return initialExpansionPercent;
    }

    public static void setInitialExpansionPercent(int initialExpansionPercent) {
        PropertyUtil.initialExpansionPercent = initialExpansionPercent;
    }

    public static int getDefaultMaxSize() {
        return defaultMaxSize;
    }

    public static void setDefaultMaxSize(int defaultMaxSize) {
        PropertyUtil.defaultMaxSize = defaultMaxSize;
    }

    public static int getDefaultMaxAggrCount() {
        return defaultMaxAggrCount;
    }

    public static void setDefaultMaxAggrCount(int defaultMaxAggrCount) {
        PropertyUtil.defaultMaxAggrCount = defaultMaxAggrCount;
    }

    public static int getDefaultMaxAggrSize() {
        return defaultMaxAggrSize;
    }

    public static void setDefaultMaxAggrSize(int defaultMaxAggrSize) {
        PropertyUtil.defaultMaxAggrSize = defaultMaxAggrSize;
    }

    public static int getCorrectUsageDelay() {
        return correctUsageDelay;
    }

    public static void setCorrectUsageDelay(int correctUsageDelay) {
        PropertyUtil.correctUsageDelay = correctUsageDelay;
    }

    public static boolean isStandaloneMode() {
        return EnvUtil.getStandaloneMode();
    }

    public static boolean isUseExternalDB() {
        return useExternalDB;
    }

    public static void setUseExternalDB(boolean useExternalDB) {
        PropertyUtil.useExternalDB = useExternalDB;
    }

    public static boolean isEmbeddedStorage() {
        return embeddedStorage;
    }

    // Determines whether to read the data directly
    // if use mysql, Reduce database read pressure
    // if use raft+derby, Reduce leader read pressure

    public static boolean isDirectRead() {
        return EnvUtil.getStandaloneMode() && isEmbeddedStorage();
    }

    public static void setEmbeddedStorage(boolean embeddedStorage) {
        PropertyUtil.embeddedStorage = embeddedStorage;
    }

    private void loadSetting() {
        try {
            setNotifyConnectTimeout(Integer.parseInt(EnvUtil.getProperty(PropertiesConstant.NOTIFY_CONNECT_TIMEOUT,
                    String.valueOf(notifyConnectTimeout))));
            LOGGER.info("notifyConnectTimeout:{}", notifyConnectTimeout);
            setNotifySocketTimeout(Integer.parseInt(EnvUtil.getProperty(PropertiesConstant.NOTIFY_SOCKET_TIMEOUT,
                    String.valueOf(notifySocketTimeout))));
            LOGGER.info("notifySocketTimeout:{}", notifySocketTimeout);
            setHealthCheck(Boolean.parseBoolean(
                    EnvUtil.getProperty(PropertiesConstant.IS_HEALTH_CHECK, String.valueOf(isHealthCheck))));
            LOGGER.info("isHealthCheck:{}", isHealthCheck);
            setMaxHealthCheckFailCount(Integer.parseInt(
                    EnvUtil.getProperty(PropertiesConstant.MAX_HEALTH_CHECK_FAIL_COUNT,
                            String.valueOf(maxHealthCheckFailCount))));
            LOGGER.info("maxHealthCheckFailCount:{}", maxHealthCheckFailCount);
            setMaxContent(
                    Integer.parseInt(EnvUtil.getProperty(PropertiesConstant.MAX_CONTENT, String.valueOf(maxContent))));
            LOGGER.info("maxContent:{}", maxContent);
            // capacity management
            setManageCapacity(getBoolean(PropertiesConstant.IS_MANAGE_CAPACITY, isManageCapacity));
            setCapacityLimitCheck(getBoolean(PropertiesConstant.IS_CAPACITY_LIMIT_CHECK, isCapacityLimitCheck));
            setDefaultClusterQuota(getInt(PropertiesConstant.DEFAULT_CLUSTER_QUOTA, defaultClusterQuota));
            setDefaultGroupQuota(getInt(PropertiesConstant.DEFAULT_GROUP_QUOTA, defaultGroupQuota));
            setDefaultTenantQuota(getInt(PropertiesConstant.DEFAULT_TENANT_QUOTA, defaultTenantQuota));
            setDefaultMaxSize(getInt(PropertiesConstant.DEFAULT_MAX_SIZE, defaultMaxSize));
            setDefaultMaxAggrCount(getInt(PropertiesConstant.DEFAULT_MAX_AGGR_COUNT, defaultMaxAggrCount));
            setDefaultMaxAggrSize(getInt(PropertiesConstant.DEFAULT_MAX_AGGR_SIZE, defaultMaxAggrSize));
            setCorrectUsageDelay(getInt(PropertiesConstant.CORRECT_USAGE_DELAY, correctUsageDelay));
            setInitialExpansionPercent(getInt(PropertiesConstant.INITIAL_EXPANSION_PERCENT, initialExpansionPercent));
            // External data sources are used by default in cluster mode
            boolean useExternalDB = PropertiesConstant.DM
                    .equalsIgnoreCase(getString(PropertiesConstant.SPRING_DATASOURCE_PLATFORM, ""));
            setUseExternalDB(useExternalDB);

            // must initialize after setUseExternalDB
            // This value is true in stand-alone mode and false in cluster mode
            // If this value is set to true in cluster mode, nacos's distributed storage engine is turned on
            // default value is depend on ${nacos.standalone}

            if (isUseExternalDB()) {
                setEmbeddedStorage(false);
            } else {
                boolean embeddedStorage =
                        PropertyUtil.embeddedStorage || Boolean.getBoolean(PropertiesConstant.EMBEDDED_STORAGE);
                setEmbeddedStorage(embeddedStorage);

                // If the embedded data source storage is not turned on, it is automatically
                // upgraded to the external data source storage, as before
                if (!embeddedStorage) {
                    setUseExternalDB(true);
                }
            }
        } catch (Exception e) {
            LOGGER.error("read application.properties failed", e);
            throw e;
        }
    }

    private boolean getBoolean(String key, boolean defaultValue) {
        return Boolean.parseBoolean(getString(key, String.valueOf(defaultValue)));
    }

    private int getInt(String key, int defaultValue) {
        return Integer.parseInt(getString(key, String.valueOf(defaultValue)));
    }

    private String getString(String key, String defaultValue) {
        String value = getProperty(key);
        if (value == null) {
            return defaultValue;
        }
        LOGGER.info("{}:{}", key, value);
        return value;
    }

    public String getProperty(String key) {
        return EnvUtil.getProperty(key);
    }

    public String getProperty(String key, String defaultValue) {
        return EnvUtil.getProperty(key, defaultValue);
    }

    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        loadSetting();
    }
}

  1. 修改com.alibaba.nacos.core.listener.StartingApplicationListener.java
    把private static final String DEFAULT_DATABASE = "msyql"改为private static final String DEFAULT_DATABASE = “dm”。如果不更改,启动日志会打印Nacos started successfully in stanalone mode. use embedded storage的错误日志,正确的日志是Nacos started successfully in stanalone mode. use external storage,会给人造成误解。embedded storage的意思是使用了嵌入式存储,其实使用了达梦数据库。
    在这里插入图片描述
    完整代码:
/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.nacos.core.listener;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
import com.alibaba.nacos.common.executor.ExecutorFactory;
import com.alibaba.nacos.common.executor.NameThreadFactory;
import com.alibaba.nacos.common.executor.ThreadPoolManager;
import com.alibaba.nacos.common.notify.NotifyCenter;
import com.alibaba.nacos.common.event.ServerConfigChangeEvent;
import com.alibaba.nacos.sys.env.EnvUtil;
import com.alibaba.nacos.sys.file.FileChangeEvent;
import com.alibaba.nacos.sys.file.FileWatcher;
import com.alibaba.nacos.sys.file.WatchFileCenter;
import com.alibaba.nacos.sys.utils.ApplicationUtils;
import com.alibaba.nacos.sys.utils.DiskUtils;
import com.alibaba.nacos.sys.utils.InetUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * init environment config.
 *
 * @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a>
 * @since 0.5.0
 */
public class StartingApplicationListener implements NacosApplicationListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(StartingApplicationListener.class);

    private static final String MODE_PROPERTY_KEY_STAND_MODE = "nacos.mode";

    private static final String MODE_PROPERTY_KEY_FUNCTION_MODE = "nacos.function.mode";

    private static final String LOCAL_IP_PROPERTY_KEY = "nacos.local.ip";

    private static final String NACOS_APPLICATION_CONF = "nacos_application_conf";

    private static final String NACOS_MODE_STAND_ALONE = "stand alone";

    private static final String NACOS_MODE_CLUSTER = "cluster";

    private static final String DEFAULT_FUNCTION_MODE = "All";

    private static final String DEFAULT_DATABASE = "dm";

    private static final String DATASOURCE_PLATFORM_PROPERTY = "spring.datasource.platform";

    private static final String DEFAULT_DATASOURCE_PLATFORM = "";

    private static final String DATASOURCE_MODE_EXTERNAL = "external";

    private static final String DATASOURCE_MODE_EMBEDDED = "embedded";

    private static final Map<String, Object> SOURCES = new ConcurrentHashMap<>();

    private ScheduledExecutorService scheduledExecutorService;

    private volatile boolean starting;

    @Override
    public void starting() {
        starting = true;
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        makeWorkDir();

        injectEnvironment(environment);

        loadPreProperties(environment);

        initSystemProperty();
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        logClusterConf();

        logStarting();
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {

    }

    @Override
    public void started(ConfigurableApplicationContext context) {
        starting = false;

        closeExecutor();

        ApplicationUtils.setStarted(true);
        judgeStorageMode(context.getEnvironment());
    }

    @Override
    public void running(ConfigurableApplicationContext context) {
    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        starting = false;

        makeWorkDir();

        LOGGER.error("Startup errors : ", exception);
        ThreadPoolManager.shutdown();
        WatchFileCenter.shutdown();
        NotifyCenter.shutdown();

        closeExecutor();

        context.close();

        LOGGER.error("Nacos failed to start, please see {} for more details.",
                Paths.get(EnvUtil.getNacosHome(), "logs/nacos.log"));
    }

    private void injectEnvironment(ConfigurableEnvironment environment) {
        EnvUtil.setEnvironment(environment);
    }

    private void loadPreProperties(ConfigurableEnvironment environment) {
        try {
            SOURCES.putAll(EnvUtil.loadProperties(EnvUtil.getApplicationConfFileResource()));
            environment.getPropertySources()
                    .addLast(new OriginTrackedMapPropertySource(NACOS_APPLICATION_CONF, SOURCES));
            registerWatcher();
        } catch (Exception e) {
            throw new NacosRuntimeException(NacosException.SERVER_ERROR, e);
        }
    }

    private void registerWatcher() throws NacosException {

        WatchFileCenter.registerWatcher(EnvUtil.getConfPath(), new FileWatcher() {
            @Override
            public void onChange(FileChangeEvent event) {
                try {
                    Map<String, ?> tmp = EnvUtil.loadProperties(EnvUtil.getApplicationConfFileResource());
                    SOURCES.putAll(tmp);
                    NotifyCenter.publishEvent(ServerConfigChangeEvent.newEvent());
                } catch (IOException ignore) {
                    LOGGER.warn("Failed to monitor file ", ignore);
                }
            }

            @Override
            public boolean interest(String context) {
                return StringUtils.contains(context, "application.properties");
            }
        });

    }

    private void initSystemProperty() {
        if (EnvUtil.getStandaloneMode()) {
            System.setProperty(MODE_PROPERTY_KEY_STAND_MODE, NACOS_MODE_STAND_ALONE);
        } else {
            System.setProperty(MODE_PROPERTY_KEY_STAND_MODE, NACOS_MODE_CLUSTER);
        }
        if (EnvUtil.getFunctionMode() == null) {
            System.setProperty(MODE_PROPERTY_KEY_FUNCTION_MODE, DEFAULT_FUNCTION_MODE);
        } else if (EnvUtil.FUNCTION_MODE_CONFIG.equals(EnvUtil.getFunctionMode())) {
            System.setProperty(MODE_PROPERTY_KEY_FUNCTION_MODE, EnvUtil.FUNCTION_MODE_CONFIG);
        } else if (EnvUtil.FUNCTION_MODE_NAMING.equals(EnvUtil.getFunctionMode())) {
            System.setProperty(MODE_PROPERTY_KEY_FUNCTION_MODE, EnvUtil.FUNCTION_MODE_NAMING);
        }

        System.setProperty(LOCAL_IP_PROPERTY_KEY, InetUtils.getSelfIP());
    }

    private void logClusterConf() {
        if (!EnvUtil.getStandaloneMode()) {
            try {
                List<String> clusterConf = EnvUtil.readClusterConf();
                LOGGER.info("The server IP list of Nacos is {}", clusterConf);
            } catch (IOException e) {
                LOGGER.error("read cluster conf fail", e);
            }
        }
    }

    private void closeExecutor() {
        if (scheduledExecutorService != null) {
            scheduledExecutorService.shutdownNow();
        }
    }

    private void makeWorkDir() {
        String[] dirNames = new String[] {"logs", "conf", "data"};
        for (String dirName : dirNames) {
            LOGGER.info("Nacos Log files: {}", Paths.get(EnvUtil.getNacosHome(), dirName));
            try {
                DiskUtils.forceMkdir(new File(Paths.get(EnvUtil.getNacosHome(), dirName).toUri()));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    private void logStarting() {
        if (!EnvUtil.getStandaloneMode()) {

            scheduledExecutorService = ExecutorFactory
                    .newSingleScheduledExecutorService(new NameThreadFactory("com.alibaba.nacos.core.nacos-starting"));

            scheduledExecutorService.scheduleWithFixedDelay(() -> {
                if (starting) {
                    LOGGER.info("Nacos is starting...");
                }
            }, 1, 1, TimeUnit.SECONDS);
        }
    }

    private void judgeStorageMode(ConfigurableEnvironment env) {

        // External data sources are used by default in cluster mode
        boolean useExternalStorage = (DEFAULT_DATABASE.equalsIgnoreCase(env.getProperty(DATASOURCE_PLATFORM_PROPERTY, DEFAULT_DATASOURCE_PLATFORM)));

        // must initialize after setUseExternalDB
        // This value is true in stand-alone mode and false in cluster mode
        // If this value is set to true in cluster mode, nacos's distributed storage engine is turned on
        // default value is depend on ${nacos.standalone}

        if (!useExternalStorage) {
            boolean embeddedStorage = EnvUtil.getStandaloneMode() || Boolean.getBoolean("embeddedStorage");
            // If the embedded data source storage is not turned on, it is automatically
            // upgraded to the external data source storage, as before
            if (!embeddedStorage) {
                useExternalStorage = true;
            }
        }

        LOGGER.info("Nacos started successfully in {} mode. use {} storage",
                System.getProperty(MODE_PROPERTY_KEY_STAND_MODE), useExternalStorage ? DATASOURCE_MODE_EXTERNAL : DATASOURCE_MODE_EMBEDDED);
    }
}

  1. 编辑启动类,加入-Dnacos.standalone=true参数,意思是以单机模式启动,启动类在console/src/main/java/com/alibaba/nacos/Nacos.java
    在这里插入图片描述
  2. 初始化数据库,脚本如下
  • 创建表空间,用户名和密码
--创建表空间
CREATE TABLESPACE  "XXX" DATAFILE 'XXX.DBF' SIZE 300 autoextend on maxsize 67108863 CACHE = NORMAL;
--创建用户
CREATE USER "XXX" IDENTIFIED BY "XXX" LIMIT PASSWORD_LOCK_TIME 1, PASSWORD_GRACE_TIME 10 DEFAULT TABLESPACE "XXX";
--给用户授权
GRANT "RESOURCE","PUBLIC","DBA","VTI" TO "XXX";
  • 创建表
CREATE TABLE "NACOS"."config_info"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL,
"data_id" VARCHAR(255) NOT NULL,
"group_id" VARCHAR(255),
"content" CLOB NOT NULL,
"md5" VARCHAR(32),
"gmt_create" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"gmt_modified" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"src_user" TEXT,
"src_ip" VARCHAR(50),
"app_name" VARCHAR(128),
"tenant_id" VARCHAR(128) DEFAULT '',
"c_desc" VARCHAR(256),
"c_use" VARCHAR(64),
"effect" VARCHAR(64),
"type" VARCHAR(64),
"c_schema" TEXT,
"encrypted_data_key" TEXT NOT NULL,
NOT CLUSTER PRIMARY KEY("id"),
CONSTRAINT "uk_configinfo_datagrouptenant" UNIQUE("data_id", "group_id", "tenant_id")) STORAGE(ON "NACOS", CLUSTERBTR) ;

COMMENT ON TABLE "NACOS"."config_info" IS 'config_info';
COMMENT ON COLUMN "NACOS"."config_info"."content" IS 'content';
COMMENT ON COLUMN "NACOS"."config_info"."data_id" IS 'data_id';
COMMENT ON COLUMN "NACOS"."config_info"."encrypted_data_key" IS '秘钥';
COMMENT ON COLUMN "NACOS"."config_info"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "NACOS"."config_info"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "NACOS"."config_info"."id" IS 'id';
COMMENT ON COLUMN "NACOS"."config_info"."md5" IS 'md5';
COMMENT ON COLUMN "NACOS"."config_info"."src_ip" IS 'source ip';
COMMENT ON COLUMN "NACOS"."config_info"."src_user" IS 'source user';
COMMENT ON COLUMN "NACOS"."config_info"."tenant_id" IS '租户字段';


CREATE TABLE "NACOS"."config_info_aggr"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL,
"data_id" VARCHAR(255) NOT NULL,
"group_id" VARCHAR(255) NOT NULL,
"datum_id" VARCHAR(255) NOT NULL,
"content" CLOB NOT NULL,
"gmt_modified" TIMESTAMP(0) NOT NULL,
"app_name" VARCHAR(128),
"tenant_id" VARCHAR(128) DEFAULT '',
NOT CLUSTER PRIMARY KEY("id"),
CONSTRAINT "uk_configinfoaggr_datagrouptenantdatum" UNIQUE("data_id", "group_id", "tenant_id", "datum_id")) STORAGE(ON "NACOS", CLUSTERBTR) ;

COMMENT ON TABLE "NACOS"."config_info_aggr" IS '增加租户字段';
COMMENT ON COLUMN "NACOS"."config_info_aggr"."content" IS '内容';
COMMENT ON COLUMN "NACOS"."config_info_aggr"."data_id" IS 'data_id';
COMMENT ON COLUMN "NACOS"."config_info_aggr"."datum_id" IS 'datum_id';
COMMENT ON COLUMN "NACOS"."config_info_aggr"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "NACOS"."config_info_aggr"."group_id" IS 'group_id';
COMMENT ON COLUMN "NACOS"."config_info_aggr"."id" IS 'id';
COMMENT ON COLUMN "NACOS"."config_info_aggr"."tenant_id" IS '租户字段';


CREATE TABLE "NACOS"."config_info_beta"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL,
"data_id" VARCHAR(255) NOT NULL,
"group_id" VARCHAR(128) NOT NULL,
"app_name" VARCHAR(128),
"content" CLOB NOT NULL,
"beta_ips" VARCHAR(1024),
"md5" VARCHAR(32),
"gmt_create" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"gmt_modified" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"src_user" TEXT,
"src_ip" VARCHAR(50),
"tenant_id" VARCHAR(128) DEFAULT '',
"encrypted_data_key" TEXT NOT NULL,
NOT CLUSTER PRIMARY KEY("id"),
CONSTRAINT "uk_configinfobeta_datagrouptenant" UNIQUE("data_id", "group_id", "tenant_id")) STORAGE(ON "NACOS", CLUSTERBTR) ;

COMMENT ON TABLE "NACOS"."config_info_beta" IS 'config_info_beta';
COMMENT ON COLUMN "NACOS"."config_info_beta"."app_name" IS 'app_name';
COMMENT ON COLUMN "NACOS"."config_info_beta"."beta_ips" IS 'betaIps';
COMMENT ON COLUMN "NACOS"."config_info_beta"."content" IS 'content';
COMMENT ON COLUMN "NACOS"."config_info_beta"."data_id" IS 'data_id';
COMMENT ON COLUMN "NACOS"."config_info_beta"."encrypted_data_key" IS '秘钥';
COMMENT ON COLUMN "NACOS"."config_info_beta"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "NACOS"."config_info_beta"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "NACOS"."config_info_beta"."group_id" IS 'group_id';
COMMENT ON COLUMN "NACOS"."config_info_beta"."id" IS 'id';
COMMENT ON COLUMN "NACOS"."config_info_beta"."md5" IS 'md5';
COMMENT ON COLUMN "NACOS"."config_info_beta"."src_ip" IS 'source ip';
COMMENT ON COLUMN "NACOS"."config_info_beta"."src_user" IS 'source user';
COMMENT ON COLUMN "NACOS"."config_info_beta"."tenant_id" IS '租户字段';


CREATE TABLE "NACOS"."config_info_tag"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL,
"data_id" VARCHAR(255) NOT NULL,
"group_id" VARCHAR(128) NOT NULL,
"tenant_id" VARCHAR(128) DEFAULT '',
"tag_id" VARCHAR(128) NOT NULL,
"app_name" VARCHAR(128),
"content" CLOB NOT NULL,
"md5" VARCHAR(32),
"gmt_create" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"gmt_modified" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"src_user" TEXT,
"src_ip" VARCHAR(50),
NOT CLUSTER PRIMARY KEY("id"),
CONSTRAINT "uk_configinfotag_datagrouptenanttag" UNIQUE("data_id", "group_id", "tenant_id", "tag_id")) STORAGE(ON "NACOS", CLUSTERBTR) ;

COMMENT ON TABLE "NACOS"."config_info_tag" IS 'config_info_tag';
COMMENT ON COLUMN "NACOS"."config_info_tag"."app_name" IS 'app_name';
COMMENT ON COLUMN "NACOS"."config_info_tag"."content" IS 'content';
COMMENT ON COLUMN "NACOS"."config_info_tag"."data_id" IS 'data_id';
COMMENT ON COLUMN "NACOS"."config_info_tag"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "NACOS"."config_info_tag"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "NACOS"."config_info_tag"."group_id" IS 'group_id';
COMMENT ON COLUMN "NACOS"."config_info_tag"."id" IS 'id';
COMMENT ON COLUMN "NACOS"."config_info_tag"."md5" IS 'md5';
COMMENT ON COLUMN "NACOS"."config_info_tag"."src_ip" IS 'source ip';
COMMENT ON COLUMN "NACOS"."config_info_tag"."src_user" IS 'source user';
COMMENT ON COLUMN "NACOS"."config_info_tag"."tag_id" IS 'tag_id';
COMMENT ON COLUMN "NACOS"."config_info_tag"."tenant_id" IS 'tenant_id';


CREATE TABLE "NACOS"."config_tags_relation"
(
"id" BIGINT NOT NULL,
"tag_name" VARCHAR(128) NOT NULL,
"tag_type" VARCHAR(64),
"data_id" VARCHAR(255) NOT NULL,
"group_id" VARCHAR(128) NOT NULL,
"tenant_id" VARCHAR(128) DEFAULT '',
"nid" BIGINT IDENTITY(1, 1) NOT NULL,
NOT CLUSTER PRIMARY KEY("nid"),
CONSTRAINT "uk_configtagrelation_configidtag" UNIQUE("id", "tag_name", "tag_type")) STORAGE(ON "NACOS", CLUSTERBTR) ;

COMMENT ON TABLE "NACOS"."config_tags_relation" IS 'config_tag_relation';
COMMENT ON COLUMN "NACOS"."config_tags_relation"."data_id" IS 'data_id';
COMMENT ON COLUMN "NACOS"."config_tags_relation"."group_id" IS 'group_id';
COMMENT ON COLUMN "NACOS"."config_tags_relation"."id" IS 'id';
COMMENT ON COLUMN "NACOS"."config_tags_relation"."tag_name" IS 'tag_name';
COMMENT ON COLUMN "NACOS"."config_tags_relation"."tag_type" IS 'tag_type';
COMMENT ON COLUMN "NACOS"."config_tags_relation"."tenant_id" IS 'tenant_id';


CREATE  INDEX "INDEX27450417857800" ON "NACOS"."config_tags_relation"("tenant_id" ASC) STORAGE(ON "NACOS", CLUSTERBTR) ;

CREATE TABLE "NACOS"."group_capacity"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL,
"group_id" VARCHAR(128) DEFAULT '' NOT NULL,
"quota" BIGINT DEFAULT 0 NOT NULL,
"usage" BIGINT DEFAULT 0 NOT NULL,
"max_size" BIGINT DEFAULT 0 NOT NULL,
"max_aggr_count" BIGINT DEFAULT 0 NOT NULL,
"max_aggr_size" BIGINT DEFAULT 0 NOT NULL,
"max_history_count" BIGINT DEFAULT 0 NOT NULL,
"gmt_create" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"gmt_modified" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
NOT CLUSTER PRIMARY KEY("id"),
CONSTRAINT "uk_group_id" UNIQUE("group_id"),
CHECK("quota" >= 0)
,CHECK("usage" >= 0)
,CHECK("max_size" >= 0)
,CHECK("max_aggr_count" >= 0)
,CHECK("max_aggr_size" >= 0)
,CHECK("max_history_count" >= 0)) STORAGE(ON "NACOS", CLUSTERBTR) ;

COMMENT ON TABLE "NACOS"."group_capacity" IS '集群、各Group容量信息表';
COMMENT ON COLUMN "NACOS"."group_capacity"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "NACOS"."group_capacity"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "NACOS"."group_capacity"."group_id" IS 'Group ID,空字符表示整个集群';
COMMENT ON COLUMN "NACOS"."group_capacity"."id" IS '主键ID';
COMMENT ON COLUMN "NACOS"."group_capacity"."max_aggr_count" IS '聚合子配置最大个数,,0表示使用默认值';
COMMENT ON COLUMN "NACOS"."group_capacity"."max_aggr_size" IS '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值';
COMMENT ON COLUMN "NACOS"."group_capacity"."max_history_count" IS '最大变更历史数量';
COMMENT ON COLUMN "NACOS"."group_capacity"."max_size" IS '单个配置大小上限,单位为字节,0表示使用默认值';
COMMENT ON COLUMN "NACOS"."group_capacity"."quota" IS '配额,0表示使用默认值';
COMMENT ON COLUMN "NACOS"."group_capacity"."usage" IS '使用量';


CREATE TABLE "NACOS"."his_config_info"
(
"id" DECIMAL(20,0) NOT NULL,
"nid" BIGINT IDENTITY(1, 1) NOT NULL,
"data_id" VARCHAR(255) NOT NULL,
"group_id" VARCHAR(128) NOT NULL,
"app_name" VARCHAR(128),
"content" CLOB NOT NULL,
"md5" VARCHAR(32),
"gmt_create" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"gmt_modified" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"src_user" TEXT,
"src_ip" VARCHAR(50),
"op_type" CHAR(10),
"tenant_id" VARCHAR(128) DEFAULT '',
"encrypted_data_key" TEXT NOT NULL,
NOT CLUSTER PRIMARY KEY("nid"),
CHECK("id" >= 0)) STORAGE(ON "NACOS", CLUSTERBTR) ;

COMMENT ON TABLE "NACOS"."his_config_info" IS '多租户改造';
COMMENT ON COLUMN "NACOS"."his_config_info"."app_name" IS 'app_name';
COMMENT ON COLUMN "NACOS"."his_config_info"."encrypted_data_key" IS '秘钥';
COMMENT ON COLUMN "NACOS"."his_config_info"."tenant_id" IS '租户字段';


CREATE  INDEX "idx_gmt_create" ON "NACOS"."his_config_info"("gmt_create" ASC) STORAGE(ON "NACOS", CLUSTERBTR) ;
CREATE  INDEX "idx_did" ON "NACOS"."his_config_info"("data_id" ASC) STORAGE(ON "NACOS", CLUSTERBTR) ;
CREATE  INDEX "idx_gmt_modified" ON "NACOS"."his_config_info"("gmt_modified" ASC) STORAGE(ON "NACOS", CLUSTERBTR) ;

CREATE TABLE "NACOS"."permissions"
(
"role" VARCHAR(50) NOT NULL,
"resource" VARCHAR(255) NOT NULL,
"action" VARCHAR(8) NOT NULL,
CONSTRAINT "uk_role_permission" UNIQUE("role", "resource", "action")) STORAGE(ON "NACOS", CLUSTERBTR) ;

CREATE TABLE "NACOS"."roles"
(
"username" VARCHAR(50) NOT NULL,
"role" VARCHAR(50) NOT NULL,
CONSTRAINT "idx_user_role" UNIQUE("username", "role")) STORAGE(ON "NACOS", CLUSTERBTR) ;
insert into "NACOS"."roles"("username", "role")  VALUES(<"username", VARCHAR(50)>, <"role", VARCHAR(50)>);


CREATE TABLE "NACOS"."tenant_capacity"
(
"id" BIGINT IDENTITY(1, 1) NOT NULL,
"tenant_id" VARCHAR(128) DEFAULT '' NOT NULL,
"quota" BIGINT DEFAULT 0 NOT NULL,
"usage" BIGINT DEFAULT 0 NOT NULL,
"max_size" BIGINT DEFAULT 0 NOT NULL,
"max_aggr_count" BIGINT DEFAULT 0 NOT NULL,
"max_aggr_size" BIGINT DEFAULT 0 NOT NULL,
"max_history_count" BIGINT DEFAULT 0 NOT NULL,
"gmt_create" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
"gmt_modified" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP() NOT NULL,
NOT CLUSTER PRIMARY KEY("id"),
CONSTRAINT "uk_tenant_id" UNIQUE("tenant_id"),
CHECK("quota" >= 0)
,CHECK("usage" >= 0)
,CHECK("max_size" >= 0)
,CHECK("max_aggr_count" >= 0)
,CHECK("max_aggr_size" >= 0)
,CHECK("max_history_count" >= 0)) STORAGE(ON "NACOS", CLUSTERBTR) ;

COMMENT ON TABLE "NACOS"."tenant_capacity" IS '租户容量信息表';
COMMENT ON COLUMN "NACOS"."tenant_capacity"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "NACOS"."tenant_capacity"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "NACOS"."tenant_capacity"."id" IS '主键ID';
COMMENT ON COLUMN "NACOS"."tenant_capacity"."max_aggr_count" IS '聚合子配置最大个数';
COMMENT ON COLUMN "NACOS"."tenant_capacity"."max_aggr_size" IS '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值';
COMMENT ON COLUMN "NACOS"."tenant_capacity"."max_history_count" IS '最大变更历史数量';
COMMENT ON COLUMN "NACOS"."tenant_capacity"."max_size" IS '单个配置大小上限,单位为字节,0表示使用默认值';
COMMENT ON COLUMN "NACOS"."tenant_capacity"."quota" IS '配额,0表示使用默认值';
COMMENT ON COLUMN "NACOS"."tenant_capacity"."tenant_id" IS 'Tenant ID';
COMMENT ON COLUMN "NACOS"."tenant_capacity"."usage" IS '使用量';


CREATE TABLE "NACOS"."tenant_info"
(
"id" BIGINT IDENTITY(3, 1) NOT NULL,
"kp" VARCHAR(128) NOT NULL,
"tenant_id" VARCHAR(128) DEFAULT '',
"tenant_name" VARCHAR(128) DEFAULT '',
"tenant_desc" VARCHAR(256),
"create_source" VARCHAR(32),
"gmt_create" BIGINT NOT NULL,
"gmt_modified" BIGINT NOT NULL,
NOT CLUSTER PRIMARY KEY("id"),
CONSTRAINT "uk_tenant_info_kptenantid" UNIQUE("kp", "tenant_id")) STORAGE(ON "NACOS", CLUSTERBTR) ;

COMMENT ON TABLE "NACOS"."tenant_info" IS 'tenant_info';
COMMENT ON COLUMN "NACOS"."tenant_info"."create_source" IS 'create_source';
COMMENT ON COLUMN "NACOS"."tenant_info"."gmt_create" IS '创建时间';
COMMENT ON COLUMN "NACOS"."tenant_info"."gmt_modified" IS '修改时间';
COMMENT ON COLUMN "NACOS"."tenant_info"."id" IS 'id';
COMMENT ON COLUMN "NACOS"."tenant_info"."kp" IS 'kp';
COMMENT ON COLUMN "NACOS"."tenant_info"."tenant_desc" IS 'tenant_desc';
COMMENT ON COLUMN "NACOS"."tenant_info"."tenant_id" IS 'tenant_id';
COMMENT ON COLUMN "NACOS"."tenant_info"."tenant_name" IS 'tenant_name';


CREATE  INDEX "idx_tenant_id" ON "NACOS"."tenant_info"("tenant_id" ASC) STORAGE(ON "NACOS", CLUSTERBTR) ;

CREATE TABLE "NACOS"."users"
(
"username" VARCHAR(50) NOT NULL,
"password" VARCHAR(500) NOT NULL,
"enabled" TINYINT NOT NULL,
NOT CLUSTER PRIMARY KEY("username")) STORAGE(ON "NACOS", CLUSTERBTR) ;
insert into "NACOS"."users"("username", "password", "enabled") VALUES(<"username", VARCHAR(50)>, <"password", VARCHAR(500)>, <"enabled", TINYINT>);
  1. 把创建好的表空间、用户名、密码填写到console下的application.properteis文件中,然后启动Nacos,访问http://localhost:8848/nacos/#/login
    在这里插入图片描述
    如果能正常登录则数据库替换成功。

二、语法适配达梦数据库

       研究nacos源码发现:nacos中的SQL书写规范,绝大多数功能不需要改写SQL,前提是:①达梦数据库开启了兼容MySQL②大小写不敏感,具体配置请看我的博文:Mysql迁移达梦数据库踩坑历险记,因为开启前面两项配置并不能百之百保证所有的MySQL语法在达梦数据中兼容,因此,在测试中发现还是有两处功能需要做手动适配。

2.1 绑定角色

角色管理-绑定角色-动态查询用户名:
在这里插入图片描述
修改文件:com.alibaba.nacos.plugin.auth.impl.persistence.ExternalUserPersistServiceImpl,将SQL改为如下即可
在这里插入图片描述

2.2 权限管理

权限管理-添加权限-动态查询角色名
在这里插入图片描述
修改文件:com.alibaba.nacos.plugin.auth.impl.persistence.ExternalRolePersistServiceImpl,将SQL改为如下即可
在这里插入图片描述

三、源码打包

       所有的修改完成后,就可以对源码进行打包了,由于nacos打包时有着严格的编码格式校验和新增文件Lisence权限认证的问题,我们需要做以下更改:

  1. 跳过格式校验:Nacos(all) pom.xml Build plugins配置中启用了格式校验插件,在pom.xml中找到maven-pmd-plugin,maven-checkstyle-plugin相关控件配置,注释掉。
  2. 跳过认证:Nacos(all) pom.xml 配置中,找到apache-rat-plugin控件组,注释掉相关插件配置。

       更改完成后以管理员身份运行cmd,进入nacos源码目录位置 D:\Nacos-2.1.2\,执行mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U打包命令,打包成功后的压缩包在Nacos-2.1.2\distribution\target\nacos-server-2.1.2.zip
在这里插入图片描述nacos源码适配达梦数据的流程就到这里了,欢迎大家阅读!

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

屿丶斐然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值