nacos连接mysql数据库并使用sm4加密数据库密码

本文详细介绍了如何修改Nacos2.1.0的源码,实现数据库连接配置中密码的加密处理,包括修改`ExternalDataSourceProperties`类以支持解密,添加国密SM4加密工具类,以及在MySQL数据库中添加Nacos依赖的表。此外,还提供了在`application.properties`中配置加密密码的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:
1、https://blog.csdn.net/footless_bird/article/details/118928743
2、https://blog.csdn.net/taolin0/article/details/129557711
3、官方手册:https://nacos.io/zh-cn/docs/v2/quickstart/quick-start.html

修改源码

下载源码

使用的nacos源码是2.1.0版本的
下载地址:https://github.com/alibaba/nacos
在这里插入图片描述

修改代码

1、修改源码类

修改config模块下的“ExternalDataSourceProperties”类,具体路径如下:

nacos-2.1.0/config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceProperties.java

具体代码如下:

/*
 * 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.config.server.utils.Sm4Util;
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 java.util.concurrent.TimeUnit;

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 = "com.mysql.cj.jdbc.Driver";
    
    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<>();

    private List<String> sm4Key = new ArrayList<>();
    
    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;
    }

    public void setSm4Key(List<String> sm4Key) {
        this.sm4Key = sm4Key;
    }

    /**
     * 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(JDBC_DRIVER_NAME);
            poolProperties.setJdbcUrl(url.get(index).trim());
            // poolProperties.setUsername(getOrDefault(user, index, user.get(0)).trim());
            // poolProperties.setPassword(getOrDefault(password, index, password.get(0)).trim());

            //---------------------------------------------------------------------------------------
            // 在这里可以自定义密码的解密规则,此处采用sm4加密为例,可以替换成自己的解密类
            if(sm4Key.size() == 0){
                sm4Key.add("86C63180C2806ED1F47B859DE501215B");
            }
            String split = "DECRYPT@";

            String key = getOrDefault(sm4Key, index, sm4Key.get(0)).trim();
            String reallyUserName = "";
            String reallyPassword = "";

            try {
                String userNameEn = getOrDefault(user, index, user.get(0)).trim();
                String passwordEn = getOrDefault(password, index, password.get(0)).trim();

                if(userNameEn.startsWith(split)){
                    userNameEn = userNameEn.replace(split, "");
                    //解密用户名
                    reallyUserName = Sm4Util.decryptEcb(key, userNameEn);
                } else {
                    reallyUserName = userNameEn;
                }

                if(passwordEn.startsWith(split)){
                    passwordEn = passwordEn.replace(split, "");
                    //解密密码
                    reallyPassword = Sm4Util.decryptEcb(key, passwordEn);
                } else {
                    reallyPassword = passwordEn;
                }
            } catch (Exception e){

            }
            poolProperties.setUsername(reallyUserName);
            poolProperties.setPassword(reallyPassword);
            //-------------------------------------------------------------------------------------------

            HikariDataSource ds = poolProperties.getDataSource();
            ds.setConnectionTestQuery(TEST_QUERY);
            ds.setIdleTimeout(TimeUnit.MINUTES.toMillis(10L));
            ds.setConnectionTimeout(TimeUnit.SECONDS.toMillis(3L));
            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);
    }
}

  • 注意点:
    • 为了兼容可以使用不加密的数据库密码,在加密的密文前面加上“DECRYPT@”

2、国密sm4加解密工具类

config模块添加依赖
        <!--sm4加密算法-->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.66</version>
        </dependency>
sm4加密工具类
/*
 * 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 org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;

@SuppressWarnings("all")	// nacos一键打包时跳过检查,不加可能会报错
public class Sm4Util {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    private static final String ENCODING = "UTF-8";
    public static final String ALGORITHM_NAME = "SM4";

    //加密算法/分组加密模式/分组填充方式
    //PKCS5Padding-以8个字节为一组分组加密
    //定义分组加密模式使用:PKCS5Padding
    public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";

    //128-32位16进制;256-64位16进制

    public static final int DEFAULT_KEY_SIZE = 128;

    /**
     * 生成ECB暗号
     *
     * @param algorithmName 算法名称
     * @param mode          模式
     * @param key
     * @return
     * @throws Exception
     * @explain ECB模式(电子密码本模式:Electronic codebook)
     */
    private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception {
        Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
        Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
        cipher.init(mode, sm4Key);
        return cipher;
    }

    /**
     * 生成默认长度的Key
     * @return byte字节数组
     * @throws Exception
     */
    public static byte[] generateKey() throws Exception {
        return generateKey(DEFAULT_KEY_SIZE);
    }

    /**
     * 生成指定长度的Key
     * @param keySize
     * @return byte字节数组
     * @throws Exception
     */
    public static byte[] generateKey(int keySize) throws Exception {
        KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
        kg.init(keySize, new SecureRandom());
        return kg.generateKey().getEncoded();
    }

    /**
     * sm4加密
     *
     * @param hexKey   16进制秘钥(忽略大小写)
     * @param paramStr 待加密字符串
     * @return 返回16进制的加密字符串
     * @throws Exception
     */
    public static String encryptEcb(String hexKey, String paramStr) throws Exception {
        String cipherText = "";
        // 16进制字符串-->byte[]
        byte[] keyData = ByteUtils.fromHexString(hexKey);
        // String-->byte[]
        byte[] srcData = paramStr.getBytes(ENCODING);
        // 加密后的数组
        byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData);
        // byte[]-->hexString
        cipherText = ByteUtils.toHexString(cipherArray);
        return cipherText;
    }

    /**
     * 加密模式之Ecb
     *
     * @param key
     * @param data
     * @return
     * @throws Exception
     * @explain
     */
    public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throws Exception {
        Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
        return cipher.doFinal(data);
    }

    /**
     * sm4解密
     *
     * @param hexKey     16进制密钥
     * @param cipherText 16进制的加密字符串(忽略大小写)
     * @return 解密后的字符串
     * @throws Exception
     * @explain 解密模式:采用ECB
     */
    public static String decryptEcb(String hexKey, String cipherText) throws Exception {
        // 用于接收解密后的字符串
        String decryptStr = "";
        // hexString-->byte[]
        byte[] keyData = ByteUtils.fromHexString(hexKey);
        // hexString-->byte[]
        byte[] cipherData = ByteUtils.fromHexString(cipherText);
        // 解密
        byte[] srcData = decrypt_Ecb_Padding(keyData, cipherData);
        // byte[]-->String
        decryptStr = new String(srcData, ENCODING);
        return decryptStr;
    }

    /**
     * @param key
     * @param cipherText
     * @return
     * @throws Exception
     */
    public static byte[] decrypt_Ecb_Padding(byte[] key, byte[] cipherText) throws Exception {

        Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(cipherText);
    }

    /**
     * 校验加密前后的字符串是否为同一数据
     *
     * @param hexKey     16进制密钥(忽略大小写)
     * @param cipherText 16进制加密后的字符串
     * @param paramStr   加密前的字符串
     * @return 是否为同一数据
     * @throws Exception
     * @explain
     */
    public static boolean verifyEcb(String hexKey, String cipherText, String paramStr) throws Exception{
        // 用于接收校验结果
        boolean flag = false;
        // hexString-->byte[]
        byte[] keyData = ByteUtils.fromHexString(hexKey);
        // 将16进制字符串转换成数组
        byte[] cipherData = ByteUtils.fromHexString(cipherText);
        // 解密
        byte[] decryptData = decrypt_Ecb_Padding(keyData, cipherData);
        // 将原字符串转换成byte[]
        byte[] srcData = paramStr.getBytes(ENCODING);
        // 判断2个数组是否一致
        flag = Arrays.equals(decryptData, srcData);
        return flag;
    }
}
  • 注意:文件头的注释必须加上,否则打包的时候回出问题,提示“新增文件没有经过Lisence权限认证”,具体提示如下:
