nginx内置变量和指令的关系

这是一个很好的问题,能问到这个深度,说明你已经从“会用”开始迈向“理解”了。

一句话回答指令是“动作”,变量是“信息”

  • 指令:你告诉 Nginx 要做什么(比如:proxy_pass 表示要转发,rewrite 表示要重写)。
  • 变量:你告诉 Nginx 用什么信息来做(比如:用 $remote_addr 记录客户端IP,用 $request_uri 匹配路径)。

我用一个表格和几个实例来帮你彻底理清它们的关系。

一、核心区别

维度指令 (Directive)内置变量 (Built-in Variable)
角色动词(下达命令)名词(提供信息)
本质Nginx 的配置项,驱动功能模块工作Nginx 内部维护的数据字段,动态变化的
语法关键字 + 参数 + ;,如:gzip on;$ 开头,如:$host
存在位置写在 nginx.conf 里,是配置的主体可以在配置值、条件判断、日志格式中被引用
谁定义由 Nginx 的各个模块定义(如 ngx_http_proxy_module 定义了 proxy_pass由 Nginx 核心或模块在运行时提供(如 HTTP 模块提供 $http_user_agent
示例proxy_passrewritesetif$remote_addr$uri$args$http_cookie

二、它们的“关系”是什么?

它们是“控制流”与“数据”的关系。指令负责逻辑和动作,变量为这些动作提供输入、上下文和输出目标。

我用几个你熟悉的 Nginx 配置片段来解释它们的配合:

关系 1:变量作为指令的“参数”

这是最直接的关系。指令的值,可以是一个具体的字符串,也可以是一个包含变量的表达式。

# 变量 $host 作为 proxy_pass 指令的参数
proxy_pass http://backend_$host;

# 变量 $remote_addr 作为 add_header 指令的参数
add_header X-Real-IP $remote_addr;

关系 2:变量在 if 指令中作为“判断条件”

if 是逻辑判断指令,它判断的对象,就是变量。

# 判断 $http_user_agent 这个变量是否匹配正则
if ($http_user_agent ~* "mobile") {
    # 这里的 rewrite 是另一个指令
    rewrite ^(.*)$ /mobile/$1 last;
}

关系 3:用 set 指令“创建或修改变量”

set 是一个用来操作变量的指令。你可以用它来创建自定义变量,或者修改现有变量的值,供后续指令使用。

# 创建一个新变量 $flag,并赋值为 0
set $flag 0;

# 根据条件修改变量值
if ($request_method = POST) {
    set $flag "${flag}1";
}
# 后续的 proxy_pass 或其他指令可以引用 $flag

关系 4:变量在 log_format 指令中定义“日志格式”

log_format 是一个用来定义日志模板的指令,它的模板内容就是由各种变量组成的。

# log_format 指令定义日志里要记录哪些变量
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

三、总结

指令变量
proxy_pass$host (告诉它转给谁)
if$request_method (告诉它判断什么)
rewrite$1, $2 (告诉它替换成什么)
set操作变量本身 (它就是用来定义或修改变量的)
log_format$time_local (告诉它记录什么)

你可以这样理解:指令是 Nginx 配置的“骨架”,搭建起整个处理流程;变量是流淌在骨架里的“血液”,为每一个环节提供动态的、实时的信息。 你现在能写出灵活的配置,正是因为理解了如何用指令去驾驭这些变量。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注