轻量应用服务器部署指南(腾讯云)

把 Spring Boot 应用放到腾讯云轻量应用服务器上,核心是三件事:机器环境(Java、MySQL、Nginx)、生产配置与证书、用 systemd 把进程管住。下面按一台 OpenCloudOS 9 实例来写。

轻量应用服务器(腾讯云)

查看服务器信息

cat /etc/os-release

# NAME="OpenCloudOS"
# VERSION="9.4"
# ID="opencloudos"
# ID_LIKE="opencloudos"
# VERSION_ID="9.4"
# PLATFORM_ID="platform:oc9"
# PRETTY_NAME="OpenCloudOS 9.4"
# ANSI_COLOR="0;31"
# CPE_NAME="cpe:/o:opencloudos:opencloudos:9"
# HOME_URL="https://www.opencloudos.org/"
# BUG_REPORT_URL="https://bugs.opencloudos.tech/"
uname -a
# Linux VM-4-6-opencloudos 6.6.114-43.oc9.x86_64 #1 SMP Fri Nov  7 15:35:09 CST 2025 x86_64 x86_64 x86_64 GNU/Linux

arch
# x86_64

更新系统、安装必要工具

# 更新系统
sudo dnf update -y

# 安装编译工具和依赖
sudo dnf install -y git zsh curl wget gcc make ncurses-devel

终端美化(Zsh + Oh My Zsh)

# 验证 zsh 是否可用
which zsh
# /usr/bin/zsh

官方脚本和国内镜像二选一。官方脚本会克隆仓库并生成 ~/.zshrc;走 Gitee 时要自己拷模板。

# 方案一:官方脚本
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

# 方案二:国内镜像(访问 GitHub 困难时)
git clone https://gitee.com/mirrors/oh-my-zsh.git ~/.oh-my-zsh
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
# 切换当前用户的默认 shell
chsh -s $(which zsh)

# 重新登录或启动新终端,验证安装是否成功
echo $SHELL

安装 Java 环境(Java 17)

Spring Boot 3 最低 Java 17;Boot 4 同样要求 17 及以上。生产用 17 或 21(LTS)都可以。

# OpenCloudOS 9 默认使用 dnf
sudo dnf install -y java-17-openjdk-devel

# 验证安装
java -version

安装 MySQL

OpenCloudOS 9 的 AppStream 里通常是 mysql-server,服务名是 mysqld。若 dnf 提示冲突或装到的是 MariaDB,先确认服务名(mysqldmariadb),或改用 MySQL 官方仓库的 mysql-community-server

# 安装 MySQL 服务器
sudo dnf install -y mysql-server mysql

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

# 查看服务状态
sudo systemctl status mysqld

# 查看 MySQL 监听的端口和地址(OpenCloudOS 9 默认没有 netstat,用 ss)
sudo ss -tlnp | grep -E 'mysql|3306'
# MySQL 安装后需要设置 root 密码
sudo mysql_secure_installation
# 按照提示:
# - 输入当前 root 密码(首次安装密码为空,直接回车;官方仓库安装则先看 /var/log/mysqld.log 里的临时密码)
# - 设置密码强度验证策略(建议选 0 或 1)
# - 设置新的 root 密码
# - 删除匿名用户(选 Y)
# - 禁止远程 root 登录(选 Y)
# - 删除测试数据库(选 Y)
# - 重新加载权限表(选 Y)

# 使用密码登录
sudo mysql -u root -p
-- 查看当前用户
SELECT USER(), CURRENT_USER();
-- 创建数据库
CREATE DATABASE IF NOT EXISTS springboot_app DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 创建用户
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';

-- 授予权限
GRANT ALL PRIVILEGES ON springboot_app.* TO 'app_user'@'localhost';

-- 刷新权限
FLUSH PRIVILEGES;

-- 查看创建结果
SELECT user, host FROM mysql.user WHERE user = 'app_user';
SHOW GRANTS FOR 'app_user'@'localhost';

MySQL 8 默认认证插件是 caching_sha2_password。Spring Boot 使用的 MySQL Connector/J 8.0.9 及以上已经支持,不必再改成已过时的 mysql_native_password(MySQL 8.4 起该插件已弃用)。只有极老的客户端连不上时才需要改插件。

-- 仅当旧客户端不支持 caching_sha2_password 时才执行
ALTER USER 'app_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'StrongPassword123!';
FLUSH PRIVILEGES;
SELECT user, host, plugin FROM mysql.user WHERE user = 'app_user';
# 新开一个终端窗口,使用新创建的用户登录
mysql -u app_user -p springboot_app

