当前位置: 代码网 > it编程>编程语言>Java > 从 Linux 命令到灰度发布:一次完整的 SpringBoot 多环境部署过程

从 Linux 命令到灰度发布:一次完整的 SpringBoot 多环境部署过程

2026年08月18日 Java 我要评论
本文是一篇面向后端工程师的部署实战复盘,覆盖 linux 基础命令、多环境划分、灰度发布流程、springboot 多环境配置、maven 打包以及部署报错排查。内容从概念到原理再到实战,适合刚接触服

本文是一篇面向后端工程师的部署实战复盘,覆盖 linux 基础命令、多环境划分、灰度发布流程、springboot 多环境配置、maven 打包以及部署报错排查。内容从概念到原理再到实战,适合刚接触服务器部署的同学系统学习,也适合作为团队知识库沉淀。

一、linux 基础操作命令

服务器部署的第一步,是能在命令行里熟练地"走来走去"。下面这些命令是日常操作服务器时使用频率最高的,建议全部上手敲一遍。

1. 查看目录文件

命令作用
ls列出当前目录内的文件
ls -a列出全部文件(包含隐藏文件)
ls -l查看文件详细信息(权限、大小、时间等)
llls -l 的简写命令

命令行前缀长这样:

root@主机名:当前目录#

其中 root 是当前登录用户。几个高频小技巧:

  • . 代表当前目录,.. 代表上一级目录;
  • tab 键可以命令自动补全(敲一半按一下,省时又避免手滑拼错);
  • ctrl + c 可以终止当前正在执行的命令,比如某个命令卡住了,第一时间按它。

2. 目录切换与查看路径

cd 目录名     # 进入指定目录,例如:cd spring-cloud-blog
pwd          # 查看、返回当前所在目录的完整路径

pwd 是 print working directory 的缩写,迷路时用它确认自己到底在哪个目录。

3. 文件夹操作

mkdir 文件夹名      # 创建文件夹,例如:mkdir java115_java116
rm 文件夹名/        # 直接删除文件夹会报错,提示这是目录无法删除
rm -r 文件夹名/     # 递归删除文件夹以及内部全部内容

这里有一个非常典型的踩坑点:rm 直接删除目录会失败,因为 rm 默认只删除普通文件。必须加 -r(recursive,递归)参数才能删除整个目录树。删除是不可逆的,生产环境请务必三思而后行。

4. 文件操作

创建文件

touch aa.log

读取文件

命令作用
cat一次性读取全部内容
more分页查看,结束按 ctrl+c
less分页查看,结束输入 :q
head -50 xxx读取文件前 50 行
tail -50 xxx读取文件末尾 50 行

这里有个很实用的组合用法:查看日志时,通常我们只关心最新的内容,所以 tail 用得最多。配合 tail -f(follow)还能实时滚动查看追加的日志,排查线上问题时几乎离不开它。

编辑写入文件(vi / vim 编辑器)

vi 文件名

进入编辑器后,几个核心按键:

  • i:进入编辑模式(insert);
  • esc:退出编辑模式;
  • :w:仅保存;
  • :q:退出;
  • :wq:保存并退出;
  • :wq!:强制保存并退出;
  • :q!:强制退出,不保存修改。

初学者的最大困惑就是"为什么按了半天没反应"——因为 vi/vim 有三种模式,刚打开时处于命令模式,此时键盘输入的是命令而非文字,需要先按 i 进入编辑模式才能打字。

文件上传下载

  • 上传文件:① 本地文件直接拖拽上传;② rz 命令上传;
  • 下载文件sz 命令下载。

rz / sz 需要先安装工具:

apt-get install lrzsz

注:rz/sz 依赖终端工具支持(如 xshell、securecrt、mobaxterm 等),windows 自带的 cmd 和部分终端可能不生效,此时用 sftp 图形工具或 scp 命令替代即可。

5. 进程查看命令

ps aux | grep java   # 筛选查看 java 相关进程
ps -ef               # 查看全部进程

| 是管道符,把左边命令的输出交给右边命令处理;grep 负责过滤。这个组合是排查"服务到底有没有起来"的第一步:先看进程在不在,再看日志报什么错。

6. 软件安装命令区分

