跳转至

immutable: NGINX 模块用于设置静态资产的不可变缓存

安装

您可以在任何基于 RHEL 的发行版中安装此模块,包括但不限于:

  • RedHat Enterprise Linux 7、8、9 和 10
  • CentOS 7、8、9
  • AlmaLinux 8、9
  • Rocky Linux 8、9
  • Amazon Linux 2 和 Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-immutable
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-immutable

通过在 /etc/nginx/nginx.conf 顶部添加以下内容来启用该模块:

load_module modules/ngx_http_immutable_module.so;

本文档描述了 nginx-module-immutable v0.0.6,于 2026 年 2 月 14 日发布。


Coverity Scan Buy Me a Coffee

这个小型 NGINX 模块可以通过设置 immutable 属性来帮助改善公共静态资产的缓存,设置远期过期时间。

目标受众

依赖于缓存破坏模式的网站和框架:

  • 静态资源在其 URL 中包含版本/哈希,而从不修改这些资源
  • 在必要时,使用具有新版本号/哈希的新版本更新资源,以便其 URL 不同

使用缓存破坏的流行框架:

  • Magento 2
  • 在此处添加您自己的框架!

概述

http {
    server {
        location /static/ {
            immutable on;
        }
    }
}

将产生以下 HTTP 头:

...
Cache-Control: public,max-age=31536000,stale-while-revalidate=31536000,stale-if-error=31536000,immutable
Expires: Thu, 31 Dec 2037 23:55:55 GMT
...

它与 expires max; 的不同之处在于:

  • 设置 immutable 属性,例如 Cache-Control: public,max-age=31536000,immutable 以改善缓存。这是 1 年而不是 10 年,原因见下文。
  • 仅在真正必要时发送 Expires,例如当客户端通过 HTTP/1.0 请求资源时。
  • 设置 public 属性以确保资产可以被公共缓存缓存,这通常是一个期望的行为。

由于 Chromium 基于浏览器对 immutable 的支持不足,我们还添加了 stale-while-revalidate=31536000,stale-if-error=31536000,这有助于在边缘情况下提高缓存命中率。使用这些指令可以在缓存生命周期之外提供缓存响应,对于不可变资源来说,这个时间是永远的。

因此,在大多数情况下,immutable on; 可以作为 expires max; 的更好替代方案来实现缓存破坏模式。

指令

immutable

语法: immutable on | off;

默认值: immutable off;

上下文: httpserverlocation

为该位置启用或禁用不可变缓存头。

immutable_cache_status

语法: immutable_cache_status on | off;

默认值: immutable_cache_status off;

上下文: httpserverlocation

启用 RFC 9211 Cache-Status 头以进行调试和可观察性。当启用时,响应包括:

Cache-Status: "nginx/immutable"; hit; ttl=31536000

该头有助于调试跨多层缓存架构(NGINX -> CDN -> 浏览器)的缓存行为。每个缓存层可以附加其自己的状态,形成如下链条:

Cache-Status: "nginx/immutable"; hit; ttl=31536000, "cloudflare"; fwd=uri-miss; stored

示例配置:

location /static/ {
    immutable on;
    immutable_cache_status on;
}

immutable_types

语法: immutable_types mime-type ...;

默认值: (无 - 当未指定时适用于所有类型)

上下文: httpserverlocation

将不可变缓存头限制为具有指定 MIME 类型的响应。当未指定时,不可变头适用于所有响应。这类似于 gzip_types 在 gzip 模块中的工作方式。

示例配置:

location /static/ {
    immutable on;
    # 仅将不可变头应用于 JavaScript 和 CSS 文件
    immutable_types application/javascript text/css;
}

为什么是 31536000 秒(1 年)?

RFC 定义使用一年将响应标记为“永不过期”:

要将响应标记为“永不过期”,源服务器发送一个过期日期,约为响应发送时的一年后。HTTP/1.1 服务器不应发送超过一年后的过期日期。

更多细节请参见 这篇文章

Ubuntu 和 Debian 包

在这些操作系统上安装模块包非常简单。

ngx_immutable 是 APT NGINX Extras 集合的一部分,因此您可以与 任何模块 一起安装它,包括 Brotli。

首先,设置存储库,然后:

sudo apt-get update
sudo apt-get install nginx-module-immutable

示例:Magento 2 生产配置

假设您的商店在生产模式下运行,您已经编译了所有资产。 此 示例配置 可以优化为:

location /static/ {
    immutable on;

    # 移除用于克服浏览器缓存的静态文件签名
    location ~ ^/static/version {
        rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
    }

    location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|json)$ {
        add_header X-Frame-Options "SAMEORIGIN";
    }
    location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
        add_header Cache-Control "no-store";
        add_header X-Frame-Options "SAMEORIGIN";
        immutable off;
    }
    add_header X-Frame-Options "SAMEORIGIN";
}

ngx_security_headers 一起使用时,可以进一步简化:

security_headers on;

location /static/ {
    immutable on;

    location ~ ^/static/version {
        rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
    }

    location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
        add_header Cache-Control "no-store";
        immutable off;
    }
}

GitHub

您可以在 nginx-module-immutable 的 GitHub 仓库 中找到此模块的其他配置提示和文档。