Skip to content

nginx 变量介绍

nginx 变量官方文档 https://nginx.org/en/docs/varindex.html

https://nginx.org/en/docs/http/ngx_http_core_module.html#variables

nginx 变量 https://blog.csdn.net/PercyXuBiao/article/details/126056822

Nginx 变量简介

在 Nginx 配置中,所有变量都需要使用 $ 前缀来引用,类似于许多编程语言中的变量使用方式。Nginx 的变量仅支持字符串数据类型。这意味着无论变量的内容看起来是数字还是其他类型,它们在处理时都将作为字符串处理。

示例:定义和使用基本字符串变量

nginx
server {
    location /example1 {
        set $example "Example Text";
        return 200 $example;
    }
}

此例中定义了一个名为 $example 的变量,其值为 "Example Text",在请求 /example1 时返回。

示例:将变量用于修改和重定向

nginx
server {
    location /oldpage {
        set $newpage "/newpage";
        rewrite ^ $newpage permanent;
    }
}

在此示例中,定义了一个变量 $newpage 用于存储新页面的路径。当访问 /oldpage 时,请求将被永久重定向到 /newpage

Nginx 变量的定义和使用

自定义变量

在 Nginx 配置中,可以使用 set 指令来定义自定义变量。这通常在 serverlocation 块中进行。自定义变量允许你在配置中存储和使用动态值。

示例:使用变量进行条件响应

nginx
server {
    location /hello {
        set $name "visitor";
        return 200 "Hello, $name!";
    }
}

在此配置中,$name 被设置为 "visitor",并用于生成响应 "Hello, visitor!"。

示例:基于时间的变量

nginx
server {
    location / {
        set $greeting "Welcome!";
        # 使用内置的 $date_gmt 变量检查当前 GMT 时间
        if ($date_gmt ~* "^[A-Za-z]{3}, (\d{2}) [A-Za-z]{3} (\d{4}) (\d{2}):(\d{2}):(\d{2}) GMT$") {
            set $hour $3;
            if ($hour >= 06 && $hour < 12) {
                set $greeting "Good morning!";
            }
            if ($hour >= 12 && $hour < 18) {
                set $greeting "Good afternoon!";
            }
            if ($hour >= 18 || $hour < 06) {
                set $greeting "Good evening!";
            }
        }
        return 200 $greeting;
    }
}

此配置通过分析 GMT 时间来确定一天中的时间,并根据不同的时间段向访问者显示相应的欢迎消息。

变量的可见性

变量的作用范围取决于其定义的位置。通常,一个在 server 块中定义的变量可在其内部的所有 location 块中使用。然而,一个在 location 块中定义的变量仅限于该 location 内部使用。

示例:在 server 块中定义全局变量

nginx
server {
    set $server_name "My Server";
    location / {
        return 200 "This is $server_name";
    }
    location /about {
        return 200 "About $server_name";
    }
}

在此示例中,$server_name 在 server 块中定义,并在两个不同的 location 块中使用,展示了变量的跨 location 可见性。

示例:限定 location 的变量使用

nginx
server {
    location /start {
        set $start_message "Start here";
        return 200 $start_message;
    }
    location /end {
        # 此行将会出错,因为 $start_message 在这个 location 不可见
        return 200 $start_message;
    }
}

在此示例中,$start_message 变量仅在 /start 路径定义和可见。尝试在 /end 路径中使用此变量会导致错误,因为它在该 location 中不可见。

nginx 自定义变量

在 Nginx 中,你可以定义自定义变量来实现特定的配置需求。这些变量可以在配置文件中用来控制行为、重写请求、做日志记录等。下面是一个简单的例子,展示如何在 Nginx 配置中定义和使用自定义变量。

1. 基于请求头部的自定义日志格式

