学习目标

通过本章学习,你将能够: - 掌握 Nacos 的多种安装方式 - 理解单机模式和集群模式的区别 - 熟练配置 Nacos 的各项参数 - 完成数据库的配置和初始化 - 掌握 Nacos 的启动和管理

1. 环境准备

1.1 系统要求

from enum import Enum
from dataclasses import dataclass
from typing import List, Dict, Optional
import os
import platform

class OSType(Enum):
    """操作系统类型"""
    LINUX = "linux"
    WINDOWS = "windows"
    MACOS = "macos"

class DeploymentMode(Enum):
    """部署模式"""
    STANDALONE = "standalone"  # 单机模式
    CLUSTER = "cluster"        # 集群模式

class DatabaseType(Enum):
    """数据库类型"""
    DERBY = "derby"    # 内嵌数据库
    MYSQL = "mysql"    # MySQL 数据库

@dataclass
class SystemRequirement:
    """系统要求数据类"""
    component: str
    minimum_version: str
    recommended_version: str
    description: str

@dataclass
class NacosConfig:
    """Nacos 配置数据类"""
    server_port: int = 8848
    management_port: int = 9848
    management_context_path: str = "/nacos"
    cluster_port: int = 9849
    db_type: DatabaseType = DatabaseType.DERBY
    db_url: Optional[str] = None
    db_username: Optional[str] = None
    db_password: Optional[str] = None
    jvm_xms: str = "1g"
    jvm_xmx: str = "1g"
    jvm_xmn: str = "512m"

