Skip to content
清晨的一缕阳光
返回

Nacos 高可用部署

Nacos 高可用部署

高可用架构

集群架构

┌─────────────────────────────────────────────────────┐
│                    Nginx / SLB                      │
│              (负载均衡器)                            │
└───────────────────┬─────────────────────────────────┘

        ┌───────────┼───────────┐
        │           │           │
        ▼           ▼           ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│   Nacos 1   │ │   Nacos 2   │ │   Nacos 3   │
│  :8848      │ │  :8848      │ │  :8848      │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
       │               │               │
       └───────────────┼───────────────┘

              ┌────────▼────────┐
              │   MySQL 集群     │
              │  (数据持久化)    │
              └─────────────────┘

核心特性

集群部署

1. 环境准备

# 服务器规划
nacos1: 192.168.1.101
nacos2: 192.168.1.102
nacos3: 192.168.1.103

# MySQL 准备
mysql: 192.168.1.200:3306
database: nacos_config
user: nacos
password: nacos123

2. 数据库初始化

-- 创建数据库
CREATE DATABASE nacos_config CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 初始化表结构
SOURCE /path/to/nacos/conf/nacos-mysql.sql;

3. 配置文件

application.properties(所有节点)

# 集群模式
nacos.core.auth.enabled=true
nacos.core.auth.server.identity.key=serverIdentity
nacos.core.auth.server.identity.value=security

# 数据源配置
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://192.168.1.200:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai
db.user=nacos
db.password=nacos123

# 集群配置
nacos.naming.cluster.conf=192.168.1.101:8848,192.168.1.102:8848,192.168.1.103:8848

# 节点标识
server.tomcat.basedir=/opt/nacos/tomcat

cluster.conf(所有节点相同)

192.168.1.101:8848
192.168.1.102:8848
192.168.1.103:8848

4. 启动集群

# 节点 1
cd /opt/nacos/bin
sh startup.sh -m cluster

# 节点 2
cd /opt/nacos/bin
sh startup.sh -m cluster

# 节点 3
cd /opt/nacos/bin
sh startup.sh -m cluster

5. 验证集群

# 查看集群状态
curl http://192.168.1.101:8848/nacos/v1/ns/operator/servers

# 查看节点健康状态
curl http://192.168.1.101:8848/nacos/v1/console/health/readiness

Nginx 负载均衡配置

基础配置

upstream nacos_cluster {
    server 192.168.1.101:8848 weight=1 max_fails=3 fail_timeout=30s;
    server 192.168.1.102:8848 weight=1 max_fails=3 fail_timeout=30s;
    server 192.168.1.103:8848 weight=1 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name nacos.example.com;
    
    location /nacos {
        proxy_pass http://nacos_cluster/nacos;
        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_connect_timeout 10s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # 缓冲配置
        proxy_buffer_size 4k;
        proxy_buffers 4 32k;
        proxy_busy_buffers_size 64k;
    }
}

HTTPS 配置

server {
    listen 443 ssl http2;
    server_name nacos.example.com;
    
    ssl_certificate /etc/nginx/ssl/nacos.crt;
    ssl_certificate_key /etc/nginx/ssl/nacos.key;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:10m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    location /nacos {
        proxy_pass http://nacos_cluster/nacos;
        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;
    }
}

# HTTP 重定向到 HTTPS
server {
    listen 80;
    server_name nacos.example.com;
    return 301 https://$server_name$request_uri;
}

Docker 部署

docker-compose.yml

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: nacos-mysql
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: nacos_config
      MYSQL_USER: nacos
      MYSQL_PASSWORD: nacos123
    volumes:
      - mysql_data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - nacos-network

  nacos1:
    image: nacos/nacos-server:2.2.0
    container_name: nacos1
    environment:
      - MODE=cluster
      - NACOS_SERVERS=nacos1:8848;nacos2:8848;nacos3:8848
      - SPRING_DATASOURCE_PLATFORM=mysql
      - MYSQL_SERVICE_HOST=mysql
      - MYSQL_SERVICE_PORT=3306
      - MYSQL_SERVICE_DB_NAME=nacos_config
      - MYSQL_SERVICE_USER=nacos
      - MYSQL_SERVICE_PASSWORD=nacos123
      - JVM_XMS=512m
      - JVM_XMX=512m
    ports:
      - "8848:8848"
    depends_on:
      - mysql
    networks:
      - nacos-network

  nacos2:
    image: nacos/nacos-server:2.2.0
    container_name: nacos2
    environment:
      - MODE=cluster
      - NACOS_SERVERS=nacos1:8848;nacos2:8848;nacos3:8848
      - SPRING_DATASOURCE_PLATFORM=mysql
      - MYSQL_SERVICE_HOST=mysql
      - MYSQL_SERVICE_PORT=3306
      - MYSQL_SERVICE_DB_NAME=nacos_config
      - MYSQL_SERVICE_USER=nacos
      - MYSQL_SERVICE_PASSWORD=nacos123
      - JVM_XMS=512m
      - JVM_XMX=512m
    ports:
      - "8849:8848"
    depends_on:
      - mysql
    networks:
      - nacos-network

  nacos3:
    image: nacos/nacos-server:2.2.0
    container_name: nacos3
    environment:
      - MODE=cluster
      - NACOS_SERVERS=nacos1:8848;nacos2:8848;nacos3:8848
      - SPRING_DATASOURCE_PLATFORM=mysql
      - MYSQL_SERVICE_HOST=mysql
      - MYSQL_SERVICE_PORT=3306
      - MYSQL_SERVICE_DB_NAME=nacos_config
      - MYSQL_SERVICE_USER=nacos
      - MYSQL_SERVICE_PASSWORD=nacos123
      - JVM_XMS=512m
      - JVM_XMX=512m
    ports:
      - "8850:8848"
    depends_on:
      - mysql
    networks:
      - nacos-network

  nginx:
    image: nginx:alpine
    container_name: nacos-nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - nacos1
      - nacos2
      - nacos3
    networks:
      - nacos-network

