nginx动态控制前端版本
需求:
用户请求到nginx,nginx内部调一个http接口获取一个版本号,根据版本号返回对应目录下的代码
一、整体思路
- 内部接口调用:利用 Nginx 的 sub_filter 或 proxy_pass 模块,在处理请求时向内部 HTTP 接口发起请求获取版本号。
- 版本号匹配:通过 Nginx 的变量(如 $version)存储版本号,结合 if 或 map 指令匹配不同版本对应的代码目录。
- 静态文件响应:根据匹配结果,将请求代理到对应版本的代码目录(如 /var/www/v1.0、/var/www/v2.0),返回静态资源。
二、关键步骤
1. 安装与配置 Nginx
确保 Nginx 已安装并启用 http_proxy_module 和 http_sub_module 模块(默认编译时包含)。
2. 定义内部 HTTP 接口
假设存在一个获取版本号的接口(如 http://version-service/get-version),返回内容为纯文本(如 v1.0)。
示例接口响应:
v1.0
3. 配置 Nginx 变量获取版本号
通过 proxy_pass 或 sub_filter 调用接口,并将响应内容赋值给 Nginx 变量 $version。
方式一:使用 proxy_pass 同步调用接口
server {listen 80;server_name your-domain.com;# 定义获取版本号的上游服务upstream version_service {server 127.0.0.1:8080; # 替换为实际接口地址}location / {# 1. 调用版本号接口,将响应存储到变量 $versioninternal;proxy_pass http://version_service/get-version;proxy_pass_request_body off;proxy_set_header Content-Type "";proxy_intercept_errors on;error_page 500 502 503 504 =200 @set_version;# 2. 匹配版本号并返回对应目录内容set $version "";location @set_version {# 从接口响应中提取版本号(假设响应为纯文本)proxy_pass_request_body off;proxy_set_header Content-Length "";proxy_set_body $upstream_output_body;set $version $upstream_output_body;# 去除首尾空格(可选)strip_tags $version;trim_right $version "";trim_left $version "";# 3. 根据版本号匹配目录if ($version = v1.0) {alias /var/www/v1.0/;} elseif ($version = v2.0) {alias /var/www/v2.0/;} else {return 404 "Version not found: $version";}# 处理静态文件请求(如 HTML、JS、CSS)try_files $uri $uri/ /index.html;}}
}
方式二:使用 sub_filter 异步获取版本号(推荐)
适用于版本号不随每次请求变化的场景(如全局版本),通过缓存减少接口调用频率:
http {# 缓存版本号(例如缓存 1 分钟)proxy_cache_path /var/cache/nginx/version_cache levels=1:2 keys_zone=version_cache:10m max_size=10g inactive=60s;server {listen 80;server_name your-domain.com;# 1. 从缓存或接口获取版本号location = /get-version {internal;proxy_pass http://version-service/get-version;proxy_cache version_cache;proxy_cache_valid 200 60s;proxy_pass_request_body off;proxy_set_header Content-Type "";}# 2. 主请求处理location / {# 获取版本号并赋值给变量set $version "";internal;sub_filter_types text/plain;sub_filter_once off;sub_filter "" "$version";sub_filter_by_lazy_headers on;sub_filter_by_lazy_body on;# 调用内部接口获取版本号rewrite_by_lua_block {local res = ngx.location.capture("/get-version")if res.status == 200 thenngx.var.version = res.bodyelsengx.var.version = "v1.0" # 默认版本end}# 3. 根据版本号匹配目录(使用 map 指令优化条件判断)map $version $version_dir {default "/var/www/v1.0";"v1.0" "/var/www/v1.0";"v2.0" "/var/www/v2.0";}alias $version_dir/;try_files $uri $uri/ /index.html;}}
}
三、目录结构与权限
- 代码目录示例:
/var/www/
├── v1.0/
│ ├── index.html
│ └── assets/
└── v2.0/
├── index.html
└── assets/
- 权限设置:
chown -R nginx:nginx /var/www/ # 确保 Nginx 用户有权限读取目录
chmod -R 755 /var/www/