一台阿里云服务器部署两个SpringBoot项目的最佳实践?

在单台阿里云服务器上部署两个 Spring Boot 项目,最佳实践的核心原则是:隔离性、可维护性、自动化和安全性

以下是经过生产环境验证的最佳实践方案,分为 架构选型具体实施步骤关键注意事项 三部分。


一、 架构选型推荐

方案 适用场景 优点 缺点
Nginx + Systemd (推荐) 大多数中小型项目 资源占用低、配置灵活、易于监控、无需额外中间件 需要手动配置 Nginx 反向X_X
Docker Compose 希望环境一致、快速迁移 环境隔离好、启动停止方便、依赖管理简单 学习成本稍高,需安装 Docker
Spring Cloud Gateway / K8s 大型微服务架构 功能强大、扩展性强 过度设计,小项目不推荐

强烈建议采用 Nginx + SystemdDocker Compose 方案。
以下以 Nginx + Systemd 为例(最轻量、最常用),并附带 Docker 方案简述。


二、 最佳实践详细步骤(Nginx + Systemd)

1. 项目打包与部署结构

  • 将两个 Spring Boot 项目分别打包为独立的 JAR 文件(如 app1.jar, app2.jar)。
  • 创建统一目录结构,例如:
    /opt/apps/
    ├── app1/
    │   ├── app1.jar
    │   ├── application.yml
    │   └── logs/
    ├── app2/
    │   ├── app2.jar
    │   ├── application.yml
    │   └── logs/

2. 使用 Systemd 管理服务(关键!)

不要使用 nohup java -jar ... & 这种方式,它难以重启、日志混乱、无法开机自启。

为每个项目创建 systemd 服务文件:

# /etc/systemd/system/app1.service
[Unit]
Description=App1 Service
After=network.target

[Service]
Type=simple
User=root  # 建议使用专用用户,如 deploy
WorkingDirectory=/opt/apps/app1
ExecStart=/usr/bin/java -Xms512m -Xmx1024m -jar /opt/apps/app1/app1.jar --spring.profiles.active=prod
ExecStop=/bin/kill -SIGTERM $MAINPID
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

💡 注意:

  • 设置 -Xms-Xmx 防止内存溢出。
  • 指定 WorkingDirectory 和日志路径。
  • 使用 --spring.profiles.active 区分环境配置。

加载并启用服务:

sudo systemctl daemon-reload
sudo systemctl enable app1.service
sudo systemctl start app1.service
sudo systemctl status app1.service

app2 重复上述操作,创建 app2.service

3. 配置 Nginx 反向X_X

通过域名或端口区分两个项目。

方式 A:不同端口(简单)

  • App1: http://your-ip:8081
  • App2: http://your-ip:8082

方式 B:不同子域名(推荐,更专业)
假设你有域名 example.com

  • App1: app1.example.com → X_X到 localhost:8081
  • App2: app2.example.com → X_X到 localhost:8082

Nginx 配置示例 (/etc/nginx/conf.d/apps.conf):

# App1 配置
server {
    listen 80;
    server_name app1.example.com;

    location / {
        proxy_pass http://127.0.0.1:8081;
        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;
    }
}

# App2 配置
server {
    listen 80;
    server_name app2.example.com;

    location / {
        proxy_pass http://127.0.0.1:8082;
        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;
    }
}

重载 Nginx:

sudo nginx -t && sudo nginx -s reload

4. 安全组配置

在阿里云控制台 安全组 中:

  • 开放 HTTP (80) 和 HTTPS (443) 端口。
  • 关闭 8081、8082 等内部应用端口,只允许 Nginx 访问。
  • 仅对运维 IP 开放 SSH (22) 端口。

三、 替代方案:Docker Compose(更现代)

如果你熟悉 Docker,这是更优雅的方式:

# docker-compose.yml
version: '3'
services:
  app1:
    image: openjdk:17-jdk-slim
    container_name: app1
    ports:
      - "8081:8081"
    volumes:
      - ./app1:/app
    command: ["java", "-jar", "/app/app1.jar"]
    restart: always

  app2:
    image: openjdk:17-jdk-slim
    container_name: app2
    ports:
      - "8082:8082"
    volumes:
      - ./app2:/app
    command: ["java", "-jar", "/app/app2.jar"]
    restart: always

  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app1
      - app2
    restart: always

然后通过 Nginx 容器X_X到 app1:8081app2:8082


四、 关键注意事项与优化建议

1. 资源隔离与限制

  • CPU/Memory 限制:在 Systemd 中可设置 MemoryLimit=,或在 Docker 中使用 mem_limit:
  • 避免争抢资源:确保 JVM 堆内存总和不超过服务器物理内存的 70%~80%,留出空间给 OS 和 Nginx。

2. 日志管理

  • 集中日志:不要只看控制台。配置 Logback/Log4j2 输出到文件,并使用 logrotate 自动切割日志。
  • ELK/Loki:如果预算允许,接入阿里云 SLS(日志服务)或使用 Loki+Grafana 进行日志收集和分析。

3. 数据库连接

  • 共享数据库? 如果两个项目共用一个 MySQL 实例,务必:
    • 使用不同的 Schema 或前缀表名。
    • 合理设置连接池大小(HikariCP),避免连接耗尽。
  • 独立数据库? 更推荐每个项目拥有独立的数据库实例或 Schema,便于维护和故障隔离。

4. 健康检查与监控

  • 暴露 Actuator 端点 /actuator/health
  • 使用阿里云云监控或 Prometheus + Grafana 监控 CPU、内存、JVM GC 情况。
  • 设置告警:当 CPU > 80% 或内存 > 90% 时通知。

5. 备份与恢复

  • 定期备份数据库。
  • 保存配置文件版本控制(Git)。
  • 考虑使用阿里云 ECS 快照功能,定期创建系统盘和数据盘快照。

五、 总结:最佳实践清单

必须做:

  • 使用 Systemd 或 Docker 管理服务生命周期。
  • 使用 Nginx 作为反向X_X,隐藏后端端口。
  • 配置阿里云安全组,仅开放必要端口。
  • 设置 JVM 内存参数,防止 OOM。
  • 配置日志轮转(logrotate)。

避免做:

  • 直接暴露 Java 进程端口到公网。
  • 使用 nohup & 运行应用。
  • 两个项目共用同一个数据库账号且无权限隔离。
  • 忽略监控和日志。

通过以上方案,你可以在一台阿里云服务器上稳定、安全、高效地运行多个 Spring Boot 项目。

未经允许不得转载:CLOUD技术博 » 一台阿里云服务器部署两个SpringBoot项目的最佳实践?