class NacosInstaller:
    """Nacos 安装器"""
    
    def __init__(self):
        self.system_requirements = self._initialize_requirements()
        self.current_os = self._detect_os()
    
    def _initialize_requirements(self) -> List[SystemRequirement]:
        """初始化系统要求"""
        return [
            SystemRequirement(
                component="JDK",
                minimum_version="1.8",
                recommended_version="11+",
                description="Java 开发工具包,支持 Oracle JDK 和 OpenJDK"
            ),
            SystemRequirement(
                component="Memory",
                minimum_version="2GB",
                recommended_version="4GB+",
                description="系统内存,集群模式建议 8GB+"
            ),
            SystemRequirement(
                component="Disk",
                minimum_version="10GB",
                recommended_version="50GB+",
                description="磁盘空间,用于存储日志和数据"
            ),
            SystemRequirement(
                component="MySQL",
                minimum_version="5.6.5",
                recommended_version="8.0+",
                description="外部数据库(集群模式必需)"
            )
        ]
    
    def _detect_os(self) -> OSType:
        """检测操作系统"""
        system = platform.system().lower()
        if system == "linux":
            return OSType.LINUX
        elif system == "windows":
            return OSType.WINDOWS
        elif system == "darwin":
            return OSType.MACOS
        else:
            return OSType.LINUX  # 默认
    
    def check_system_requirements(self) -> Dict[str, bool]:
        """检查系统要求"""
        results = {}
        
        # 检查 Java 版本
        try:
            java_version = os.popen('java -version 2>&1').read()
            if 'java version' in java_version or 'openjdk version' in java_version:
                results['java'] = True
                print("✅ Java 环境检查通过")
            else:
                results['java'] = False
                print("❌ Java 环境未安装")
        except:
            results['java'] = False
            print("❌ Java 环境检查失败")
        
        # 检查内存
        try:
            if self.current_os == OSType.LINUX:
                mem_info = os.popen('free -m').read()
                # 简化检查,实际应解析内存信息
                results['memory'] = True
                print("✅ 内存检查通过")
            else:
                results['memory'] = True
                print("✅ 内存检查跳过(非 Linux 系统)")
        except:
            results['memory'] = False
            print("❌ 内存检查失败")
        
        # 检查磁盘空间
        try:
            if self.current_os == OSType.LINUX:
                disk_info = os.popen('df -h').read()
                results['disk'] = True
                print("✅ 磁盘空间检查通过")
            else:
                results['disk'] = True
                print("✅ 磁盘空间检查跳过(非 Linux 系统)")
        except:
            results['disk'] = False
            print("❌ 磁盘空间检查失败")
        
        return results
    
    def generate_download_commands(self, version: str = "2.3.0") -> Dict[str, str]:
        """生成下载命令"""
        base_url = f"https://github.com/alibaba/nacos/releases/download/{version}"
        
        commands = {
            OSType.LINUX: f"wget {base_url}/nacos-server-{version}.tar.gz",
            OSType.WINDOWS: f"curl -L -o nacos-server-{version}.zip {base_url}/nacos-server-{version}.zip",
            OSType.MACOS: f"curl -L -o nacos-server-{version}.tar.gz {base_url}/nacos-server-{version}.tar.gz"
        }
        
        return {os_type.value: cmd for os_type, cmd in commands.items()}
    
    def generate_installation_script(self, mode: DeploymentMode, 
                                   config: NacosConfig) -> str:
        """生成安装脚本"""
        if self.current_os == OSType.LINUX:
            return self._generate_linux_script(mode, config)
        elif self.current_os == OSType.WINDOWS:
            return self._generate_windows_script(mode, config)
        else:
            return self._generate_macos_script(mode, config)
    
    def _generate_linux_script(self, mode: DeploymentMode, 
                              config: NacosConfig) -> str:
        """生成 Linux 安装脚本"""
        script = f'''#!/bin/bash

# Nacos 安装脚本 - Linux
# 部署模式: {mode.value}

set -e

echo "开始安装 Nacos..."

# 1. 创建安装目录
NACOS_HOME="/opt/nacos"
sudo mkdir -p $NACOS_HOME
cd $NACOS_HOME

# 2. 下载 Nacos
echo "下载 Nacos 安装包..."
wget https://github.com/alibaba/nacos/releases/download/2.3.0/nacos-server-2.3.0.tar.gz

# 3. 解压安装包
echo "解压安装包..."
tar -xzf nacos-server-2.3.0.tar.gz
cd nacos

# 4. 配置 JVM 参数
echo "配置 JVM 参数..."
cat > bin/startup.sh << 'EOF'
#!/bin/bash

export JAVA_OPT="${{JAVA_OPT}} -Xms{config.jvm_xms}"
export JAVA_OPT="${{JAVA_OPT}} -Xmx{config.jvm_xmx}"
export JAVA_OPT="${{JAVA_OPT}} -Xmn{config.jvm_xmn}"
export JAVA_OPT="${{JAVA_OPT}} -Dnacos.standalone={"true" if mode == DeploymentMode.STANDALONE else "false"}"

# 启动 Nacos
sh $(dirname $0)/startup.sh -m {mode.value}
EOF

chmod +x bin/startup.sh

# 5. 配置数据库(如果使用 MySQL)
'''
        
        if config.db_type == DatabaseType.MYSQL:
            script += f'''
echo "配置 MySQL 数据库..."
cat > conf/application.properties << 'EOF'
# MySQL 数据库配置
spring.datasource.platform=mysql
db.num=1
db.url.0={config.db_url}
db.user.0={config.db_username}
db.password.0={config.db_password}
db.pool.config.connectionTimeout=30000
db.pool.config.validationTimeout=10000
db.pool.config.maximumPoolSize=20
db.pool.config.minimumIdle=2
EOF

# 初始化数据库
echo "初始化数据库..."
mysql -h{config.db_url.split('//')[1].split(':')[0]} -u{config.db_username} -p{config.db_password} < conf/nacos-mysql.sql
'''
        
        script += '''
# 6. 设置系统服务
echo "设置系统服务..."
sudo cat > /etc/systemd/system/nacos.service << 'EOF'
[Unit]
Description=Nacos Server
After=network.target

[Service]
Type=forking
User=nacos
Group=nacos
ExecStart=/opt/nacos/nacos/bin/startup.sh -m standalone
ExecStop=/opt/nacos/nacos/bin/shutdown.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

# 7. 创建 nacos 用户
sudo useradd -r -s /bin/false nacos
sudo chown -R nacos:nacos /opt/nacos

# 8. 启用服务
sudo systemctl daemon-reload
sudo systemctl enable nacos

echo "Nacos 安装完成!"
echo "启动命令: sudo systemctl start nacos"
echo "查看状态: sudo systemctl status nacos"
echo "访问地址: http://localhost:8848/nacos"
echo "默认账号: nacos/nacos"
'''
        
        return script
    
    def _generate_windows_script(self, mode: DeploymentMode, 
                               config: NacosConfig) -> str:
        """生成 Windows 安装脚本"""
        script = f'''@echo off
REM Nacos 安装脚本 - Windows
REM 部署模式: {mode.value}

echo 开始安装 Nacos...

REM 1. 创建安装目录
set NACOS_HOME=C:\\nacos
mkdir %NACOS_HOME%
cd /d %NACOS_HOME%

REM 2. 下载 Nacos(需要手动下载)
echo 请手动下载 nacos-server-2.3.0.zip 到当前目录
pause

REM 3. 解压安装包(需要手动解压)
echo 请手动解压 nacos-server-2.3.0.zip
pause

cd nacos

REM 4. 配置 JVM 参数
echo 配置 JVM 参数...
echo set JAVA_OPT=%%JAVA_OPT%% -Xms{config.jvm_xms} > bin\\startup.cmd.tmp
echo set JAVA_OPT=%%JAVA_OPT%% -Xmx{config.jvm_xmx} >> bin\\startup.cmd.tmp
echo set JAVA_OPT=%%JAVA_OPT%% -Xmn{config.jvm_xmn} >> bin\\startup.cmd.tmp
echo set JAVA_OPT=%%JAVA_OPT%% -Dnacos.standalone={"true" if mode == DeploymentMode.STANDALONE else "false"} >> bin\\startup.cmd.tmp
echo call bin\\startup.cmd -m {mode.value} >> bin\\startup.cmd.tmp
move bin\\startup.cmd.tmp bin\\startup.cmd
'''
        
        if config.db_type == DatabaseType.MYSQL:
            script += f'''
REM 5. 配置 MySQL 数据库
echo 配置 MySQL 数据库...
echo # MySQL 数据库配置 > conf\\application.properties
echo spring.datasource.platform=mysql >> conf\\application.properties
echo db.num=1 >> conf\\application.properties
echo db.url.0={config.db_url} >> conf\\application.properties
echo db.user.0={config.db_username} >> conf\\application.properties
echo db.password.0={config.db_password} >> conf\\application.properties

echo 请手动执行 conf\\nacos-mysql.sql 初始化数据库
pause
'''
        
        script += '''
REM 6. 启动 Nacos
echo Nacos 安装完成!
echo 启动命令: bin\\startup.cmd
echo 停止命令: bin\\shutdown.cmd
echo 访问地址: http://localhost:8848/nacos
echo 默认账号: nacos/nacos

pause
'''
        
        return script
    
    def _generate_macos_script(self, mode: DeploymentMode, 
                             config: NacosConfig) -> str:
        """生成 macOS 安装脚本"""
        # macOS 脚本与 Linux 类似,但使用 brew 等 macOS 特有工具
        return self._generate_linux_script(mode, config).replace(
            "sudo useradd -r -s /bin/false nacos",
            "# macOS 不需要创建系统用户"
        ).replace(
            "sudo systemctl",
            "# macOS 使用 launchctl 管理服务"
        )

