SpringBoot项目在阿里云服务器上如何通过Nginx实现多项目部署?

SpringBoot 项目在阿里云服务器上通过 Nginx 实现多项目部署

整体架构

用户请求 → 阿里云ECS(公网IP) → Nginx(反向X_X) → 多个SpringBoot应用(不同端口)
                                    │
                            ┌───────┼────────┐
                            ▼       ▼        ▼
                        :8081   :8082    :8083
                     UserApp  OrderApp  ProductApp

一、服务器环境准备

1. 安装 JDK 和 Maven(如果尚未安装)

# 检查Java版本
java -version

# 安装JDK 17(示例)
sudo yum install java-17-openjdk-devel -y

# 验证
java -version
javac -version

2. 上传并打包 SpringBoot 应用

# 创建应用目录
mkdir -p /opt/apps/user-service
mkdir -p /opt/apps/order-service
mkdir -p /opt/apps/product-service

# 将各项目的 jar 包上传到对应目录
scp user-service.jar root@your-server:/opt/apps/user-service/
scp order-service.jar root@your-server:/opt/apps/order-service/
scp product-service.jar root@your-server:/opt/apps/product-service/

3. 启动各 SpringBoot 应用

# 以 nohup 方式后台启动
nohup java -jar /opt/apps/user-service/user-service.jar --server.port=8081 > /opt/apps/user-service/logs.log 2>&1 &
nohup java -jar /opt/apps/order-service/order-service.jar --server.port=8082 > /opt/apps/order-service/logs.log 2>&1 &
nohup java -jar /opt/apps/product-service/product-service.jar --server.port=8083 > /opt/apps/product-service/logs.log 2>&1 &

# 查看进程
ps -ef | grep java

推荐:使用 systemd 管理进程,便于开机自启和重启。

4. 创建 systemd 服务文件(可选但推荐)

# /etc/systemd/system/user-service.service
[Unit]
Description=User Service
After=syslog.target network.target

[Service]
User=root
ExecStart=/usr/bin/java -jar /opt/apps/user-service/user-service.jar --server.port=8081
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable user-service
sudo systemctl start user-service
sudo systemctl status user-service

二、安装 Nginx

# CentOS/RHEL
sudo yum install nginx -y

# Ubuntu/Debian
sudo apt update
sudo apt install nginx -y

# 启动 Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx

开放防火墙端口

# CentOS 7+
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
sudo firewall-cmd --zone=public --add-port=443/tcp --permanent
sudo firewall-cmd --reload

# Ubuntu (ufw)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

⚠️ 注意:8081、8082、8083 等内部端口不要对外开放,只通过 Nginx 反向X_X访问。


三、Nginx 配置多项目部署

方案一:基于域名的虚拟主机(推荐)

每个项目绑定独立域名:

