dev → test → staging → gray → prod环境 = 同一套代码,在不同运行条件下的不同实例
目的:
- 保护线上用户
- 降低开发和发布风险
- 让问题尽量提前暴露
本地环境 dev
开发者电脑上的运行环境
通过 npm / yarn 等打开开发服务器
用于 写代码、调试,可以debugger,打印控制台、打断点
在构建方面:不压缩、不混淆
测试环境 test
由于本地环境的差异大(Node版本、依赖),只有在自己电脑能跑
所以得有一个过渡-测试环境:模拟线上环境,但不对真实用户开放的环境
部署在服务器上,使用独立域名,接近线上的配置
例如
text.example.com进行
- 前后端联调
- 功能测试
- 回归测试
- QA测试
- UAT 产品验收
VITE_API_BASE=https://test-api.example.comif (import.meta.env.MODE === 'test') { enableDebugPanel(); }| 本地 | 测试 |
|---|---|
| localhost | 真实域名 |
| mock 接口 | 真后端 |
| 无 Nginx | 有 Nginx |
| 无 CDN | 有 CDN |
| HTTP | HTTPS |
预发布环境 staging
上线前最后一次、最接近真实线上环境的验证环境
一般是内部人员的真实数据(test是QA和研发,现在是其他例如产品等)
域名、环境等等都和 prod 一样
灰度 gray
新功能、新版本并不会一次性全量上线,而是只对一部分用户或环境先生效,观察效果稳定后再逐步扩大范围,最终全量发布
小范围试水 → 验证安全 → 再全面放开
- 黑:旧版本(完全没变)
- 白:新版本(全部用户都用)
- 灰:介于两者之间
作用
- 降低发布风险
- 验证真实用户行为:本地/测试环境都不是真实用户
- 支持快速回滚:只需要关闭灰度开关或把比例调回到0
如何实现
- 按「用户」灰度
常见方式:
- 按 userId 哈希取模
- 按账号白名单
- 按新用户 / 老用户
**userId** % 100 < 5 → 5% 用户走新逻辑- 按「流量」灰度(网关/Nginx)
- 10% 请求 → 新服务
- 90% 请求 → 旧服务
split_clients $request_id $version { 10% new; * old; }- 功能开关(Feature Flag)
是否开启由:
- 后台配置
- AB平台
- 配置中心(如 Apollo / Nacos)
if (featureFlags.newPayFlow) { renderNewPay() } else { renderOldPay() }| 灰度发布(金丝雀发布) | 安全上线 |
|---|---|
| AB 测试 | 对比效果好坏 |
线上环境 prod
真实用户正在使用的环境
- 用户访问的网站
- APP请求的接口
- 真正产生业务数据
错误不能暴露给用户
在构建阶段会进行压缩、混淆
日志非常精简
// 线上禁止 console.log if (import.meta.env.PROD) { console.log = () => {}; }VITE_API_BASE=https://api.example.com不能随便进行调试、发布
徐岙发布流程 + 回滚机制
发布流程
本地环境 ↓ 测试环境(CI 自动部署) ↓ 回归测试 / 产品验收 ↓ 线上环境(灰度 / 全量)- 本地 pnpm dev
- 提 PR → 自动部署到 test
- QA 验证
- 合并 main → CI 部署 prod(production 生产环境,用户正在真实使用的环境)
找出本地和线上的差异点
- 环境变量不同
.env.development 和 .env.production
如 API_BASE_URL
可以用console.log(import.meta.env)/console.log(process.env)查看
- 打包产物和本地运行逻辑不同
线上问题可能出现在
- 某个函数被错误地 tree-shake 掉了
- CDN 缓存未更新、版本不一致
解决:本地执行一次真实打包
npm run build npx serve dist- 环境差异:浏览器版本
使用错误出现的环境尝试复现
Babel polyfill 补齐
- 网络
查看开发者工具的网络
对比 CORS 的响应头查看是否是跨域问题
对比一下 Cookie
- 后端的线上逻辑与本地不一致