nginx动态控制前端版本

发布于:2025-05-23 ⋅ 阅读:(26) ⋅ 点赞:(0)

需求:

用户请求到nginx,nginx内部调一个http接口获取一个版本号,根据版本号返回对应目录下的代码

一、整体思路

  1. 内部接口调用:利用 Nginx 的 sub_filter 或 proxy_pass 模块,在处理请求时向内部 HTTP 接口发起请求获取版本号。
  2. 版本号匹配:通过 Nginx 的变量(如 $version)存储版本号,结合 if 或 map 指令匹配不同版本对应的代码目录。
  3. 静态文件响应:根据匹配结果,将请求代理到对应版本的代码目录(如 /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. 调用版本号接口,将响应存储到变量 $version
        internal;
        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 then
                    ngx.var.version = res.body
                else
                    ngx.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;
        }
    }
}

三、目录结构与权限

  1. 代码目录示例:

/var/www/
├── v1.0/
│ ├── index.html
│ └── assets/
└── v2.0/
├── index.html
└── assets/

  1. 权限设置:
chown -R nginx:nginx /var/www/  # 确保 Nginx 用户有权限读取目录
chmod -R 755 /var/www/

网站公告

今日签到

点亮在社区的每一天
去签到