下面我们来看一下 nginx 配置语法。Nginx 的二进制文件中已经指定它包含了哪些模块,但每一个模块都会提供独一无二的配置语法,这些所有的配置语法会遵循同样的语法规则。下面我们来看一下主要的语法规则。
Nginx 的配置文件是一个 ask 文本文件,这个文本文件主要有两部分组成,一个叫做dev指令,一个叫dev block指令块。
我们可以看到这个例子中像http大括号,这就是一个指令块。而 include mine.types; 这是一条指令,每条指令都是以分号结尾的,指令和参数间以空格符号分隔。我们还是拿刚刚 include 来看。include是一个指令名,它中间呢可以一个或者多个空格来分隔。那么后面的mime.types 就是它的参数,它可以具备一个参数,我们可以看到下面也可以具备多个参数,比如说 limit_req_zone,它具备了一个、两个、三个参数。那么两条指令间呢。不是以回车作为分隔符的,还是以分号。我们可以看到,把两条指令放在一行中写也是没有问题的,只不过这样可读性会变得很差。
第三,指令块呢是以大括号组成的,它会将多条指令组织在一起。比如 upstream,他把了一条指令 server 放在了 thwp 这个指令块下面,像 server 它也放置了listen、limit_req_zone 这些指令,它还可以包含其他的指令块,比如说 location。那么有些指令块呢可以有名字,比如像 upstream后面有个 thwp。 location 后面也可以有名字。但是有些指令块呢是没有名字的,比如说 server 和 http,究竟什么样的指令有名字,什么样的指令没有名字呢?这是由提供这个指令块的 nginx 模块来决定的,它可以决定指令块后面有一个或者说多个参数,或者说没有参数。
我们看第四条 include 语句,它允许组合多个配置文件以提升可维护性。在我们这个例子中呢,mime.types这个文件中其实里面是含有很多条不同的文件的后缀名,与http协议中mine格式者对照关系表,这些关系指令呢其实是非常的耦合在一起的,和我们的语法关联不大。所以我们用了 include 的这样一个语法以后呢,我们整个文件的可读性好了很多,还不是简单的列在这里。
第五呢我们使用 # 符号呢可以添加注释,提升可读性,这非常简单。比如在server list后面我们加了一个N X配置语法,以描述我们下面一些配置的表达。
第六,使用 $ 符号呢,可以使用变量,我们可以看个例子,这里有两个例子,一个是 limit_req_zone,它控制了我们的流控,这里我们用了一个参数叫 $binary_remote_addr。它其实描述的远端的地址。这是一个变量,这个变量并不是limit request这个模块提供的,还是 nginx 的框架提供的。还有下面 proxy_cache_key 后面也是。使用了四个变量,$host $uri #is_args $args。同样的proxy这个模块并不提供这些变量,这些变量是由其他模块提供的。
我们看第七条—部分指令的参数是支持正则表达式的。比如 location 后面,我们可以看到它可以支持非常复杂的正则表达式,而且可以把正则表达式中括号里的内容通过 $1 $2 等方式取出来。那么在 nginx 的配置文件中呢,当涉及到时间的时候,我们还有许多种表达方式,比如以下八种,
包括毫秒、秒、分钟、小时、天、周、月、年,我们再看一个例子,比如这里 expires 3m; 就表示说三分钟后我希望这个catch刷新。
那么空间也是有单位的,当我们后面不加任何的后缀名的时候,表示字节加了小K或者大K表示千字节,后面M表示兆字节G。我们看看就这个例子,还是看 limit_req_zone,这里我们开了一个 10m,也就是十兆的一个内存大小的共享内存空间,以给不同的worker去使用。
那么在http这样的框架中呢,它里面有四个块,像http、server、location、upstream,我们再简单的说一下 http 大括号里面呢表示里面所有的指令都是由http模块去解析去执行的一个非 http 模块。比如说像stream或者像M啊,他们是没有办法去解析这里面的指令了。那么 upstream 呢则表示是上游服务。当我们 nginx 需要与tomcat、django等等我们企业内网的其他服务交互的时候呢,我们可以定义一个upstream。server 呢则是一个对应的一个域名,或者对应一组域名。location 呢则是一个URL表达式。以上是 nginx 的基本语法配置规则。