# 使用示例
if __name__ == "__main__":
    # 创建安装器
    installer = NacosInstaller()
    
    # 检查系统要求
    print("=== 系统要求检查 ===")
    requirements_check = installer.check_system_requirements()
    
    # 显示系统要求
    print("\n=== 系统要求列表 ===")
    for req in installer.system_requirements:
        print(f"{req.component}:")
        print(f"  最低版本: {req.minimum_version}")
        print(f"  推荐版本: {req.recommended_version}")
        print(f"  说明: {req.description}")
        print()
    
    # 生成下载命令
    print("=== 下载命令 ===")
    download_commands = installer.generate_download_commands()
    for os_type, command in download_commands.items():
        print(f"{os_type}: {command}")
    
    # 生成安装脚本
    print("\n=== 安装脚本生成 ===")
    
    # 单机模式配置
    standalone_config = NacosConfig(
        server_port=8848,
        db_type=DatabaseType.DERBY
    )
    
    standalone_script = installer.generate_installation_script(
        DeploymentMode.STANDALONE, 
        standalone_config
    )
    
    print("单机模式安装脚本:")
    print(standalone_script[:500] + "..." if len(standalone_script) > 500 else standalone_script)
    
    # 集群模式配置
    cluster_config = NacosConfig(
        server_port=8848,
        db_type=DatabaseType.MYSQL,
        db_url="jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC",
        db_username="nacos",
        db_password="nacos"
    )
    
    cluster_script = installer.generate_installation_script(
        DeploymentMode.CLUSTER, 
        cluster_config
    )
    
    print("\n集群模式安装脚本:")
    print(cluster_script[:500] + "..." if len(cluster_script) > 500 else cluster_script)

