加群联系作者vx:xiaoda0423
仓库地址:https://webvueblog.github.io/JavaPlusDoc/
https://1024bat.cn/
🚀 一、前后端缓存策略协同
🔧 1. 前端:合理利用浏览器缓存
强缓存(from disk cache / memory cache)
浏览器命中强缓存,不发请求,直接用本地缓存
适合不常改动的静态资源:如图片、字体、JS/CSS 等
服务端响应:
Cache-Control: public, max-age=86400 Expires: Wed, 16 Apr 2025 12:00:00 GMT
前端表现:
协商缓存(304)
服务端响应:
Last-Modified: Wed, 10 Apr 2025 06:00:00 GMT ETag: "abc123xyz"
客户端下一次发起请求带上:
If-Modified-Since: ... If-None-Match: ...
如果资源没变,返回 304,节省带宽;否则返回新的 200
强制刷新(Ctrl+F5)
浏览器自动加上请求头:
Cache-Control: no-cache Pragma: no-cache
🧠 2. 后端:根据资源类型设置缓存响应头
建议结合 Nginx、Spring Boot 或其他后端框架统一配置静态资源策略。
✅ 示例策略(Nginx):
location ~* .(js|css|png|jpg|jpeg|gif|woff|woff2|svg|ico)$ {expires 30d;add_header Cache-Control "public, max-age=2592000, immutable";
}
location /api/ {expires off;add_header Cache-Control "no-store";
}
✅ 示例策略(Spring Boot):
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/").setCacheControl(CacheControl.maxAge(30, TimeUnit.DAYS).cachePublic());}
}
🎯 二、配合思路
资源类型 | 建议缓存策略 | 原因/说明 |
---|---|---|
JS/CSS | Cache-Control: max-age=31536000, immutable | 不常更新、版本号改名 |
图片/字体 | Cache-Control: max-age=31536000, immutable | 不变就一直缓存 |
HTML | Cache-Control: no-cache | 每次都需要检查是否有更新 |
API 请求 | Cache-Control: no-store | 避免缓存敏感数据,实时性强 |
JSON 配置文件 | 可选协商缓存 (ETag + Last-Modified) | 若更新频率低可协商缓存 |
上传文件 | 通常不缓存 | 私密/敏感性资源 |
🎨 三、结合构建工具版本号策略(前端重点)
💡 原理:
每次构建时,资源文件自动添加 hash 值(如 app.7ad32f.js
),强缓存时间可以设置很长(如一年),资源更新后文件名变了,用户自然请求最新资源。
Webpack/Vite/Rollup 常用方式:
output: {filename: '[name].[contenthash].js'
}
HTML 引用时自动更新引用路径,如:
<script src="/static/js/app.7ad32f.js"></script>
🛠 四、注意点
ETag 在集群部署时建议关闭
每个节点生成的 ETag 可能不同,导致命中失败 →
nginx.conf
:etag off;
尽量不要前端禁用缓存(Disable Cache)
除了调试开发,正式环境打开会极大增加流量
图片字体类资源 CDN 分发 + 永久缓存
甚至可以设置:
Cache-Control: max-age=315360000, immutable
动态数据慎用缓存头
比如用户信息、购物车、支付状态,不建议缓存
前端合理配置构建和版本策略,后端精细控制缓存响应头。
层级
优化手段
前端
hash 文件名、immutable 标记、避免 no-cache 滥用
后端
静态资源加长缓存、动态资源配合校验、关闭 ETag(如必要)
网络
启用 CDN 缓存、压缩 Gzip/Brotli、减少 RTT
业务
尽量数据解耦(静态 vs 动态),结构分离、更新原子性
准备 3 个 Nginx 实例:模拟多层代理(Client → Proxy1 → Proxy2 → Backend)
配置测试页面:
后端 Nginx 返回
$remote_addr
,$http_x_forwarded_for
,$http_x_real_ip
来验证 IP 透传。同时返回
$request_method
,$request_uri
来验证proxy_pass
和rewrite
效果。添加资源带上
ETag
,Last-Modified
,Cache-Control
头部测试缓存策略。
Curl 测试命令模板:
curl -I -H "Cache-Control: no-cache" http://localhost/static.js curl -I -H "If-None-Match: "etag123"" http://localhost/static.js curl -I -H "a_b: 123" http://localhost:81
关键配置测试点:
proxy_pass
+ URI 规则的差异行为rewrite + break
对proxy_pass
行为影响proxy_set_header
的 header 继承与覆盖机制underscores_in_headers
开关对 header 变量命名的影响缓存命中(304 vs 200 vs from disk cache)
✅ 一、蓝绿部署(Blue-Green Deployment)
🔍 核心思路:
同时部署两个版本:
blue
:当前稳定线上版本green
:即将上线的新版本
通过 Nginx 实现快速流量切换,避免停机。
🔧 Nginx 配置方法(蓝绿环境切换):
upstream app_backend {server 10.0.0.1:8080; # blue# server 10.0.0.2:8080; # green(上线时把这行打开,把上面注释掉) }server {listen 80;location / {proxy_pass http://app_backend;} }
🔁 切换版本时:只需修改
upstream
的目标 IP 并 reload Nginx,即可完成无缝蓝绿切换。
✨ 实操建议:
配合 Jenkins/脚本做一键切流
结合 health check,避免新版本服务不可用
✅ 二、灰度发布(Canary Release)
🔍 核心思路:
只让部分用户使用新版本,根据规则(如 IP、cookie、header、比例等)灰度流量。
🎯 场景一:按 IP 灰度发布
map $remote_addr $gray_user {default 0;192.168.1.100 1; # 指定用户 IP 灰度 }upstream app_v1 {server 10.0.0.1:8080; # 旧版本 }upstream app_v2 {server 10.0.0.2:8080; # 新版本 }server {listen 80;location / {if ($gray_user = 1) {proxy_pass http://app_v2;}proxy_pass http://app_v1;} }
🎯 场景二:按 Cookie 灰度发布
map $http_cookie $gray_cookie {default 0;"~*gray_user=true" 1; }location / {if ($gray_cookie = 1) {proxy_pass http://app_v2;}proxy_pass http://app_v1; }
🎯 场景三:按比例灰度发布(权重轮询)
upstream canary {server 10.0.0.1:8080 weight=9; # v1 - 90%server 10.0.0.2:8080 weight=1; # v2 - 10% }server {listen 80;location / {proxy_pass http://canary;} }
⚠️ 注意:这种方式对“同一个用户固定命中新旧版本”没有保证。
🔧 Nginx 配合蓝绿/灰度部署的实操小技巧:
功能点
技术方案
精准用户灰度
$remote_addr
/
$http_cookie
/$http_user_agent
动态权重切流
使用 nginx + consul/etcd + lua/openresty
实时切换 upstream
配合
nginx reload
ordynamic upstream
模块监控切流效果
配合
access_log
+ log_format 打日志分析健康检查
proxy_next_upstream
+
max_fails
+fail_timeout
✅ 项目结构(蓝绿灰度 Nginx 示例)
nginx-canary-demo/ ├── docker-compose.yml ├── nginx/ │ ├── nginx.conf │ └── conf.d/ │ └── default.conf ├── app-v1/ # 模拟蓝色版本 │ └── index.html ├── app-v2/ # 模拟绿色版本 │ └── index.html └── test/└── curl_test.sh
📦 docker-compose.yml
version: '3.8'services:nginx:image: nginx:latestvolumes:- ./nginx/nginx.conf:/etc/nginx/nginx.conf- ./nginx/conf.d:/etc/nginx/conf.d- ./app-v1:/usr/share/nginx/html/v1- ./app-v2:/usr/share/nginx/html/v2ports:- "8080:80"app-v1:image: httpd:alpinevolumes:- ./app-v1:/usr/local/apache2/htdocs/ports:- "8081:80"app-v2:image: httpd:alpinevolumes:- ./app-v2:/usr/local/apache2/htdocs/ports:- "8082:80"
🧠 nginx/conf.d/default.conf
# 蓝绿灰度配置 map $http_cookie$is_gray_user {default 0;"~*gray_user=true" 1; }upstream blue {server app-v1:80; }upstream green {server app-v2:80; }server {listen 80;server_name localhost;location / {if ($is_gray_user = 1) {proxy_pass http://green;}proxy_pass http://blue;} }
🔧 nginx/nginx.conf
worker_processes 1; events { worker_connections 1024; }http {include mime.types;default_type text/html;sendfile on;keepalive_timeout 65;include /etc/nginx/conf.d/*.conf; }
📄 app-v1/index.html
<!DOCTYPE html> <html> <head><title>Blue Version</title></head> <body style="background-color:lightblue;"> <h1>Blue Version: v1</h1> </body> </html>
📄 app-v2/index.html
<!DOCTYPE html> <html> <head><title>Green Version</title></head> <body style="background-color:lightgreen;"> <h1>Green Version: v2 (灰度用户专属)</h1> </body> </html>
🧪 test/curl_test.sh
#!/bin/bashecho "== 普通用户访问 ==" curl -s http://localhost:8080 | grep h1echo "== 灰度用户访问 ==" curl -s -H "Cookie: gray_user=true" http://localhost:8080 | grep h1
🚀 使用方法
启动项目:
docker-compose up --build
访问测试:
普通访问: http://localhost:8080
灰度访问:
curl -H "Cookie: gray_user=true" http://localhost:8080
运行测试脚本:
chmod +x test/curl_test.sh ./test/curl_test.sh
🧩 后续进阶建议
功能
方法
动态流量比例调整
Nginx + Lua + Redis 控制比例
权重灰度(10% 进入 green)
upstream weight
+ sticky session
请求路径/UA/Referer 灰度
用
$http_user_agent
或$request_uri
做 map🌈 场景回顾:蓝绿环境 + 灰度切流
Blue(当前稳定)
Green(新版本)
默认流量都走 Blue
Jenkins 按钮发布时,先检测 Green 健康,再流量切换
切流可灰度逐步调整、也可一键全量
🛠️ 1. Nginx 目标配置(动态切换 upstream)
我们通过软链接 + reload 实现:
bash 复制编辑 /etc/nginx/conf.d/default.conf -> points to: conf.d/blue.conf or conf.d/green.conf
例如:
conf.d/upstream-blue.conf
upstream backend {server app-v1:80; }
conf.d/upstream-green.conf
upstream backend {server app-v2:80; }
conf.d/location.conf
server {listen 80;location / {proxy_pass http://backend;} }
🧪 2. 健康检查脚本(
health_check.sh
)#!/bin/bashTARGET_URL=$1 RETRY=5for i in $(seq 1 $RETRY); do echo"Health check [$i/$RETRY]: $TARGET_URL"code=$(curl -s -o /dev/null -w "%{http_code}""$TARGET_URL") if [ "$code" == "200" ]; thenecho"✅ Health check success."exit 0 fisleep 2 doneecho"❌ Health check failed." exit 1
🚀 3. 一键切流脚本(
switch_traffic.sh
)#!/bin/bashTARGET=$1# blue or green NGINX_DIR="/etc/nginx/conf.d" LINK="$NGINX_DIR/default.conf" UPSTREAM="$NGINX_DIR/upstream-${TARGET}.conf"if [ "$TARGET" != "blue" ] && [ "$TARGET" != "green" ]; then echo"Usage: $0 [blue|green]" exit 1 fi# 健康检查 bash ./health_check.sh "http://127.0.0.1:808${TARGET/blue/1}${TARGET/green/2}" || exit 1# 切换 upstream rm -f $LINK ln -s $UPSTREAM$LINK# Reload Nginx nginx -s reload echo"✅ 切流到 $TARGET 成功"
🧱 4. Jenkins 流程(自由风格任务 / Pipeline)
方式一:自由风格任务 + 参数
添加构建参数:
TARGET_ENV
(值为blue
或green
)构建步骤:
cd /your/nginx-deploy-dir git pull chmod +x switch_traffic.sh ./switch_traffic.sh $TARGET_ENV
方式二:Pipeline 示例
pipeline {agent anyparameters {choice(name: 'TARGET', choices: ['blue', 'green'], description: '选择要切流的版本')}stages {stage('切流') {steps {sh '''cd /your/nginx-deploy-dirgit pull./switch_traffic.sh $TARGET'''}}} }
🔒 稳定性保证(建议搭配)
功能
技术点
健康检查
curl + retry
灰度切换(10%)
Nginx map + $request_id hash 灰度
回滚
切换软链接回 blue 即可
实时监控
Prometheus + Grafana
异常自动报警
Jenkins 配合 DingTalk/飞书
Nginx 的主配置文件(nginx.conf)
🔧
worker_processes 1;
启动 1 个 worker 进程(处理请求的核心进程)
通常设为
auto
(自动根据 CPU 核心数来分配)
⚙️
events { worker_connections 1024; }
这是 事件模块,控制每个 worker 能同时处理的连接数:
worker_connections 1024
:一个 worker 最多能处理 1024 个并发连接理论最大并发:
worker_processes × worker_connections
(但受限于系统 ulimit)
🌐
http { ... }
Nginx 的 HTTP 服务核心配置块,包含所有 web server 配置。
逐条解释:
📎
include mime.types;
引入
mime.types
文件,告诉 Nginx 各种文件扩展名对应的Content-Type
(如.html
是text/html
)
📎
default_type text/html;
如果找不到合适的 mime type,就默认使用
text/html
🚀
sendfile on;
开启零拷贝(zero copy),优化文件传输效率
用于静态资源场景(图片、视频、压缩包等)
🔁
keepalive_timeout 65;
TCP keep-alive 时间,单位:秒
如果 65 秒内没有请求,则断开连接,节省资源
默认值是
75
,这里调成65
说明略早释放
📁
include /etc/nginx/conf.d/*.conf;
引入所有
/etc/nginx/conf.d/
目录下的.conf
文件所有的
server {}
或location {}
块通常写在这里
例子:
/etc/nginx/ ├── nginx.conf # 主配置 └── conf.d/├── app1.conf # 站点1├── app2.conf # 站点2
📁 项目结构建议
deploy/ ├── nginx/ │ ├── blue.conf # 蓝环境配置 │ ├── green.conf # 绿环境配置 │ └── main.conf # 入口 nginx 配置 (引用 upstream) ├── scripts/ │ └── switch_env.sh # 切流脚本(蓝 -> 绿 / 绿 -> 蓝)
🧩
main.conf
(Nginx 主配置引用 upstream)# main.conf (加载到 nginx.conf 或 conf.d/default.conf)upstream backend {include /etc/nginx/upstream/active.conf; }server {listen 80;location / {proxy_pass http://backend;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}location = /healthz {return 200 'ok';} }
🟦
blue.conf
# blue.conf server 10.0.0.11:8080 max_fails=3 fail_timeout=30s;
🟩
green.conf
# green.conf server 10.0.0.12:8080 max_fails=3 fail_timeout=30s;
🔗
active.conf
(软链接)# 初始环境为 blue ln -s /etc/nginx/upstream/blue.conf /etc/nginx/upstream/active.conf
🛠️
switch_env.sh
(脚本实现一键切流)#!/bin/bashUPSTREAM_DIR="/etc/nginx/upstream" CURRENT=$(readlink "$UPSTREAM_DIR/active.conf")if [[ $CURRENT == *"blue.conf" ]]; thenNEW_TARGET="green.conf" elseNEW_TARGET="blue.conf" fiecho"[INFO] 切换到环境: $NEW_TARGET"# 更新软链接 ln -sf "$UPSTREAM_DIR/$NEW_TARGET""$UPSTREAM_DIR/active.conf"# 检查健康 echo"[INFO] 进行健康检查..."CHECK_URL="http://127.0.0.1/healthz" sleep 1 HEALTH=$(curl -s --max-time 3 "$CHECK_URL")if [[ "$HEALTH" == "ok" ]]; thenecho"[INFO] 健康检查通过,重载 Nginx..."nginx -s reloadecho"[OK] 切流成功!当前环境:$NEW_TARGET" elseecho"[ERROR] 健康检查失败,回滚..."# 回滚ln -sf "$CURRENT""$UPSTREAM_DIR/active.conf"nginx -s reloadecho"[ROLLBACK] 已回滚至 $CURRENT"exit 1 fi
✅ 使用方式
# Jenkins中执行 bash /path/to/scripts/switch_env.sh
💡 可选增强点
功能
建议方式
自动灰度比例切换
Nginx
weight
参数 + hash多版本健康检查
/healthz
带版本参数
压力测试
wrk
/
ab
/hey
工具可视化状态切换
搭配
Nginx status + Lua