# 在轻量应用服务器,上传 myapp.sql 到 /opt/myapp/ 目录,然后导入数据
mysql -u app_user -p springboot_app < /opt/myapp/myapp.sql

安装 Nginx

# 安装 nginx
sudo dnf install -y nginx

安装后,Nginx 的配置文件位于 /etc/nginx/,主配置文件为 /etc/nginx/nginx.conf。OpenCloudOS、RHEL 系站点配置放在 /etc/nginx/conf.d/sites-enabled 是 Debian 布局,目录不存在时不要照搬)。把下面这段存成 /etc/nginx/conf.d/app.conf 之类的文件。这是静态站点(8443),和后面 Spring Boot 监听的 443 是两套 HTTPS,不要混成同一份配置。

server {
    listen 8443 ssl;
    listen [::]:8443 ssl;
    server_name app.izhao.com.cn;   # 域名已解析再填,如 www.yourdomain.com

    ssl_certificate     /opt/yizhao/ssl/app.izhao.com.cn_bundle.crt;
    ssl_certificate_key /opt/yizhao/ssl/app.izhao.com.cn.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    root /opt/yizhao/www;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ /index.html;
    }
}
# 测试配置是否成功(改过 conf.d 后要测)
sudo nginx -t
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
sudo systemctl status nginx
sudo systemctl start nginx
sudo systemctl reload nginx
sudo systemctl restart nginx
sudo systemctl enable nginx

防火墙配置

轻量应用服务器有两层过滤:控制台「防火墙」(安全组)和机器上的 firewalld。只开其中一层,另一层仍会拦。数据库只给本机 Java 用时,不要对公网开放 3306。

# 安装 firewalld
sudo dnf install -y firewalld

# 启动并启用
sudo systemctl start firewalld
sudo systemctl enable firewalld

# 检查状态
sudo systemctl status firewalld
# 开放端口(22、80、443、8443 按实际对外服务开;8080、9443 仅在确实对公网提供时再开)
sudo firewall-cmd --permanent --add-port=22/tcp
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=8443/tcp
sudo firewall-cmd --permanent --add-port=9443/tcp
# 数据库只给本机用时不要对公网开放 3306
sudo firewall-cmd --permanent --add-port=3306/tcp
sudo firewall-cmd --reload

# 查看开放端口
sudo firewall-cmd --list-all
sudo firewall-cmd --list-ports
sudo firewall-cmd --list-services

部署前准备

生产环境配置

创建一个生产环境的配置文件:src/main/resources/application-prod.properties不要提交到 Git),将同目录下的 application.properties 文件的内容复制过来,然后修改:server.ssl.key-store-passwordspring.datasource.urlusernamepassword 等属性。

Spring Boot 2.4 起,--spring.config.location替换默认搜索路径(jar 内的 application.properties 不再自动加载)。只靠这一份外置文件时,把需要的项都写进去;若要叠加,改用 --spring.config.additional-location

Hibernate 6(Spring Boot 3+)用 MySQLDialect,不要再写已移除的 MySQL8Dialect。本机 MySQL 走 TCP 时 useSSL=false 更常见;若开启 SSL,再改回 true

spring.application.name=uni-spring-boot

# 证书配置
server.address=0.0.0.0
server.port=443
server.ssl.enabled=true
server.ssl.key-store=/opt/myapp/keystore.p12
server.ssl.key-alias=tomcat
server.ssl.key-password=123456
server.ssl.key-store-password=123456
server.ssl.key-store-type=PKCS12

server.tomcat.connection-timeout=30s

# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/[myDatabase]?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
spring.datasource.username=[username]
spring.datasource.password=[password]
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA/Hibernate 配置
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect

security.public-paths=/api/login/**,/api/hello/**,/api/public/**,/api/test/**
spring.web.resources.add-mappings=false

本地打包

在项目根目录执行:

# 在 IntelliJ IDEA
# 方案一:使用 Maven 面板,双击 clean(清理)、package(打包)
# 方案二:打开底部 Terminal 标签,执行:
mvn clean package -DskipTests

# 打包成功后,在 target/ 目录下,查看生成的 JAR 包
ls -lh target/*.jar

# 本地测试(可选)
java -jar target/你的应用名.jar
java -jar target/你的应用名.jar --spring.profiles.active=prod
java -jar target/你的应用名.jar --spring.config.location=file:./application-prod.properties

运行应用

准备上传文件清单

在项目根目录创建部署文件夹:deploy/server

deploy/
├── server/
│   ├── 你的应用名.jar
│   ├── application-prod.properties  # 生产配置
│   ├── keystore.p12 或 keystore.jks # HTTPS 证书
│   ├── start.sh                     # 启动脚本
│   ├── stop.sh                      # 停止脚本
│   ├── restart.sh                   # 重启脚本
│   └── myapp.service                # systemd 单元(必须是 .service 后缀)

start.sh

绑定 443 需要 root 或 CAP_NET_BIND_SERVICE。脚本里不要使用未定义的 $sudo_cmd

#!/bin/bash
APP_NAME="uni-spring-boot-0.0.1-SNAPSHOT.jar"
APP_PORT="443"
JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -Dspring.profiles.active=prod -Dserver.port=$APP_PORT"
LOG_FILE="/opt/myapp/logs/app.log"
PID_FILE="/opt/myapp/app.pid"
KEYSTORE_FILE="/opt/myapp/keystore.p12"

echo "========================================"
echo "🔐 启动 Spring Boot HTTPS 应用"
echo "应用: $APP_NAME"
echo "端口: $APP_PORT (HTTPS)"
echo "时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "========================================"

# 检查是否已运行
if [ -f "$PID_FILE" ]; then
    PID=$(cat "$PID_FILE")
    if ps -p $PID > /dev/null 2>&1; then
        echo "⚠️  应用已在运行,PID: $PID"
        exit 1
    fi
fi

# 检查证书文件
if [ ! -f "$KEYSTORE_FILE" ]; then
    echo "❌ 错误: 未找到证书文件 $KEYSTORE_FILE"
    exit 1
fi

echo "✅ 证书文件存在: $(ls -lh "$KEYSTORE_FILE")"

# 创建日志目录
mkdir -p /opt/myapp/logs

# 备份旧日志
if [ -f "$LOG_FILE" ]; then
    mv "$LOG_FILE" "${LOG_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
fi

echo "🚀 启动应用..."
cd /opt/myapp

# 启动命令
nohup java $JAVA_OPTS -jar $APP_NAME > "$LOG_FILE" 2>&1 &

# 等待并获取进程 ID
sleep 3
APP_PID=$(ps -ef | grep "$APP_NAME" | grep -v grep | awk '{print $2}')

if [ -n "$APP_PID" ]; then
    echo $APP_PID > "$PID_FILE"
    echo ""
    echo "✅ 启动成功!"
    echo "   PID: $APP_PID"
    echo "   端口: https://服务器IP:$APP_PORT"
    echo "   日志: $LOG_FILE"
    echo ""
    echo "📋 常用命令:"
    echo "   查看日志: tail -f $LOG_FILE"
    echo "   实时日志: tail -100f $LOG_FILE"
    echo "   停止应用: ./stop.sh"
    echo "   重启应用: ./restart.sh"
    echo "   检查状态: ps -ef | grep $APP_NAME"
else
    echo "❌ 启动失败!"
    echo "查看错误日志:"
    tail -30 "$LOG_FILE"
    exit 1
fi
chmod +x start.sh
./start.sh

stop.sh

#!/bin/bash
APP_NAME="uni-spring-boot-0.0.1-SNAPSHOT.jar"
PID_FILE="/opt/myapp/app.pid"

echo "停止 Spring Boot 应用..."

if [ -f "$PID_FILE" ]; then
    PID=$(cat "$PID_FILE")
    echo "找到进程 PID: $PID"

    # 优雅停止
    kill -15 $PID 2>/dev/null
    sleep 3

    # 检查是否停止
    if ps -p $PID > /dev/null 2>&1; then
        echo "强制停止..."
        kill -9 $PID 2>/dev/null
    fi

    rm -f "$PID_FILE"
    echo "✅ 应用已停止"
else
    echo "⚠️  未找到 PID 文件,尝试通过名称停止..."
    PIDS=$(ps -ef | grep "$APP_NAME" | grep -v grep | awk '{print $2}')

    if [ -z "$PIDS" ]; then
        echo "应用未运行"
    else
        echo "停止进程: $PIDS"
        kill -15 $PIDS 2>/dev/null
        sleep 2
        kill -9 $PIDS 2>/dev/null
        echo "✅ 应用已停止"
    fi
fi
chmod +x stop.sh
./stop.sh

restart.sh

#!/bin/bash
echo "重启应用..."
echo ""

./stop.sh
sleep 2
./start.sh

myapp.service

systemd 不会像 shell 那样拆开 JAVA_OPTS 里的空格,写在 ExecStart 里会变成一个参数。JVM 参数放到 JAVA_TOOL_OPTIONS,由 Java 自己读取。单元文件必须是 /etc/systemd/system/xxx.service

若 MySQL 实际服务名是 mariadb.service,把下面的 mysqld.service 改掉。User=root 才能直接绑 443;若改成普通用户,需要保留 AmbientCapabilities=CAP_NET_BIND_SERVICE

[Unit]
Description=Uni Spring Boot HTTPS Application
After=network.target mysqld.service
Wants=mysqld.service
Requires=mysqld.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/myapp
Environment="JAVA_TOOL_OPTIONS=-Xms512m -Xmx1024m -XX:+UseG1GC"
ExecStart=/usr/bin/java -jar /opt/myapp/uni-spring-boot-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod --spring.config.location=file:/opt/myapp/application-prod.properties
ExecStop=/bin/kill -15 $MAINPID
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SuccessExitStatus=143

# 安全配置
PrivateTmp=true
ProtectSystem=full
ReadWritePaths=/opt/myapp/logs

# 非 root 用户绑 443 时需要
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
ls -la deploy/server/

注意: 在腾讯云轻量应用服务器,通过 systemd 来管理应用,myapp.service 里已经定义了:ExecStart(启动)、ExecStop(停止)、Restart=always(崩溃后自动重启),start.shstop.shrestart.sh 从功能上已经不再是必需的。这三个脚本可以用于:手动调试或在不通过 systemd 的情况下临时启动 JAR、本地测试服务器上用。

上传文件到服务器

myapp.service 上传到 /etc/systemd/system/myapp.service(文件名必须以 .service 结尾),其余文件放到 /opt/myapp/,并在该目录下创建 logs

systemd 服务管理命令

sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl stop myapp
sudo systemctl restart myapp
sudo systemctl status myapp

# 查看详细日志
sudo journalctl -u myapp -f     # 实时日志
sudo journalctl -u myapp --since "10 minutes ago"
sudo journalctl -u myapp -n 100 # 最近 100 行

# 启用、禁用开机启动
sudo systemctl enable myapp
sudo systemctl disable myapp

# 重新加载服务配置(修改 .service 文件后)
sudo systemctl daemon-reload
sudo systemctl restart myapp

测试 HTTPS

# 检查端口监听
sudo ss -tulpn | grep :443
# 在服务器内部测试
curl -k https://localhost:443
curl -k https://localhost:443/api/hello/welcome
# 从外部测试
# 获取服务器公网 IP
curl -s ifconfig.me

# 然后用浏览器或另一台电脑访问
# https://你的服务器公网IP:443

域名、证书

域名解析

先购买域名,然后在 DNS 服务商处配置解析,然后查看:

# 在服务器上测试
nslookup mydomain.com
ping mydomain.com
curl -I http://mydomain.com
curl -I https://mydomain.com

SSL 证书申请

在腾讯云「SSL 证书」页面申请免费证书,下载时选 Nginx(适用大部分场景)(pem 文件、crt 文件、key 文件)

下载解压后,通常会得到以下文件:

  • mydomain.csr
  • mydomain.key
  • mydomain_bundle.crt
  • mydomain_bundle.pem

上传证书到服务器:/etc/ssl/myapp。打 PKCS12 时用带完整链的 mydomain_bundle.crt(或 .pem),不要只用缺中间证书的单张 mydomain.crt

# 将证书和私钥转换为 PKCS12 格式
sudo openssl pkcs12 -export \
  -in mydomain_bundle.crt \
  -inkey mydomain.key \
  -out keystore.p12 \
  -name "tomcat" \
  -CAfile mydomain_bundle.crt \
  -caname "root" \
  -password pass:123456

# 复制证书
sudo cp keystore.p12 /opt/myapp/
# 修改 application-prod.properties
server.ssl.key-store=/opt/myapp/keystore.p12
server.ssl.key-alias=tomcat
server.ssl.key-password=123456
server.ssl.key-store-password=123456
server.ssl.key-store-type=PKCS12
# 重启应用(服务名与上面的 myapp.service 一致)
sudo systemctl restart myapp
sudo systemctl status myapp
# 验证
curl -k https://localhost:443
curl -k https://localhost:443/api/hello/welcome

© lizhao all right reserved,powered by Gitbook文件修订时间: 2026-09-01 23:37:33

results matching ""

    No results matching ""