2. 单机模式安装

2.1 快速安装

Linux/macOS 安装步骤

# 1. 下载 Nacos
wget https://github.com/alibaba/nacos/releases/download/2.3.0/nacos-server-2.3.0.tar.gz

# 2. 解压
tar -xzf nacos-server-2.3.0.tar.gz
cd nacos

# 3. 启动(单机模式)
sh startup.sh -m standalone

# 4. 查看日志
tail -f logs/start.out

Windows 安装步骤

REM 1. 下载并解压 nacos-server-2.3.0.zip

REM 2. 进入 nacos 目录
cd nacos

REM 3. 启动(单机模式)
startup.cmd -m standalone

REM 4. 查看日志
type logs\start.out

2.2 Docker 安装

# 1. 拉取镜像
docker pull nacos/nacos-server:v2.3.0

# 2. 启动容器(单机模式)
docker run -d \
  --name nacos-standalone \
  -p 8848:8848 \
  -p 9848:9848 \
  -e MODE=standalone \
  -e PREFER_HOST_MODE=hostname \
  nacos/nacos-server:v2.3.0

# 3. 查看日志
docker logs -f nacos-standalone

2.3 Docker Compose 安装

# docker-compose.yml
version: '3.8'

services:
  nacos:
    image: nacos/nacos-server:v2.3.0
    container_name: nacos-standalone
    environment:
      - MODE=standalone
      - PREFER_HOST_MODE=hostname
      - JVM_XMS=512m
      - JVM_XMX=512m
      - JVM_XMN=256m
    ports:
      - "8848:8848"
      - "9848:9848"
    volumes:
      - ./nacos/logs:/home/nacos/logs
      - ./nacos/data:/home/nacos/data
    restart: unless-stopped
    networks:
      - nacos-network

networks:
  nacos-network:
    driver: bridge

volumes:
  nacos-logs:
  nacos-data:

启动命令:

docker-compose up -d

3. 集群模式安装

3.1 数据库准备

3.1.1 MySQL 安装

# Ubuntu/Debian
sudo apt update
sudo apt install mysql-server

# CentOS/RHEL
sudo yum install mysql-server
# 或者
sudo dnf install mysql-server

# 启动 MySQL
sudo systemctl start mysql
sudo systemctl enable mysql

3.1.2 创建数据库

-- 1. 登录 MySQL
mysql -u root -p

-- 2. 创建数据库
CREATE DATABASE nacos DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 3. 创建用户
CREATE USER 'nacos'@'%' IDENTIFIED BY 'nacos';

-- 4. 授权
GRANT ALL PRIVILEGES ON nacos.* TO 'nacos'@'%';
FLUSH PRIVILEGES;

-- 5. 退出
EXIT;

3.1.3 初始化表结构

# 执行 Nacos 提供的 SQL 脚本
mysql -u nacos -p nacos < conf/nacos-mysql.sql

3.2 集群配置

3.2.1 cluster.conf 配置

# 编辑集群配置文件
cp conf/cluster.conf.example conf/cluster.conf
vim conf/cluster.conf
# cluster.conf 内容
# 格式: ip:port
192.168.1.101:8848
192.168.1.102:8848
192.168.1.103:8848

3.2.2 application.properties 配置

# conf/application.properties

# 服务器配置
server.port=8848
nacos.inetutils.prefer-hostname-over-ip=false
nacos.inetutils.ip-address=192.168.1.101

# 数据库配置
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://192.168.1.100:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=nacos
db.password.0=nacos
db.pool.config.connectionTimeout=30000
db.pool.config.validationTimeout=10000
db.pool.config.maximumPoolSize=20
db.pool.config.minimumIdle=2

# JVM 配置
nacos.cmdb.dumpTaskInterval=3600
nacos.cmdb.eventTaskInterval=10
nacos.cmdb.labelTaskInterval=300
nacos.cmdb.loadDataAtStart=false

# 认证配置
nacos.core.auth.enabled=true
nacos.core.auth.system.type=nacos
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
nacos.core.auth.plugin.nacos.token.expire.seconds=18000
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789