# /etc/nginx/conf.d/user-service.conf
server {
    listen       80;
    server_name  user.example.com;

    # 日志
    access_log  /var/log/nginx/user-access.log;
    error_log   /var/log/nginx/user-error.log;

    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;

        # WebSocket 支持(如果需要)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # 超时设置
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # 静态资源缓存
    location ~* .(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}
# /etc/nginx/conf.d/order-service.conf
server {
    listen       80;
    server_name  order.example.com;

    access_log  /var/log/nginx/order-access.log;
    error_log   /var/log/nginx/order-error.log;

    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;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
# /etc/nginx/conf.d/product-service.conf
server {
    listen       80;
    server_name  product.example.com;

    access_log  /var/log/nginx/product-access.log;
    error_log   /var/log/nginx/product-error.log;

    location / {
        proxy_pass http://127.0.0.1:8083;
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

方案二:基于路径的反向X_X(单域名多应用)

所有项目共用一个域名,通过 URL 路径区分:

# /etc/nginx/conf.d/multi-app.conf
server {
    listen       80;
    server_name  www.example.com;

    # === 用户服务 ===
    location /api/user/ {
        proxy_pass http://127.0.0.1:8081/api/user/;
        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;
    }

    # === 订单服务 ===
    location /api/order/ {
        proxy_pass http://127.0.0.1:8082/api/order/;
        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;
    }

    # === 商品服务 ===
    location /api/product/ {
        proxy_pass http://127.0.0.1:8083/api/product/;
        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;
    }

    # 默认首页或网关入口
    location / {
        return 302 /api/user/login;
    }
}

💡 关键提示proxy_pass 末尾的 / 会影响路径传递行为:

  • proxy_pass http://127.0.0.1:8081/;/api/user/info 转发为 /info
  • proxy_pass http://127.0.0.1:8081;/api/user/info 转发为 /api/user/info

根据 SpringBoot 应用的 context-path 配置选择合适的方式。

方案三:带 HTTPS 的完整配置(生产推荐)

# /etc/nginx/conf.d/secure-multi-app.conf
server {
    listen       80;
    server_name  www.example.com api.example.com;
    # 强制 HTTP → HTTPS 重定向
    return 301 https://$host$request_uri;
}

server {
    listen       443 ssl http2;
    server_name  www.example.com api.example.com;

    # SSL 证书配置
    ssl_certificate     /etc/nginx/ssl/www.example.com.pem;
    ssl_certificate_key /etc/nginx/ssl/www.example.com.key;

    # SSL 优化参数
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # 日志
    access_log  /var/log/nginx/secure-access.log;
    error_log   /var/log/nginx/secure-error.log;

    # 安全头
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    # --- 用户服务 ---
    location /api/user/ {
        proxy_pass http://127.0.0.1:8081/api/user/;
        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;

        # 限流(可选)
        limit_req zone=user_limit burst=20 nodelay;
    }

    # --- 订单服务 ---
    location /api/order/ {
        proxy_pass http://127.0.0.1:8082/api/order/;
        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;

        limit_req zone=order_limit burst=20 nodelay;
    }

    # --- 商品服务 ---
    location /api/product/ {
        proxy_pass http://127.0.0.1:8083/api/product/;
        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;

        limit_req zone=product_limit burst=20 nodelay;
    }

    # 静态资源
    location ~* .(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
        root /var/www/static;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # 自定义错误页
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}

定义限流区域(放在 http {} 块中,如 /etc/nginx/nginx.conf):

http {
    # ... 其他配置 ...

    limit_req_zone $binary_remote_addr zone=user_limit:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=order_limit:10m rate=5r/s;
    limit_req_zone $binary_remote_addr zone=product_limit:10m rate=10r/s;

    include /etc/nginx/conf.d/*.conf;
}

四、Nginx 常用命令

# 测试配置文件语法
sudo nginx -t

# 重新加载配置(不中断服务)
sudo nginx -s reload

# 查看 Nginx 状态
sudo systemctl status nginx

# 查看访问日志
tail -f /var/log/nginx/access.log

# 查看错误日志
tail -f /var/log/nginx/error.log

五、阿里云额外配置

1. 安全组规则

在阿里云控制台 → ECS → 安全组中添加规则:

方向 协议 端口范围 授权对象 描述
入方向 TCP 80 0.0.0.0/0 HTTP
入方向 TCP 443 0.0.0.0/0 HTTPS
入方向 TCP 22 你的IP/32 SSH

不要开放 8081、8082、8083 等内部应用端口!

2. DNS 解析

在阿里云 DNS 控制台添加 A 记录:

user.example.com      →  你的ECS公网IP
order.example.com     →  你的ECS公网IP
product.example.com   →  你的ECS公网IP
www.example.com       →  你的ECS公网IP

3. SSL 证书申请(Let’s Encrypt 免费证书)

# 安装 certbot
sudo yum install certbot python3-certbot-nginx -y

# 获取证书(自动配置 Nginx)
sudo certbot --nginx -d www.example.com -d api.example.com

# 自动续期
sudo crontab -e
# 添加: 0 3 * * 1 certbot renew --quiet

六、SpringBoot 端注意事项

1. 配置 application.yml

server:
  port: 8081          # 实际监听端口
  servlet:
    context-path: /api/user   # 如果使用了基于路径的方案

# 信任X_X头(让 SpringBoot 正确识别真实 IP)
server:
  forward-headers-strategy: native

2. CORS 跨域配置(如果前端与后端不同源)

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https://www.example.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

3. 统一 API 前缀建议

应用 端口 Context Path 示例请求
user-service 8081 /api/user GET /api/user/profile
order-service 8082 /api/order POST /api/order/create
product-service 8083 /api/product GET /api/product/list

七、高可用进阶方案

1. Nginx 负载均衡(同一应用多实例)

upstream user-service-cluster {
    server 127.0.0.1:8081 weight=5;
    server 127.0.0.1:8084 weight=5;
    keepalive 32;
}

server {
    location /api/user/ {
        proxy_pass http://user-service-cluster/api/user/;
        # ... 其他 proxy 配置 ...
    }
}

2. Nginx Plus / OpenResty(高级功能)

  • 动态健康检查
  • 微服务路由
  • 灰度发布

3. Docker + Nginx 容器化部署

# Dockerfile for Nginx
FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY conf.d/ /etc/nginx/conf.d/
# docker-compose.yml
version: '3.8'
services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/nginx/ssl
      - ./logs/nginx:/var/log/nginx
    depends_on:
      - user-service
      - order-service
      - product-service
    restart: always

  user-service:
    build: ./user-service
    ports:
      - "8081:8081"
    restart: always

  order-service:
    build: ./order-service
    ports:
      - "8082:8082"
    restart: always

  product-service:
    build: ./product-service
    ports:
      - "8083:8083"
    restart: always

八、常见问题排查

问题 可能原因 解决方案
502 Bad Gateway 后端服务未启动 检查 ps -ef | grep java
504 Gateway Timeout 后端响应慢 增加 proxy_read_timeout
404 Not Found 路径不匹配 检查 proxy_pass 末尾 /
跨域错误 CORS 未配置 后端添加 CORS 配置
无法访问 防火墙/安全组 检查阿里云安全组和系统防火墙
SSL 报错 证书过期/格式错误 openssl x509 -in cert.pem -text 检查
# 快速诊断命令
curl -I http://127.0.0.1:8081/api/user/test      # 直接测后端
curl -I http://localhost/api/user/test             # 经 Nginx 测
sudo nginx -t                                      # 检查 Nginx 配置
journalctl -u nginx -f                             # 查看 Nginx 日志

总结流程图

┌─────────────┐     ┌──────────────┐     ┌─────────────────┐
│  浏览器/A   │────▶│   Nginx      │────▶│  SpringBoot App │
│  客户端     │     │  (端口80/443) │     │  (端口8081+)    │
└─────────────┘     └──────────────┘     └─────────────────┘
                       │                      │
               ┌───────┴───────┐         ┌────┴────┐
               │ 域名路由      │         │ 数据库  │
               │ 路径路由      │         │ Redis   │
               │ 负载均衡      │         │ MQ      │
               └───────────────┘         └─────────┘

核心要点

  1. Nginx 作为唯一入口,对外只开放 80/443
  2. 每个 SpringBoot 应用监听不同内部端口
  3. 通过域名或路径将请求分发到对应应用
  4. 配置正确的 proxy headers 确保后端能获取真实客户端信息
  5. 生产环境务必启用 HTTPS
未经允许不得转载:CLOUD技术博 » SpringBoot项目在阿里云服务器上如何通过Nginx实现多项目部署?