系统安装命令
ubuntu 系统apt(如 apt-get install xxx
centos 系统yum(如 yum install xxx

两个发行版的包管理器不同,用错命令会直接提示"command not found"。上手新服务器时,先 cat /etc/os-release 确认系统版本,再决定用哪套命令。

7. 退出操作

结束会话常用三种方式:ctrl+c:q(!)(vi/vim 中退出)、exit

二、软件项目多环境与灰度发布流程

掌握了基础命令,接下来理解一个更大的背景:一个软件从开发到上线,为什么要分那么多环境?以及如何安全地把新版本推上线?

1. 项目环境划分

一般来说,一个成熟的项目会划分出 5 种运行环境:

  1. 开发环境(dev):程序员本地或共享开发机,写代码、自测用;
  2. 测试环境(test):qa 工程师做功能测试、回归测试;
  3. 预发布环境(stage):上线前最后一次"彩排",使用真实用户数据做最终验证;
  4. 灰度环境:把新版本先切给一小部分真实流量验证;
  5. 线上/发布环境(prod):正式对外提供服务的环境。

这里的关键点是预发布环境会使用真实用户数据。为什么?因为很多线上 bug 只有在真实数据量级、真实数据分布下才会暴露——测试环境的假数据往往掩盖了问题。所以预发布环境(也叫 staging)承担了"上线前最后一公里"的把关职责。

2. 灰度发布流程(示例:一共 100 台服务器)

灰度发布(gray release / canary release)的核心思想是:分批上线新版本,降低一次性全量上线带来的故障风险。假设集群一共 100 台机器:

  1. 灰度 1 台机器,占总量 1%,小范围验证——即便出问题,影响面也极小;
  2. 灰度扩充到 10 台机器,占总量 11%,扩大验证范围;
  3. 灰度扩充到 40~50 台机器,占总量 50%;
  4. 全部机器更新新版本,全量上线。

流量经过负载均衡分发到后端多台业务服务器集群。灰度时,负载均衡按比例把一小部分真实流量导向已更新新版本的机器,其余流量仍走旧版本,从而实现"边验证、边观察、随时可回滚"。

为什么不能直接全量? 新版本哪怕测试再充分,也无法 100% 覆盖真实流量中的各种边界情况。灰度把"全量上线失败"这种大事故,拆解成了"1% 流量下的小问题",把损失降到可控范围。这是互联网公司最核心的工程实践之一。

三、springboot 多环境配置

回到代码层面:程序要正常运行,必须保证运行环境与程序配置匹配。也就是说,同样一份代码,跑在开发机上要连开发库,跑在服务器上要连生产库——这些差异需要通过"多环境配置"来预先设置。

1. 数据准备

在服务器上执行数据库建表脚本,生成和本地一致的数据表结构。代码跑得起来的前提是表结构存在,这一步经常被忽略,导致启动后一查数据就报"表不存在"。

2. 程序配置文件修改

实际工作中,开发、测试、生产环境的配置不一样(最典型的就是 mysql 账号密码)。为了不混用,springboot 支持给不同环境设置独立配置文件

命名规则

多平台配置文件命名规则:application-xxx.ymlapplication-xxx.properties,中间的 xxx 用来标记环境。

示例配置文件:

  • application.yml:主配置文件;
  • application-dev.yml:开发环境配置;
  • application-prod.yml:生产环境配置。

文件格式是固定的,只有中间的环境标识可以修改,不同配置文件内填写对应环境参数。

配置示例

application-dev.yml(开发环境):

# 开发环境配置:填写开发环境数据库连接地址、账号密码、驱动
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mall_dev      # 开发库地址
    username: dev_user                             # 开发库账号
    password: dev_pass_123                         # 开发库密码
    driver-class-name: com.mysql.cj.jdbc.driver    # 驱动类

application-prod.yml(生产环境):

# 生产环境配置:填写生产环境数据库连接地址、账号密码、驱动
spring:
  datasource:
    url: jdbc:mysql://10.0.0.8:3306/mall_prod      # 生产库地址(内网 ip)
    username: prod_user                            # 生产库账号(权限最小化)
    password: prod_pass_strong!                    # 生产库密码
    driver-class-name: com.mysql.cj.jdbc.driver

在主配置中指定启用哪套环境

在主配置文件 application.yml 中指定当前启用哪一套环境,主配置内删除数据库相关配置(因为数据库配置已经下沉到各环境文件里了):

# application.yml 主配置文件:只负责"指定激活哪套环境"
spring:
  profiles:
    active: prod   # 激活生产环境配置

这样,springboot 启动时会读取 application.yml,发现 active: prod,进而自动加载 application-prod.yml,把生产环境的数据库配置注入进来。切换环境只需改这一个值,代码零改动。

3. 从 maven 读取环境配置变量

更进阶的做法,是把"激活哪套环境"这件事交给 maven 管理。在 pom.xml 中定义环境变量,管理 dev、prod 两套环境,并把 prod 设为默认启用:

<!-- pom.xml -->
<profiles>
    <!-- 开发环境 -->
    <profile>
        <id>dev</id>
        <properties>
            <profile.name>dev</profile.name>
        </properties>
    </profile>
    <!-- 生产环境(默认启用) -->
    <profile>
        <id>prod</id>
        <properties>
            <profile.name>prod</profile.name>
        </properties>
        <activation>
            <activebydefault>true</activebydefault>  <!-- 默认激活 prod -->
        </activation>
    </profile>
</profiles>

之后在 application.yml 中通过 @profile.name@ 读取 maven 里定义的变量,动态指定激活环境:

# application.yml:通过 maven 变量动态指定激活环境
spring:
  profiles:
    active: @profile.name@   # 打包时被 maven 替换成 dev 或 prod

这样做的好处是:一次配置,打包即切换。用 mvn package -p dev 打开发包,用 mvn package -p prod 打生产包,不用手动改配置文件。同时还要在 pom.xml 里开启资源过滤(resource filtering),否则 @profile.name@ 不会被替换——这正是下面报错的根源。

四、构建项目并打包(本地 maven 打包)

配置无误后,就可以把项目打成可执行的 jar 包,上传到服务器运行了。

1. 跳过测试

如果测试(test)代码里存在数据库等环境相关的操作,打包时执行测试会失败。此时可以点击图标跳过测试,或在命令行加参数 -dskiptests

mvn package -dskiptests

注意区分 -dskiptests-dmaven.test.skip=true:前者跳过测试执行但仍编译测试代码,后者连测试代码都不编译。日常打包用前者即可。

2. 打包步骤

打包遵循"先清理、再打包"的顺序:

mvn clean      # 先清理旧构建产物
mvn package    # 再打包

也可以合并成一条:

mvn clean package
  • 打包成功标志:控制台输出 build success
  • 产物位置:打包完成后生成 jar 包,存放在项目 target 目录下(如 shopping-system-1.0.1.jar),之后可以上传到服务器运行。

拿到 jar 后,在服务器上运行:

# 前台运行(关闭终端即停止,适合临时调试)
java -jar target/shopping-system-1.0.1.jar
# 后台运行(生产环境推荐,配合日志重定向)
nohup java -jar target/shopping-system-1.0.1.jar > app.log 2>&1 &

全文总结

本文沿着"命令 → 环境 → 配置 → 打包 → 报错 → 上线"这条主线,完整还原了一次 springboot 项目的部署流程:

  1. linux 基础命令是操作服务器的手和脚,从查看、切换、增删文件,到进程查看、包管理,构成了日常运维的基本功;
  2. 多环境划分(dev / test / stage / 灰度 / prod)解决了"同一份代码在不同环境跑不同配置"的问题,预发布环境用真实数据做最终验证;
  3. 灰度发布用分批上线的策略,把全量上线的风险拆解成可控的小范围验证,是互联网工程的核心方法论;
  4. springboot 多环境配置通过 application-xxx.yml 隔离环境差异,主配置用 spring.profiles.active 指定激活哪套环境,进阶做法是用 maven 变量 @profile.name@ 动态注入;
  5. 部署报错大多源于配置占位符未解析,核心是开启资源过滤 + 变量名严格一致;
  6. maven 打包遵循 clean → package 的流程,跳过测试、确认 build success、拿到 jar 即可部署。

核心知识点复盘

  • 命令行基础ls -a/-lcdpwdmkdirrm -rtouchcat/more/less/head/tailvi/vimi 进入编辑、:wq 保存退出)、rz/szps aux | grepapt/yum
  • 删除注意rm 删目录必须加 -r,且删除不可逆;
  • vi/vim 三模式:命令模式 → i 编辑模式 → esc 回命令模式 → :wq 保存退出;
  • 环境体系:dev / test / stage / 灰度 / prod,预发布用真实数据;
  • 灰度节奏:1% → 11% → 50% → 100%,由负载均衡按比例切流;
  • 多环境配置application-{env}.yml + 主配置 spring.profiles.active
  • maven 变量注入@profile.name@ + resource filtering + 变量名严格一致;
  • 打包流程mvn clean package,跳过测试用 -dskiptests,产物在 target 目录。

常见问题 / 避坑指南

  • rm 目录 报错:因为 rm 默认只删文件,删目录必须用 rm -r。生产环境操作前先 pwd 确认路径,避免误删。
  • vi 里"打字没反应":刚打开 vim 处于命令模式,要先按 i 进入编辑模式才能输入文字;编辑完按 esc 退回命令模式,再 :wq 保存退出。
  • 打包时测试报错:测试代码依赖数据库等环境时,用 -dskiptests 跳过测试执行;但要注意,跳测试只是权宜之计,核心逻辑建议仍保留自动化测试。
  • 环境切错导致连错库:上线前务必核对 spring.profiles.active 的值,并确认对应 application-{env}.yml 里的数据库地址、账号密码是否为预期环境。用 maven 变量注入时,打包命令记得带对 -p 参数。
  • jar 前台运行终端一关就停:生产环境用 nohup java -jar ... & 后台运行,并把输出重定向到日志文件,方便后续 tail -f 排查。

到此这篇关于从 linux 命令到灰度发布:一次完整的 springboot 多环境部署过程的文章就介绍到这了,更多相关springboot 多环境部署内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com