# 管理配置
management.endpoints.web.exposure.include=*
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false

# 日志配置
nacos.logs.path=/opt/nacos/logs
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i
server.tomcat.basedir=/opt/nacos/tomcat

3.3 集群启动

3.3.1 启动脚本

#!/bin/bash
# start-cluster.sh

# 节点列表
NODES=("192.168.1.101" "192.168.1.102" "192.168.1.103")
NACOS_HOME="/opt/nacos"

for node in "${NODES[@]}"; do
    echo "启动节点: $node"
    ssh $node "cd $NACOS_HOME && sh startup.sh"
    sleep 5
done

echo "集群启动完成"

3.3.2 健康检查

#!/bin/bash
# health-check.sh

NODES=("192.168.1.101:8848" "192.168.1.102:8848" "192.168.1.103:8848")

for node in "${NODES[@]}"; do
    echo "检查节点: $node"
    curl -s "http://$node/nacos/v1/ns/operator/metrics" | jq '.status'
done

3.4 负载均衡配置

3.4.1 Nginx 配置

# /etc/nginx/conf.d/nacos.conf

upstream nacos-cluster {
    server 192.168.1.101:8848 weight=1 max_fails=2 fail_timeout=10s;
    server 192.168.1.102:8848 weight=1 max_fails=2 fail_timeout=10s;
    server 192.168.1.103:8848 weight=1 max_fails=2 fail_timeout=10s;
}

server {
    listen 80;
    server_name nacos.example.com;
    
    location / {
        proxy_pass http://nacos-cluster;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # 健康检查
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_connect_timeout 5s;
        proxy_send_timeout 10s;
        proxy_read_timeout 10s;
    }
    
    # 健康检查端点
    location /nacos/actuator/health {
        proxy_pass http://nacos-cluster;
        access_log off;
    }
}

3.4.2 HAProxy 配置

# /etc/haproxy/haproxy.cfg

global
    daemon
    maxconn 4096
    log stdout local0

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option httplog
    option dontlognull
    option redispatch
    retries 3

frontend nacos-frontend
    bind *:80
    default_backend nacos-backend

backend nacos-backend
    balance roundrobin
    option httpchk GET /nacos/actuator/health
    http-check expect status 200
    
    server nacos1 192.168.1.101:8848 check inter 5s rise 2 fall 3
    server nacos2 192.168.1.102:8848 check inter 5s rise 2 fall 3
    server nacos3 192.168.1.103:8848 check inter 5s rise 2 fall 3

listen stats
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 30s
    stats admin if TRUE

4. 配置文件详解

4.1 application.properties 详解