volumes:
  mysql_data:

networks:
  nacos-network:
    driver: bridge

K8s 部署

StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nacos
  labels:
    app: nacos
spec:
  serviceName: nacos
  replicas: 3
  selector:
    matchLabels:
      app: nacos
  template:
    metadata:
      labels:
        app: nacos
    spec:
      containers:
        - name: nacos
          image: nacos/nacos-server:2.2.0
          ports:
            - containerPort: 8848
              name: client
            - containerPort: 9848
              name: client-rpc
            - containerPort: 9849
              name: raft-rpc
          env:
            - name: MODE
              value: "cluster"
            - name: NACOS_SERVERS
              value: "nacos-0.nacos:8848;nacos-1.nacos:8848;nacos-2.nacos:8848"
            - name: SPRING_DATASOURCE_PLATFORM
              value: "mysql"
            - name: MYSQL_SERVICE_HOST
              value: "mysql.default.svc.cluster.local"
            - name: MYSQL_SERVICE_PORT
              value: "3306"
            - name: MYSQL_SERVICE_DB_NAME
              value: "nacos_config"
            - name: MYSQL_SERVICE_USER
              value: "nacos"
            - name: MYSQL_SERVICE_PASSWORD
              value: "nacos123"
          resources:
            requests:
              memory: "512Mi"
              cpu: "250m"
            limits:
              memory: "1Gi"
              cpu: "500m"
          livenessProbe:
            httpGet:
              path: /nacos/v1/console/health/readiness
              port: 8848
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /nacos/v1/console/health/readiness
              port: 8848
            initialDelaySeconds: 10
            periodSeconds: 5

Service

apiVersion: v1
kind: Service
metadata:
  name: nacos
  labels:
    app: nacos
spec:
  type: ClusterIP
  clusterIP: None
  ports:
    - port: 8848
      name: client
      targetPort: 8848
    - port: 9848
      name: client-rpc
      targetPort: 9848
    - port: 9849
      name: raft-rpc
      targetPort: 9849
  selector:
    app: nacos
---
apiVersion: v1
kind: Service
metadata:
  name: nacos-headless
  labels:
    app: nacos
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8848
      name: http
  selector:
    app: nacos

性能优化

JVM 配置

# bin/startup.sh 中修改
JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g"
JAVA_OPT="${JAVA_OPT} -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError"
JAVA_OPT="${JAVA_OPT} -XX:HeapDumpPath=/opt/nacos/logs/java_heapdump.hprof"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"

数据库连接池

# application.properties
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://mysql:3306/nacos_config?useUnicode=true&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false
db.user=nacos
db.password=nacos123

# HikariCP 配置
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=50
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.max-lifetime=1800000

日志配置

<!-- conf/nacos-logback.xml -->
<configuration>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${nacos.home}/logs/nacos.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${nacos.home}/logs/nacos.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
            <maxFileSize>100MB</maxFileSize>
            <maxHistory>30</maxHistory>
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="FILE"/>
    </root>
</configuration>

监控告警

Prometheus 配置

# prometheus.yml
scrape_configs:
  - job_name: 'nacos'
    static_configs:
      - targets: ['nacos1:8848', 'nacos2:8848', 'nacos3:8848']
    metrics_path: '/nacos/actuator/prometheus'

Grafana 面板

导入 Nacos 监控面板(Dashboard ID: 10475)

告警规则

# alert_rules.yml
groups:
  - name: nacos
    rules:
      - alert: NacosNodeDown
        expr: up{job="nacos"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Nacos 节点 {{ $labels.instance }} 宕机"
          description: "Nacos 节点 {{ $labels.instance }} 已经宕机超过 1 分钟"
      
      - alert: NacosServiceCountLow
        expr: nacos_naming_service_count < 10
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Nacos 服务数量过低"
          description: "Nacos 注册的服务数量低于 10 个"

常见问题

1. 集群启动失败

问题:节点无法加入集群

解决方案

2. 数据不一致

问题:集群节点数据不一致

解决方案

3. 性能问题

问题:集群响应慢

解决方案

总结

Nacos 集群部署可以实现服务注册中心的高可用性,通过合理的架构设计和配置优化,可以确保系统的稳定运行。

在生产环境中,建议部署至少 3 个节点,使用独立的数据库,并配置完善的监控告警机制。


分享这篇文章到:

上一篇文章
Spring Boot OpenAPI 3.0 文档
下一篇文章
Deepseek为什么会让世界震惊