假设你想基于客户端请求的某个头部(例如 Client-Type),来改变日志中记录的内容。你可以使用 map 指令来创建一个基于 Client-Type 请求头的变量,并在日志格式中使用这个变量。

  1. 定义 Map

    http 模块中,你可以定义一个 map 来创建一个新变量,它会根据 Client-Type 请求头的值来设定变量的值。

    nginx
    http {
        map $http_client_type $log_type {
            default "general_client";
            mobile "mobile_client";
            desktop "desktop_client";
        }
    }

    这里的 $http_client_type 应该被理解为从 HTTP 请求头 Client-Type 中抽取的值。Nginx 有一个内置机制,允许通过添加前缀 $http_ 后跟小写的头名称(如 $http_user_agent)来直接访问任何 HTTP 请求头部。因此,如果 HTTP 请求中包含一个名为 Client-Type 的头部,你可以通过变量 $http_client_type 访问它的值。

    这个配置创建了一个名为 $log_type 的变量,它会根据 Client-Type 头部的值改变。如果头部是 mobile$log_type 将被设置为 mobile_client,如果是 desktop,则设置为 desktop_client。如果头部不存在或值不是这两个中的任何一个,则默认为 general_client

    以下是一个使用 Fetch API 发送请求并设置 Client-Type 头部的示例:

    js
    fetch("http://example.com/api", {
      method: "GET", // 或 POST, PUT, DELETE 等
      headers: {
        "Client-Type": "Your Client Type", // 替换为实际的客户端类型
      },
    })
      .then((response) => response.json())
      .then((data) => console.log(data))
      .catch((error) => console.error("Error:", error));
  2. 使用自定义变量在日志格式中

    现在你可以在 access_log 指令中使用这个变量来定义一个自定义的日志格式。

    nginx
    log_format custom_format '[$time_local] $remote_addr - $log_type - $request';
    access_log /var/log/nginx/access.log custom_format;

    在这个配置中,每个日志条目将包括请求时间、客户端 IP 地址、自定义的日志类型(基于 Client-Type),以及完整的请求行。

  3. 整合到服务器配置

    将上面的配置片段放入 Nginx 的配置文件中(通常是在 nginx.conf 文件中),然后重载或重启 Nginx 使配置生效。

系统变量

  1. nginx documentation https://nginx.org/en/docs/

  2. Alphabetical index of variables https://nginx.org/en/docs/varindex.html