[ERROR] Failed to execute goal org.apache.rat:apache-rat-plugin:0.12:check (default) on project nacos-config: Too many files with unapproved license: 10 See RAT report in: D:\IdeaProject\nacos-2.0.3\config\target\rat.txt -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR]   mvn <args> -rf :nacos-config

3、在mysql数据库中添加nacos依赖的表:

数据库脚本位置:


/*
 * 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.
 */

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info   */
/******************************************/
CREATE TABLE `config_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) DEFAULT NULL,
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  `c_desc` varchar(256) DEFAULT NULL,
  `c_use` varchar(64) DEFAULT NULL,
  `effect` varchar(64) DEFAULT NULL,
  `type` varchar(64) DEFAULT NULL,
  `c_schema` text,
  `encrypted_data_key` text NOT NULL COMMENT '秘钥',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_aggr   */
/******************************************/
CREATE TABLE `config_info_aggr` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) NOT NULL COMMENT 'group_id',
  `datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
  `content` longtext NOT NULL COMMENT '内容',
  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_beta   */
/******************************************/
CREATE TABLE `config_info_beta` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  `encrypted_data_key` text NOT NULL COMMENT '秘钥',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_tag   */
/******************************************/
CREATE TABLE `config_info_tag` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
  `tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_tags_relation   */
/******************************************/
CREATE TABLE `config_tags_relation` (
  `id` bigint(20) NOT NULL COMMENT 'id',
  `tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
  `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
  `nid` bigint(20) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`nid`),
  UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
  KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = group_capacity   */
/******************************************/
CREATE TABLE `group_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = his_config_info   */
/******************************************/
CREATE TABLE `his_config_info` (
  `id` bigint(64) unsigned NOT NULL,
  `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `data_id` varchar(255) NOT NULL,
  `group_id` varchar(128) NOT NULL,
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL,
  `md5` varchar(32) DEFAULT NULL,
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `src_user` text,
  `src_ip` varchar(50) DEFAULT NULL,
  `op_type` char(10) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  `encrypted_data_key` text NOT NULL COMMENT '秘钥',
  PRIMARY KEY (`nid`),
  KEY `idx_gmt_create` (`gmt_create`),
  KEY `idx_gmt_modified` (`gmt_modified`),
  KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = tenant_capacity   */
/******************************************/
CREATE TABLE `tenant_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';


CREATE TABLE `tenant_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `kp` varchar(128) NOT NULL COMMENT 'kp',
  `tenant_id` varchar(128) default '' COMMENT 'tenant_id',
  `tenant_name` varchar(128) default '' COMMENT 'tenant_name',
  `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
  `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
  `gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
  `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
  KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';

CREATE TABLE `users` (
	`username` varchar(50) NOT NULL PRIMARY KEY,
	`password` varchar(500) NOT NULL,
	`enabled` boolean NOT NULL
);

CREATE TABLE `roles` (
	`username` varchar(50) NOT NULL,
	`role` varchar(50) NOT NULL,
	UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);

CREATE TABLE `permissions` (
    `role` varchar(50) NOT NULL,
    `resource` varchar(255) NOT NULL,
    `action` varchar(8) NOT NULL,
    UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);

INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);

INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

4、在“application.properties”配置文件中,将数据库用户名和密码替换为加密密文

该配置文件路径:

nacos-2.1.0/console/src/main/resources/application.properties

修改内容如下:

#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
 spring.datasource.platform=mysql

### Count of DB:
 db.num=1

### Connect URL of DB:
 db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
# db.user.0=root
# db.password.0=mysql

 db.user.0=DECRYPT@b916909c4b06919ed4435b0d4873ecd1
 db.password.0=DECRYPT@1b72015439fb8e098edda1ae64c400ef
 db.sm4Key.0=86C63180C2806ED1F47B859DE501215B
  • 注意:“db.sm4Key.0”是后加的,源码中不存在,表示加密密钥,通过编写的工具类生成:
    public static void main(String[] args) throws Exception {
        byte[] genKeyBs = Sm4Util.generateKey();
        System.out.println(genKeyBs);
        String genKeyStr = ByteUtils.toHexString(genKeyBs);
        System.out.println("密钥:" + genKeyStr);
    }
}

5、启动测试

启动类:nacos-2.1.0/console/src/main/java/com/alibaba/nacos/Nacos.java
在这里插入图片描述
启动成功:
在这里插入图片描述
浏览器输入请求路径:
在这里插入图片描述

打包

mvn -Prelease-nacos -Dmaven.test.skip=true -Dpmd.skip=true -Dcheckstyle.skip=true clean install -U
  • 注意:
    1. 使用idea命令行进行打包
    2. 使用jdk17进行打包,否则会出现下面的打包失败的问题:
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for Alibaba NACOS 2.1.0 2.1.0:
[INFO] 
[INFO] Alibaba NACOS 2.1.0 ................................ SUCCESS [  2.795 s]
[INFO] nacos-api 2.1.0 .................................... SUCCESS [  5.703 s]
[INFO] nacos-common 2.1.0 ................................. SUCCESS [  1.575 s]
[INFO] nacos-consistency 2.1.0 ............................ SUCCESS [  3.654 s]
[INFO] nacos-plugin 2.1.0 ................................. SUCCESS [  0.100 s]
[INFO] nacos-auth-plugin 2.1.0 ............................ SUCCESS [  0.342 s]
[INFO] nacos-sys 2.1.0 .................................... SUCCESS [  0.635 s]
[INFO] nacos-auth 2.1.0 ................................... SUCCESS [  0.492 s]
[INFO] nacos-core 2.1.0 ................................... SUCCESS [  2.236 s]
[INFO] nacos-encryption-plugin 2.1.0 ...................... SUCCESS [  0.288 s]
[INFO] nacos-config 2.1.0 ................................. SUCCESS [  3.081 s]
[INFO] nacos-cmdb 2.1.0 ................................... SUCCESS [  0.547 s]
[INFO] nacos-naming 2.1.0 ................................. SUCCESS [  3.722 s]
[INFO] nacos-address 2.1.0 ................................ SUCCESS [  0.561 s]
[INFO] nacos-client 2.1.0 ................................. SUCCESS [ 19.637 s]
[INFO] nacos-plugin-default-impl 2.1.0 .................... SUCCESS [  0.794 s]
[INFO] nacos-istio 2.1.0 .................................. SUCCESS [  8.572 s]
[INFO] nacos-console 2.1.0 ................................ FAILURE [  2.748 s]
[INFO] nacos-test 2.1.0 ................................... SKIPPED
[INFO] nacos-config-test 2.1.0 ............................ SKIPPED
[INFO] nacos-naming-test 2.1.0 ............................ SKIPPED
[INFO] nacos-core-test 2.1.0 .............................. SKIPPED
[INFO] nacos-example 2.1.0 ................................ SKIPPED
[INFO] nacos-distribution 2.1.0 ........................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  57.939 s
[INFO] Finished at: 2023-04-06T11:30:45+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:3.0.5:repackage (default) on project nacos-console: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:3.0.5:repackage failed: Unable to load the mojo 'repackage' in the plugin 'org.springframework.boot:spring-boot-maven-plugin:3.0.5' due to an API incompatibility: org.codehaus.plexus.component.repository.exception.ComponentLookupException: org/springframework/boot/maven/RepackageMojo has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0
[ERROR] -----------------------------------------------------
[ERROR] realm =    plugin>org.springframework.boot:spring-boot-maven-plugin:3.0.5
[ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
[ERROR] urls[0] = file:/Users/xxx/Documents/repository/org/springframework/boot/spring-boot-maven-plugin/3.0.5/spring-boot-maven-plugin-3.0.5.jar
[ERROR] urls[1] = file:/Users/xxx/Documents/repository/org/springframework/spring-context/6.0.7/spring-context-6.0.7.jar
[ERROR] urls[2] = file:/Users/xxx/Documents/repository/org/springframework/spring-aop/6.0.7/spring-aop-6.0.7.jar
[ERROR] urls[3] = file:/Users/xxx/Documents/repository/org/springframework/spring-beans/6.0.7/spring-beans-6.0.7.jar
[ERROR] urls[4] = file:/Users/xxx/Documents/repository/org/springframework/spring-core/6.0.7/spring-core-6.0.7.jar
[ERROR] urls[5] = file:/Users/xxx/Documents/repository/org/springframework/spring-jcl/6.0.7/spring-jcl-6.0.7.jar
[ERROR] urls[6] = file:/Users/xxx/Documents/repository/org/springframework/spring-expression/6.0.7/spring-expression-6.0.7.jar
[ERROR] urls[7] = file:/Users/xxx/Documents/repository/org/springframework/boot/spring-boot-buildpack-platform/3.0.5/spring-boot-buildpack-platform-3.0.5.jar
[ERROR] urls[8] = file:/Users/xxx/Documents/repository/com/fasterxml/jackson/core/jackson-databind/2.14.2/jackson-databind-2.14.2.jar
[ERROR] urls[9] = file:/Users/xxx/Documents/repository/com/fasterxml/jackson/core/jackson-annotations/2.14.2/jackson-annotations-2.14.2.jar
[ERROR] urls[10] = file:/Users/xxx/Documents/repository/com/fasterxml/jackson/core/jackson-core/2.14.2/jackson-core-2.14.2.jar
[ERROR] urls[11] = file:/Users/xxx/Documents/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.14.2/jackson-module-parameter-names-2.14.2.jar
[ERROR] urls[12] = file:/Users/xxx/Documents/repository/net/java/dev/jna/jna-platform/5.7.0/jna-platform-5.7.0.jar
[ERROR] urls[13] = file:/Users/xxx/Documents/repository/net/java/dev/jna/jna/5.7.0/jna-5.7.0.jar
[ERROR] urls[14] = file:/Users/xxx/Documents/repository/org/apache/commons/commons-compress/1.21/commons-compress-1.21.jar
[ERROR] urls[15] = file:/Users/xxx/Documents/repository/org/apache/httpcomponents/httpclient/4.5.14/httpclient-4.5.14.jar
[ERROR] urls[16] = file:/Users/xxx/Documents/repository/org/apache/httpcomponents/httpcore/4.4.16/httpcore-4.4.16.jar
[ERROR] urls[17] = file:/Users/xxx/Documents/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar
[ERROR] urls[18] = file:/Users/xxx/Documents/repository/org/tomlj/tomlj/1.0.0/tomlj-1.0.0.jar
[ERROR] urls[19] = file:/Users/xxx/Documents/repository/org/antlr/antlr4-runtime/4.7.2/antlr4-runtime-4.7.2.jar
[ERROR] urls[20] = file:/Users/xxx/Documents/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
[ERROR] urls[21] = file:/Users/xxx/Documents/repository/org/springframework/boot/spring-boot-loader-tools/3.0.5/spring-boot-loader-tools-3.0.5.jar
[ERROR] urls[22] = file:/Users/xxx/Documents/repository/org/sonatype/plexus/plexus-build-api/0.0.7/plexus-build-api-0.0.7.jar
[ERROR] urls[23] = file:/Users/xxx/Documents/repository/org/codehaus/plexus/plexus-utils/1.5.8/plexus-utils-1.5.8.jar
[ERROR] urls[24] = file:/Users/xxx/Documents/repository/org/apache/maven/plugins/maven-shade-plugin/3.2.4/maven-shade-plugin-3.2.4.jar
[ERROR] urls[25] = file:/Users/xxx/Documents/repository/org/sonatype/sisu/sisu-inject-bean/1.4.2/sisu-inject-bean-1.4.2.jar
[ERROR] urls[26] = file:/Users/xxx/Documents/repository/org/sonatype/sisu/sisu-guice/2.1.7/sisu-guice-2.1.7-noaop.jar
[ERROR] urls[27] = file:/Users/xxx/Documents/repository/org/sonatype/aether/aether-util/1.7/aether-util-1.7.jar
[ERROR] urls[28] = file:/Users/xxx/Documents/repository/org/codehaus/plexus/plexus-interpolation/1.14/plexus-interpolation-1.14.jar
[ERROR] urls[29] = file:/Users/xxx/Documents/repository/org/codehaus/plexus/plexus-component-annotations/1.5.5/plexus-component-annotations-1.5.5.jar
[ERROR] urls[30] = file:/Users/xxx/Documents/repository/org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.jar
[ERROR] urls[31] = file:/Users/xxx/Documents/repository/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar
[ERROR] urls[32] = file:/Users/xxx/Documents/repository/org/apache/maven/shared/maven-artifact-transfer/0.12.0/maven-artifact-transfer-0.12.0.jar
[ERROR] urls[33] = file:/Users/xxx/Documents/repository/org/apache/maven/shared/maven-common-artifact-filters/3.0.1/maven-common-artifact-filters-3.0.1.jar
[ERROR] urls[34] = file:/Users/xxx/Documents/repository/org/apache/maven/shared/maven-shared-utils/3.1.0/maven-shared-utils-3.1.0.jar
[ERROR] urls[35] = file:/Users/xxx/Documents/repository/org/ow2/asm/asm/8.0/asm-8.0.jar
[ERROR] urls[36] = file:/Users/xxx/Documents/repository/org/ow2/asm/asm-commons/8.0/asm-commons-8.0.jar
[ERROR] urls[37] = file:/Users/xxx/Documents/repository/org/ow2/asm/asm-tree/8.0/asm-tree-8.0.jar
[ERROR] urls[38] = file:/Users/xxx/Documents/repository/org/ow2/asm/asm-analysis/8.0/asm-analysis-8.0.jar
[ERROR] urls[39] = file:/Users/xxx/Documents/repository/org/jdom/jdom2/2.0.6/jdom2-2.0.6.jar
[ERROR] urls[40] = file:/Users/xxx/Documents/repository/org/apache/maven/shared/maven-dependency-tree/3.0.1/maven-dependency-tree-3.0.1.jar
[ERROR] urls[41] = file:/Users/xxx/Documents/repository/org/eclipse/aether/aether-util/0.9.0.M2/aether-util-0.9.0.M2.jar
[ERROR] urls[42] = file:/Users/xxx/Documents/repository/commons-io/commons-io/2.6/commons-io-2.6.jar
[ERROR] urls[43] = file:/Users/xxx/Documents/repository/org/vafer/jdependency/2.4.0/jdependency-2.4.0.jar
[ERROR] urls[44] = file:/Users/xxx/Documents/repository/org/ow2/asm/asm-util/8.0/asm-util-8.0.jar
[ERROR] urls[45] = file:/Users/xxx/Documents/repository/com/google/guava/guava/28.2-android/guava-28.2-android.jar
[ERROR] urls[46] = file:/Users/xxx/Documents/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
[ERROR] urls[47] = file:/Users/xxx/Documents/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
[ERROR] urls[48] = file:/Users/xxx/Documents/repository/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar
[ERROR] urls[49] = file:/Users/xxx/Documents/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar
[ERROR] urls[50] = file:/Users/xxx/Documents/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar
[ERROR] urls[51] = file:/Users/xxx/Documents/repository/org/apache/commons/commons-lang3/3.7/commons-lang3-3.7.jar
[ERROR] Number of foreign imports: 1
[ERROR] import: Entry[import  from realm ClassRealm[maven.api, parent: null]]
[ERROR] 
[ERROR] -----------------------------------------------------
[ERROR] 
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginContainerException
[ERROR] 
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR]   mvn <args> -rf :nacos-console
高校点餐系统需求分析文档 一、引言 1.1 项目背景 为提升高校食堂服务效率,优化学生就餐体验,设计一套支持多角色协作、覆盖线上线下全流程的智能化点餐管理系统,实现食堂数字化转型。 1.2 目标用户 - 在校学生(核心用户群) - 食堂管理人员(含菜品管理员、订单管理员等) - 系统维护人员 - 未注册游客(受限访问) 二、系统总体架构 2.1 角色权限体系 | 角色类型 | 权限层级 | 主要功能范围 | |---------- |----------|------------------------------| | 超级管理员 | Level 4 | 系统配置、权限分配、数据审计 | | 内容管理员 | Level 3 | 资讯发布、公告管理、反馈处理 | | 运营管理员 | Level 2 | 菜品管理、订单处理、数据统计 | | 普通用户 | Level 1 | 完整消费功能 | | 游客 | Level 0 | 只读浏览功能 | 三、详细功能需求 3.1 管理员子系统 3.1.1 智能看板 实时数据监测: 当前在线用户数 待处理订单量 实时销售额统计 可视化分析: 热力图展示各时段订单密度 菜品销量TOP10排行榜 用户偏好分析雷达图 3.1.2 内容管理 轮播图管理: 支持上传1080P高清图片 设置展示优先级(1-5级) 定时上下线功能 资讯发布: 富文本编辑器(支持Markdown) 多图文混排模板 定时发布/撤回功能 3.1.3 运营管理 菜品生命周期管理: 基础信息(营养成分、过敏原标注) 动态库存预警(设置库存阈值) 季节性菜品上下架 订单处理: 异常订单标记系统 批量导出CSV功能 智能退单处理流程 3.2 用户子系统 3.2.1 智能点餐 个性化推荐: 基于历史订单的协同过滤推荐 实时热门菜品推送 健康饮食建议(卡路里计算) 多维度搜索: 语音搜索支持 拍照识菜功能 智能纠错建议 3.2.2 订单管理 支付集成: 校园一卡通对接 主流第三方支付(微信/支付宝) 余额充值系统 订单追踪: 制作进度可视化 取餐倒计时提醒 电子取餐码生成 3.2.3 社交化功能 UGC内容管理: 带图评价系统(自动审核机制) 点赞排行榜 优质点评打赏功能 社交分享: 生成带菜品海报 跨平台分享接口 好友推荐奖励机制 3.3 游客模式 受限功能: 菜品浏览(隐藏价格信息) 模拟点餐体验(需登录后完成支付) 只读查看部分评价内容 转化机制: 每日三次体验机会 新用户优惠弹窗 手机快速注册通道 四、非功能性需求 4.2 安全要求 金融级加密:支付环节采用国密SM4算法 隐私保护:敏感数据脱敏处理(如手机号中间四位*代替) 操作审计:关键操作留痕(保留180天日志) 4.3 兼容性要求 移动端:适配iOS/Android主流机型 浏览器:支持Chrome 80+、Safari 14+ 分辨率:完美适配720p-4K显示 五、创新实现方案 5.1 智能预警系统 库存预测模型:基于LSTM神经网络进行销量预测 动态定价策略:根据供需关系调整特价菜品 排队时长预估:结合后厨产能实时计算 5.2 沉浸式体验 AR菜单展示:通过手机摄像头查看3D菜品模型 虚拟营养师:扫描菜品获取健康建议 智能语音助手:全流程语音交互支持 5.3 环保设计 数字小票系统:减少纸张消耗 低碳饮食统计:计算每单碳足迹 光盘奖励计划:拍照认证获取积分 六、部署方案 6.1 技术栈选型 | 层级 | 技术方案 | |------|-----------------------------------------| | 前端 | Vue3 + TypeScript + Vite | | 后端 | Spring Cloud Alibaba微服务架构 | | 数据库 | MySQL集群 + Redis缓存 + ElasticSearch | | 运维 | Kubernetes + Prometheus监控 | 6.2 硬件配置 服务器集群:3台4C8G云主机(负载均衡) 基于这些文字,生成一份
最新发布
04-01
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值