class NacosConfigManager:
    """Nacos 配置管理器"""
    
    def __init__(self):
        self.config_sections = self._initialize_config_sections()
    
    def _initialize_config_sections(self) -> Dict[str, Dict]:
        """初始化配置段"""
        return {
            "server": {
                "description": "服务器基础配置",
                "properties": {
                    "server.port": {
                        "default": "8848",
                        "description": "Nacos 服务端口",
                        "type": "int"
                    },
                    "server.servlet.contextPath": {
                        "default": "/nacos",
                        "description": "应用上下文路径",
                        "type": "string"
                    },
                    "server.tomcat.max-threads": {
                        "default": "200",
                        "description": "Tomcat 最大线程数",
                        "type": "int"
                    }
                }
            },
            "database": {
                "description": "数据库配置",
                "properties": {
                    "spring.datasource.platform": {
                        "default": "mysql",
                        "description": "数据库平台类型",
                        "type": "string",
                        "options": ["mysql", "derby"]
                    },
                    "db.num": {
                        "default": "1",
                        "description": "数据库实例数量",
                        "type": "int"
                    },
                    "db.url.0": {
                        "default": "jdbc:mysql://localhost:3306/nacos",
                        "description": "数据库连接 URL",
                        "type": "string"
                    },
                    "db.user.0": {
                        "default": "nacos",
                        "description": "数据库用户名",
                        "type": "string"
                    },
                    "db.password.0": {
                        "default": "nacos",
                        "description": "数据库密码",
                        "type": "string"
                    }
                }
            },
            "cluster": {
                "description": "集群配置",
                "properties": {
                    "nacos.inetutils.prefer-hostname-over-ip": {
                        "default": "false",
                        "description": "优先使用主机名而非 IP",
                        "type": "boolean"
                    },
                    "nacos.inetutils.ip-address": {
                        "default": "",
                        "description": "指定服务器 IP 地址",
                        "type": "string"
                    },
                    "nacos.server.port": {
                        "default": "8848",
                        "description": "集群通信端口",
                        "type": "int"
                    }
                }
            },
            "auth": {
                "description": "认证配置",
                "properties": {
                    "nacos.core.auth.enabled": {
                        "default": "false",
                        "description": "启用认证",
                        "type": "boolean"
                    },
                    "nacos.core.auth.system.type": {
                        "default": "nacos",
                        "description": "认证系统类型",
                        "type": "string"
                    },
                    "nacos.core.auth.plugin.nacos.token.secret.key": {
                        "default": "",
                        "description": "JWT Token 密钥",
                        "type": "string"
                    }
                }
            }
        }
    
    def generate_config(self, mode: DeploymentMode, 
                       custom_config: Dict = None) -> str:
        """生成配置文件"""
        config_lines = []
        config_lines.append("# Nacos 配置文件")
        config_lines.append(f"# 部署模式: {mode.value}")
        config_lines.append(f"# 生成时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
        config_lines.append("")
        
        for section_name, section in self.config_sections.items():
            config_lines.append(f"# {section['description']}")
            
            for prop_name, prop_info in section['properties'].items():
                if custom_config and prop_name in custom_config:
                    value = custom_config[prop_name]
                else:
                    value = prop_info['default']
                
                config_lines.append(f"{prop_name}={value}")
            
            config_lines.append("")
        
        return "\n".join(config_lines)
    
    def validate_config(self, config: Dict[str, str]) -> Dict[str, List[str]]:
        """验证配置"""
        errors = {}
        
        for section_name, section in self.config_sections.items():
            section_errors = []
            
            for prop_name, prop_info in section['properties'].items():
                if prop_name in config:
                    value = config[prop_name]
                    
                    # 类型检查
                    if prop_info['type'] == 'int':
                        try:
                            int(value)
                        except ValueError:
                            section_errors.append(f"{prop_name} 必须是整数")
                    
                    elif prop_info['type'] == 'boolean':
                        if value.lower() not in ['true', 'false']:
                            section_errors.append(f"{prop_name} 必须是 true 或 false")
                    
                    # 选项检查
                    if 'options' in prop_info:
                        if value not in prop_info['options']:
                            section_errors.append(
                                f"{prop_name} 必须是 {prop_info['options']} 中的一个"
                            )
            
            if section_errors:
                errors[section_name] = section_errors
        
        return errors

# 使用示例
if __name__ == "__main__":
    config_manager = NacosConfigManager()
    
    # 生成单机模式配置
    print("=== 单机模式配置 ===")
    standalone_config = {
        "server.port": "8848",
        "spring.datasource.platform": "derby"
    }
    
    config_content = config_manager.generate_config(
        DeploymentMode.STANDALONE, 
        standalone_config
    )
    print(config_content[:500] + "...")
    
    # 验证配置
    print("\n=== 配置验证 ===")
    test_config = {
        "server.port": "invalid_port",
        "nacos.core.auth.enabled": "maybe"
    }
    
    validation_errors = config_manager.validate_config(test_config)
    if validation_errors:
        print("配置错误:")
        for section, errors in validation_errors.items():
            print(f"  {section}:")
            for error in errors:
                print(f"    - {error}")
    else:
        print("配置验证通过")

4.2 JVM 参数优化

# startup.sh 中的 JVM 参数配置

# 基础内存配置
export JAVA_OPT="${JAVA_OPT} -Xms2g"          # 初始堆大小
export JAVA_OPT="${JAVA_OPT} -Xmx2g"          # 最大堆大小
export JAVA_OPT="${JAVA_OPT} -Xmn1g"          # 新生代大小

# GC 配置
export JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC"    # 使用 G1 垃圾收集器
export JAVA_OPT="${JAVA_OPT} -XX:MaxGCPauseMillis=200"  # 最大 GC 暂停时间
export JAVA_OPT="${JAVA_OPT} -XX:+UnlockExperimentalVMOptions"
export JAVA_OPT="${JAVA_OPT} -XX:+UseZGC"     # 使用 ZGC(JDK 11+)

# 内存溢出处理
export JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError"
export JAVA_OPT="${JAVA_OPT} -XX:HeapDumpPath=/opt/nacos/logs/"

# JIT 编译优化
export JAVA_OPT="${JAVA_OPT} -XX:+TieredCompilation"
export JAVA_OPT="${JAVA_OPT} -XX:TieredStopAtLevel=1"

# 网络优化
export JAVA_OPT="${JAVA_OPT} -Djava.net.preferIPv4Stack=true"
export JAVA_OPT="${JAVA_OPT} -Dfile.encoding=UTF-8"

# 日志配置
export JAVA_OPT="${JAVA_OPT} -Dnacos.logs.path=/opt/nacos/logs"
export JAVA_OPT="${JAVA_OPT} -Dlogging.config=/opt/nacos/conf/nacos-logback.xml"

5. 验证安装

5.1 访问控制台

安装完成后,通过浏览器访问: - URL: http://localhost:8848/nacos - 默认账号: nacos - 默认密码: nacos

5.2 API 测试

# 1. 健康检查
curl http://localhost:8848/nacos/actuator/health

# 2. 获取服务列表
curl "http://localhost:8848/nacos/v1/ns/service/list?pageNo=1&pageSize=10"

# 3. 注册服务
curl -X POST "http://localhost:8848/nacos/v1/ns/instance" \
  -d "serviceName=test-service&ip=192.168.1.100&port=8080"

# 4. 发现服务
curl "http://localhost:8848/nacos/v1/ns/instance/list?serviceName=test-service"

5.3 配置测试

# 1. 发布配置
curl -X POST "http://localhost:8848/nacos/v1/cs/configs" \
  -d "dataId=test.properties&group=DEFAULT_GROUP&content=test.key=test.value"

# 2. 获取配置
curl "http://localhost:8848/nacos/v1/cs/configs?dataId=test.properties&group=DEFAULT_GROUP"

# 3. 删除配置
curl -X DELETE "http://localhost:8848/nacos/v1/cs/configs?dataId=test.properties&group=DEFAULT_GROUP"

6. 常见问题

6.1 启动失败

问题: Nacos 启动失败

解决方案:

# 1. 检查 Java 版本
java -version

# 2. 检查端口占用
netstat -tlnp | grep 8848

# 3. 查看启动日志
tail -f logs/start.out
tail -f logs/nacos.log

# 4. 检查配置文件
cat conf/application.properties

6.2 数据库连接失败

问题: MySQL 数据库连接失败

解决方案:

# 1. 测试数据库连接
mysql -h localhost -u nacos -p nacos

# 2. 检查数据库配置
grep -E "^db\." conf/application.properties

# 3. 检查防火墙
sudo ufw status
sudo firewall-cmd --list-ports

# 4. 检查 MySQL 服务状态
sudo systemctl status mysql

6.3 集群节点无法通信

问题: 集群节点之间无法通信

解决方案:

# 1. 检查集群配置
cat conf/cluster.conf

# 2. 测试节点连通性
telnet 192.168.1.101 8848

# 3. 检查防火墙规则
sudo iptables -L

# 4. 查看集群状态
curl "http://localhost:8848/nacos/v1/ns/operator/cluster"

7. 总结

7.1 核心要点

  1. 环境准备: 确保 JDK、数据库等环境满足要求
  2. 模式选择: 根据需求选择单机或集群模式
  3. 配置优化: 合理配置 JVM 参数和应用参数
  4. 安全加固: 启用认证、配置防火墙、使用 HTTPS
  5. 监控运维: 配置日志、监控指标、健康检查

7.2 最佳实践

  1. 生产环境: 使用集群模式 + 外部数据库
  2. 资源规划: 合理分配 CPU、内存、磁盘资源
  3. 网络规划: 配置负载均衡、防火墙规则
  4. 备份策略: 定期备份配置和数据
  5. 版本管理: 使用稳定版本,制定升级计划

7.3 下一步学习

在下一章中,我们将学习: - 服务注册与发现的原理和实践 - 健康检查机制的配置 - 负载均衡策略的选择 - 服务路由规则的设置

通过本章的学习,你已经掌握了 Nacos 的安装和基础配置。接下来让我们深入学习服务注册与发现的核心功能!