变量名模块描述
$argsngx_http_core_module请求中的查询字符串。
$binary_remote_addrngx_http_core_module, ngx_stream_core_module客户端 IP 地址的二进制形式,可用于节省日志空间。
$body_bytes_sentngx_http_core_module发送给客户端的 HTTP 响应体字节数,不包括响应头。
$bytes_receivedngx_stream_core_module接收到的字节数,可用于流模块。
$bytes_sentngx_http_core_module, ngx_http_log_module, ngx_stream_core_module发送的总字节数,根据模块可能包括或不包括响应头。
$connectionngx_http_core_module, ngx_http_log_module, ngx_stream_core_module当前连接的序列号。
$connection_requestsngx_http_core_module, ngx_http_log_module通过当前连接处理的请求数量。
$connection_timengx_stream_core_module连接已持续的时间,以秒为单位。
$connections_activengx_http_core_module当前活动连接的数量。
$connections_readingngx_http_core_module当前正在读取请求头的连接数量。
$connections_waitingngx_http_core_module当前空闲等待请求的连接数量。
$connections_writingngx_http_core_module当前正在写入响应数据的连接数量。
$content_lengthngx_http_core_module"Content-Length" 请求头的值。
$content_typengx_http_core_module"Content-Type" 请求头的值。
$cookie_<variable>ngx_http_core_module指定名称的 Cookie 的值。
$date_gmtngx_http_core_module格林威治时间 (GMT)。
$date_localngx_http_core_module服务器的本地时间。
$document_rootngx_http_core_module当前请求的文档根目录。
$document_uringx_http_core_module请求的 URI,不包括查询字符串。
$fastcgi_path_infongx_http_fastcgi_module用于 FastCGI 的路径信息。
$fastcgi_script_namengx_http_fastcgi_module用于 FastCGI 的脚本名称。
$geoip_area_codengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的区域代码。
$geoip_cityngx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的城市名。
$geoip_city_continent_codengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的大陆代码。
$geoip_city_country_codengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的国家代码。
$geoip_city_country_code3ngx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的三位国家代码。
$geoip_city_country_namengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的国家名称。
$geoip_country_codengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的国家代码。
$geoip_country_code3ngx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的三位国家代码。
$geoip_country_namengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的国家名称。
$geoip_dma_codengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 解析的地区市场区号(DMA)。
$geoip_latitudengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的纬度。
$geoip_longitudengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的经度。
$geoip_orgngx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的组织名称。
$geoip_postal_codengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的邮政编码。
$geoip_regionngx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的地区代码。
$geoip_region_namengx_http_geoip_module, ngx_stream_geoip_module根据客户端 IP 通过 GeoIP 模块解析的地区名称。
$gzip_rationgx_http_gzip_module压缩后的响应体与原始响应体的大小比例。
$hostngx_http_core_module请求中的 "Host" 头字段,如果请求中没有提供,则为服务器名称。
$hostnamengx_http_core_module, ngx_stream_core_module服务器的主机名。
$http2ngx_http_v2_module表示是否使用 HTTP/2 协议。
$http3ngx_http_v3_module表示是否使用 HTTP/3 协议。
$http_<header>ngx_http_core_module任何 HTTP 请求头字段的值,<header>代表请求头字段名。
$httpsngx_http_core_module如果连接使用 SSL/TLS,则为 "on";否则为空。
$invalid_refererngx_http_referer_module如果请求的引用页不符合指定的有效列表,则为 "1";否则为空。
$is_argsngx_http_core_module如果请求中有查询字符串,则为 "?";如果没有,则为空。
$jwt_claim_<name>ngx_http_jwt_module从 JWT 令牌中解析出的特定声明。<name> 是声明的名称。
$jwt_header_<name>ngx_http_jwt_module从 JWT 令牌的头部中解析出的特定字段。<name> 是字段的名称。
$jwt_payloadngx_http_jwt_moduleJWT 令牌的负载部分。
$limit_conn_statusngx_http_limit_conn_module, ngx_stream_limit_conn_module表示当前请求是否被限制连接数模块拒绝。
$limit_ratengx_http_core_module用于限制连接速率的值。
$limit_req_statusngx_http_limit_req_module表示当前请求是否被限制请求频率模 块拒绝。
$memcached_keyngx*http_memcached_module用于 memcached 服务的键。
$modern_browserngx_http_browser_module根据 User-Agent 判断请求是否来自现代浏览器。
$mqtt_preread_clientidngx_stream_mqtt_module在 MQTT 流协议中预读的客户端 ID。
$mqtt_preread_usernamengx_stream_mqtt_module在 MQTT 流协议中预读的用户名。
$msecngx_http_core_module, ngx_http_log_module, ngx_stream_core_module当前时间的毫秒表示。
$msiengx_http_browser_module如果请求来自 Microsoft Internet Explorer,返回 "1",否则为空。
$nginx_versionngx_http_core_module, ngx_stream_core_module运行的 Nginx 版本。
$otel_parent_idngx_http_opentelemetry_moduleOpenTelemetry 父 ID。
$otel_parent_sampledngx_http_opentelemetry_module表示 OpenTelemetry 父样本是否被采样。
$otel_span_idngx_http_opentelemetry_moduleOpenTelemetry 跨度 ID。
$otel_trace_idngx_http_opentelemetry_moduleOpenTelemetry 跟踪 ID。
$pidngx_http_core_module, ngx_stream_core_module处理请求的工作进程的 PID。
$pipengx_http_core_module, ngx_http_log_module如果请求通过管道传输,则返回 "p",否则为 "."。
$protocolngx_http_core_module使用的协议,例如 "HTTP/1.1" 或 "HTTP/2.0"。
$proxy_add_x_forwarded_forngx_http_proxy_module向请求添加 "X-Forwarded-For" 头部,包含原始客户端的 IP 地址。
$proxy_hostngx_http_proxy_module代理请求的主机名。
$proxy_portngx_http_proxy_module代理请求的端口号。
$proxy_protocol_addrngx_http_core_module, ngx_stream_core_module使用 PROXY 协议时的客户端地址。
$proxy_protocol_portngx_http_core_module, ngx_stream_core_module使用 PROXY 协议时的客户端端口号。
$proxy_protocol_server_addrngx_http_core_module, ngx_stream_core_module使用 PROXY 协议时的服务器地址。
$proxy_protocol_server_portngx_http_core_module, ngx_stream_core_module使用 PROXY 协议时的服务器端口号。
$proxy_protocol_tlv*ngx_http_core_module, ngx_stream_core_modulePROXY 协议中的 TLV 数据。
$proxy_protocol_tlv_aws_vpce_idngx_http_proxy_protocol_vendor_module, ngx_stream_proxy_protocol_vendor_module使用 AWS VPC Endpoint ID 的 PROXY 协议 TLV 数据。
$proxy*protocol_tlv_azure_pel_idngx_http_proxy_protocol_vendor_module, ngx_stream_proxy_protocol_vendor_module使用 Azure Private Endpoint Link ID 的 PROXY 协议 TLV 数据。
$proxy_protocol_tlv_gcp_conn_idngx_http_proxy_protocol_vendor_module, ngx_stream_proxy_protocol_vendor_module使用 Google Cloud Platform 连接 ID 的 PROXY 协议 TLV 数据。
$query_stringngx_http_core_module请求中的查询字符串,与$args 相同。
$realip_remote_addrngx_http_realip_module, ngx_stream_realip_module使用 realip 模块处理后的客户端 IP 地址。
$realip_remote_portngx_http_realip_module, ngx_stream_realip_module使用 realip 模块处理后的客户端端口号。
$realpath_rootngx_http_core_module当前请求的真实根路径,与符号链接无关。
$remote_addrngx_http_core_module, ngx_stream_core_module客户端的 IP 地址。
$remote_portngx_http_core_module, ngx_stream_core_module客户端的端口号。
$remote_userngx_http_core_module通过身份验证确定的用户名称。
$requestngx_http_core_module完整的请求行,例如 "GET /index.html HTTP/1.1"。
$request_bodyngx_http_core_module在 POST 请求中读取的请求体。
$request_body_filengx_http_core_module将请求体存储在文件中的位置。
$request_completionngx_http_core_module如果请求成功完成,则为 "OK"。
$request_filenamengx_http_core_module当前连接请求的文件路径。
$request_idngx_http_core_module请求的唯一 ID,通常用于日志或调试。
$request_lengthngx_http_core_module, ngx_http_log_module请求的总长度(包括请求行、头部和主体)。
$request_methodngx_http_core_module请求使用的方法,例如 GET 或 POST。
$request_timengx_http_core_module, ngx_http_log_module请求处理的总时间,以秒为单位。
$request_uringx_http_core_module完整的请求 URI(包括查询字符串)。
$schemengx_http_core_module请求使用的协议(http 或 https)。
$secure_linkngx_http_secure_link_module如果链接安全,则返回生成的值,否则为空。
$secure_link_expiresngx_http_secure_link_module安全链接的过期时间。
$sent_http*<header>ngx_http_core_module响应中发送的指定 HTTP 头部的值。
$sent_trailer*<name>ngx_http_v2_module在 HTTP/2 响应中发送的指定尾部(trailer)字段的值。
$server*addrngx_http_core_module, ngx_stream_core_module服务器的 IP 地址。
$server_namengx_http_core_module服务器名称,通常是请求行或 Host 头部指定的。
$server_portngx_http_core_module, ngx_stream_core_module服务器的端口号。
$server_protocolngx_http_core_module请求使用的协议版本,例如 HTTP/1.1 或 HTTP/2。
$session_log_binary_idngx_stream_session_log_module流会话日志的二进制 ID。
$session_log_idngx_stream_session_log_module流会话日志的 ID。
$session_timengx_stream_core_module流会话持续的时间。
$slice_rangengx_http_slice_module用于 HTTP 切片(slice)请求的 Range 头部。
$ssl_alpn_protocolngx_http_ssl_module, ngx_stream_ssl_moduleSSL/TLS 握手中协商的应用层协议协商(ALPN)协议。
$ssl_cipherngx_http_ssl_module, ngx_stream_ssl_module使用的 SSL/TLS 密码套件。
$ssl_ciphersngx_http_ssl_module, ngx_stream_ssl_module服务器支持的 SSL/TLS 密码套件列表。
$ssl_client_certngx_http_ssl_module, ngx_stream_ssl_module以 PEM 格式返回客户端证书。
$ssl_client_escaped_certngx_http_ssl_moduleURL 编码格式返回客户端证书。
$ssl_client_fingerprintngx_http_ssl_module, ngx_stream_ssl_module客户端证书的 SHA-1 指纹。
$ssl_client_i_dnngx_http_ssl_module, ngx_stream_ssl_module客户端证书的颁发者 DN(Distinguished Name)。
$ssl_client_i_dn_legacyngx_http_ssl_module客户端证书的传统颁发者 DN。
$ssl_client_raw_certngx_http_ssl_module, ngx_stream_ssl_module客户端原始证书数据。
$ssl_client_s_dnngx_http_ssl_module, ngx_stream_ssl_module客户端证书的主题 DN(Distinguished Name)。
$ssl_client_s_dn_legacyngx_http_ssl_module客户端证书的传统主题 DN。
$ssl_client_serialngx_http_ssl_module, ngx_stream_ssl_module客户端证书的序列号。
$ssl_client_v_endngx_http_ssl_module, ngx_stream_ssl_module客户端证书的有效期结束日期。
$ssl_client_v_remainngx_http_ssl_module, ngx_stream_ssl_module客户端证书的剩余有效天数。
$ssl_client_v_startngx_http_ssl_module, ngx_stream_ssl_module客户端证书的有效期开始日期。
$ssl_client_verifyngx_http_ssl_module, ngx_stream_ssl_module客户端证书验证结果,可能的值为 SUCCESS, FAILED, NONE。
$ssl_curvengx_http_ssl_module, ngx_stream_ssl_module协商的 ECC 曲线名称。
$ssl_curvesngx_http_ssl_module, ngx_stream_ssl_module服务器支持的 ECC 曲线列表。
$ssl_early_datangx_http_ssl_module表示客户端是否发送了 TLSv1.3 早期数据。
$ssl_preread_alpn_protocolsngx_stream_ssl_preread_module通过 SSL/TLS 握手预读的 ALPN 协议。
$ssl_preread_protocolngx_stream_ssl_preread_module通过 SSL/TLS 握手预读的协议。
$ssl_preread_server_namengx_stream_ssl_preread_module通过 SSL/TLS 握手预读的服务器名称(SNI)。
$ssl_protocolngx_http_ssl_module, ngx_stream_ssl_module使用的 SSL/TLS 协议版本。
$ssl_server_namengx_http_ssl_module, ngx_stream_ssl_moduleSSL/TLS 握手中的服务器名称指示(SNI)字段值。
$ssl_session_idngx_http_ssl_module, ngx_stream_ssl_moduleSSL/TLS 会话的 ID。
$ssl_session_reusedngx_http_ssl_module, ngx_stream_ssl_module表示 SSL/TLS 会话是否为重用会话。
$statusngx_http_core_module, ngx_http_log_module, ngx_stream_core_module响应的 HTTP 状态码。
$tcpinfo_rttngx_http_core_module, ngx_stream_core_module客户端 TCP 连接的往返时间 (RTT),以微秒为单位。
$tcpinfo_rttvarngx_http_core_module, ngx_stream_core_moduleTCP 连接的往返时间变化。
$tcpinfo_snd_cwndngx_http_core_module, ngx_stream_core_moduleTCP 连接的发送拥塞窗口大小。
$tcpinfo_rcv_spacengx_http_core_module, ngx_stream_core_moduleTCP 连接的接收缓冲区大小。
$time_iso8601ngx_http_core_module, ngx_http_log_module, ngx_stream_core_module当前时间,以 ISO 8601 标准格式输出,包括日期和时间。
$time_localngx_http_core_module, ngx_http_log_module, ngx_stream_core_module当前时间,以本地时间格式输出。
$uid_gotngx_http_userid_module当前请求中获取的用户 ID(如果设置了用户 ID 模块)。
$uid_resetngx_http_userid_module表示用户 ID 是否被重置。
$uid_setngx_http_userid_module当前请求中设置的用户 ID(如果设置了用户 ID 模块)。
$upstream_addrngx_http_upstream_module, ngx_stream_upstream_module向上游服务器发送请求时使用的地址和端口。
$upstream_bytes_receivedngx_http_upstream_module, ngx_stream_upstream_module从上游服务器接收的字节数。
$upstream_bytes_sentngx_http_upstream_module, ngx_stream_upstream_module向上游服务器发送的字节数。
$upstream_cache_statusngx_http_upstream_module缓存响应的状态,可能的值包括 MISS, BYPASS, EXPIRED, STALE, UPDATING, REVALIDATED 或 HIT。
$upstream_connect_timengx_http_upstream_module, ngx_stream_upstream_module建立到上游服务器的连接所需的时间,以秒为单位。
$upstream_cookie*<name>ngx_http_upstream_module从上游响应中获取的名为<name>的 Cookie 值。
$upstream_first_byte_timengx_http_upstream_module从连接上游开始到接收到第一个字节的时间。
$upstream*header_timengx_http_upstream_module接收上游响应头的时间。
$upstream_http*<header>ngx_http_upstream_module上游响应中的指定 HTTP 头部字段<header>的值。
$upstream_last_server_namengx_http_upstream_module用于处理当前请求的上游服务器名称。
$upstream*queue_timengx_http_upstream_module在与上游服务器建立连接之前,请求在队列中等待的时间。
$upstream_response_lengthngx_http_upstream_module从上游服务器接收的响应长度。
$upstream_response_timengx_http_upstream_module从发送请求到上游开始到接收完整响应的时间,以秒为单位。
$upstream_session_timengx_stream_upstream_module完整的上游会话时间。
$upstream_statusngx_http_upstream_module从上游服务器接收的响应的 HTTP 状态码。
$upstream_trailer*<name>ngx_http_v2_module在 HTTP/2 响应中从上游服务器接收的指定尾部<name>的值。
$uringx_http_core_module请求中的 URI,不包括查询字符串。