一、替换MySQL为达梦数据库
- 下载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 - 将源码导入IntelliJ IDEA中,选择好maven配置和jdk版本等待项目加载完成
- 安装protobuf插件, protocal Buffers(简称protobuf)是谷歌的一项技术,用于结构化的数据序列化、反序列化,常用于RPC 系统 和持续数据存储系统。
- 使用Maven编译项目源码
- 引入达梦数据库驱动,这里注意修改三个pom文件
- 修改父工程下的pom文件,在
<dependencyManagement></dependencyManagement>
标签中注释掉MySQL的驱动依赖,加入达梦数据库驱动依赖,版本我们选择8.1.1.193,
- 修改naming模块下的pom文件,注释掉MySQL的驱动依赖,加入达梦数据库驱动依赖,版本自动从父工程继承,Maven父子继承关系不明白的可以看我的另一篇博文:深入理解微服务Maven父子项目构造以及项目打包部署
- 修改config模块下的pom文件,注释掉MySQL的驱动依赖,加入达梦数据库驱动依赖
- 修改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
- 修改distribution模块下的application.properties文件,修改方式和console模块一样。这个配置就是打包完成后的配置文件,因此,也需要修改。同时,启动脚本也在bin目录下。
- 修改 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);
}
}
- 修改 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";
}
- 修改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();
}
}
- 修改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);
}
}
- 编辑启动类,加入-Dnacos.standalone=true参数,意思是以单机模式启动,启动类在console/src/main/java/com/alibaba/nacos/Nacos.java
- 初始化数据库,脚本如下
- 创建表空间,用户名和密码
--创建表空间
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>);
- 把创建好的表空间、用户名、密码填写到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权限认证的问题,我们需要做以下更改:
- 跳过格式校验:Nacos(all) pom.xml Build plugins配置中启用了格式校验插件,在pom.xml中找到maven-pmd-plugin,maven-checkstyle-plugin相关控件配置,注释掉。
- 跳过认证: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源码适配达梦数据的流程就到这里了,欢迎大家阅读!