首先使用命令确认Nginx配置所在位置,使用命令如下:
sudo nginx -t
显示如图:
则我的配置文件在/etc/nginx目录中。
配置文件一般是一个文本文件,可以由程序解析,通过为一组指令指定值便定义了程序的行为,配置nginx只需要掌握一些机制:指令、区段(block)和整体逻辑结构,实际配置过程中,大多为指令填写值。
nginx的配置文件实际是一个具有一定逻辑结构的一组指令列表,修改指令值即可控制应用程序。
nginx的配置文件默认安装在/usr/local/nginx/conf/nginx.conf,查看nginx.conf文件:
# more /usr/local/nginx/conf/nginx.conf
前两行配置如下:
#user nobody;
worker_processes 1;
1
2
使用字符”#”注释掉了第一行,第二行声明了一条指令,worker_processes是一个键,它对应的值设置为1,以";"结尾,这条指令指定了nginx作为单个工作进程工作。
每个指令都有不同的语法,例如指令worker_processes只接受一个数值,指令user需要指定两个字符串值:用户账户(nginx的woker进程使用该账户运行)和用户组。
nginx通过模块的方法构建而成,每一个模块都提供一组指令,最根本的指令是nginx核心模块部分。
在配置文件中有如下的指令:
include mime.types;
该指令用来执行对一个特定文件的包含,即在配置文件的内容中,将被插入的文件通过include指令插入到确切的位置上,实际例子如下:
nginx.conf文件内容:
user nginx nginx;
worker_processes 4;
include other_settings.conf;
other_settings.conf文件内容如下:
error_log logs/error.log;
pid logs/nginx.pid;
nginx解释配置文件的最终结果如下:
user nginx nginx;
worker_processes 4;
error_log logs/error.log;
pid logs/nginx.pid;
在nginx最初的配置文件中使用了两个文件nginx.conf和mime.types( include mime.types;),对于高级配置而言,至少需要5个文件:
标准名称 描述
nginx.conf 应用程序的基本配置文件
mime.types 文件扩展列表文件,它们与MIME类型关联
fastcgi.conf 与FastCGI相关的配置文件
proxy.conf 与Proxy相关的配置文件
sites.conf 配置nginx提供的网站,也包括众所周知的虚拟主机,推荐一个域建立一个单独的文件
以上文件名是依据惯例定义的,实际上完全可以使用其他文件名。
include指令支持文件名替换,例如:
include sites/*.conf
这将包含sites目录下的所有.conf文件,这种机制允许你为自己的网站建立单独的配置文件,然后再将它们全部包含进来。
指令块
指令由模块提供,如果激活了一个模块,那么该模块对应的指令也同时生效,如下:
events {
worker_connections 1024;
}
events模块提供的指令worker_connections 1024;只能放在events区段才有意义。
有些指令可以写在配置文件顶部,起到全局效果:
不同区段可以互相嵌套:
上述例子展示了网站对nginx的配置,在http区段可以声明多个server区段,一个server区段允许配置一个虚拟主机和监听的端口,在server区段内允许插入多个location区段,当需要对特定的路径进行URL匹配时,Location区段允许对这些路径单独设置。
一个区段嵌套其它区段,被嵌套的区段将继承其父区段的设置,上述例子server区段设置了access_log指令来记录服务器所有的HTTP请求,在location区段同样生效,可以在location区段重新设置access_log:
单位 描述
k/K 千字节
m/M 兆字节
ms Milliseconds–毫秒
s Seconds–秒(默认时间单位)
m Minutes–分钟
h Hours–小时
d Days–天
w Weeks–星期
m Months–月(30天)
y Years–年(365天)
模块提供各种变量,注意:有些指令不允许使用变量,例如:
error_log logs/error-$nginx_version.log
这是一个有效的配置指令,但它只产生一个error-$nginx_version.log文件,并不解析变量。
将字符串作为指令值,可以没有引号,但如果使用的是特殊字符,例如:空格符、分号(;)、花括号({}),就需要使用引号将其括起:
root '/home/example.com/my web pages'
注意:无论使用单引号、双引号,nginx都认为没有区别。
我们在域名配置文章中已经有配置如下:
server
{
listen 80;
server_name my.525.life;
location / {
#....
proxy_pass http://localhost:8880;
}
##### other directive
}
其实就是将Nginx的所有请求都转发给
http://localhost:8880
配置静态资源服务器的话,就是把一部分请求分离出来,让这些请求直接访问到服务器的磁盘目录中。
例如配置如下:
指定路径对应的目录。location可以使用正则表达式匹配。并指定对应的硬盘中的目录。如下:
location /image/ {
root /usr/local/static/;
autoindex on;
}
这个配置表示输入 localhost:80/image/ 或者my.525.life/image/ 时会访问本机的/usr/local/static/image/ 目录。
如果没有/usr/local/static/image/ 目录则需要新建 /usr/local/static/image/ 目录,在/usr/local/static/image/ 中我们放一张图片1.jpg上去,重启nginx服务,就可以通过 localhost:80/image/1.jpg访问了。
创建目录
mkdir /usr/local/static/image
#放一张照片上去#
cd /usr/local/static/image
ls
1.jpg
重启 nginx
sudo nginx -s reload
打开浏览器 输入 server_name/image/1.jpg 就可以访问该静态图片了
更多配置参数和匹配规则
语法规则: location [=|~|~*|^~] /uri/ { … }
= 开头表示精确匹配
^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。
~ 开头表示区分大小写的正则匹配
~* 开头表示不区分大小写的正则匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则
/ 通用匹配,任何请求都会匹配到。
多个location配置的情况下匹配顺序为:
首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
例子,有如下匹配规则:
location = / {
#规则A
}
location = /login {
#规则B
}
location ^~ /static/ {
#规则C
}
location ~ \.(gif|jpg|png|js|css)$ {
#规则D
}
location ~* \.png$ {
#规则E
}
location !~ \.xhtml$ {
#规则F
}
location !~* \.xhtml$ {
#规则G
}
location / {
#规则H
}
那么产生的效果如下:
访问根目录/, 比如http://localhost/ 将匹配规则A
访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H
访问 http://localhost/static/a.html 将匹配规则C
访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用,而 http://localhost/static/c.png 则优先匹配到规则C
访问 http://localhost/a.PNG 则匹配规则E,而不会匹配规则D,因为规则E不区分大小写。
访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。
访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理服务器存在。
所以实际使用中,个人觉得至少有两个匹配规则定义,如下:
# 第一个必选规则,处理动态请求转发到tomcat
location = / {
proxy_pass http://localhost:8080
}
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
root /webroot/res/;
}
if(condition){...}
使用环境:server,location
该指令用于检查一个条件是否符合,如果条件符合,则执行大括号内的语句。
if指令不支持嵌套,不支持多个条件&&和||处理
其中,condition中可以包含的判断标识如下:
~区分大小写匹配
~*不区分大小写匹配
!~区分大小写不匹配
!~*不区分大小写不匹配
-f 和 !-f 用来判断是否存在文件
-d 和 !-d 用来判断是否存在目录
-e 和 !-e 用来判断是否存在文件或目录
-x 和 !-x 用来判断是否可执行
如下:如果是IE浏览器就进行跳转
if ($http_user_agent ~MSIE){
rewrite ^(.*)$/msie/$1 break;
}
语法:return code
使用环境:server,location, if
该指令用于结束规则的执行并返回状态码给客户端,
状态码包括:
204(no content)
400(bad request)
402(payment required)
403(forbidden)
404(not found)
405(method not allowed)
406(not acceptable)
408(request timeout)
410(gone)
411(length required)
413(request entity too large)
416(requested range not satisfiable)
500(internal server error)
501(not implemented)
502(bad gateway)
503(service unavailable)
504(gateway timeout)
如下,如果访问的URL以.sh .bash结尾,返回状态码给403
location ~ .*\.(sh|bash)?$
{
return 403;
}
语法:set variable value
使用环境:server,location, if
该指令用于定义个变量,并给变量赋值
语法:rewrite regex replacement flag
使用环境:server,location, if
该指令根据表达式来重定向URI,或者修改字符串
flag标记有:
last相当于apache里的[L]标记,表示完成rewrite
break终止匹配,不再匹配后面的规则
redirect返回302临时重定向,地址栏会显示跳转后的地址
permanent返回301永久重定向,地址栏会显示跳转后的地址
示例,将www重定向到http://
if ($host ~* www\.(.*)){
set $host_without_www $1;
rewrite ^(.*)$ http://$host_without_www$1 permanent;
}
rewrite ^(.*)$ http://blog.720ui.com permanent;
if ( !-e $request_filename ){
rewrite ^/(.*)$ error.html last;
}
rewrite ^/b/?$ /bbs permanent;
/123456/xxxx ====> /xxxx?id=123456
rewrite ^/(d+)/(.+)/ /$2?id=$1 last;
根据不同的浏览器将得到不同的结果
if ($http_user_agent ~ Firefox) {
rewrite ^(.*)$ /firefox/$1 break;
}
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($http_user_agent ~ Chrome) {
rewrite ^(.*)$ /chrome/$1 break;
}
location ~*\.(gif|jpg|png|swf|flv)${
valid_referers none blocked www.cheng.com*.test.com;
if ($invalid_referer)
rewrite ^/(.*) http://www.lianggzone.com/error.html
}
location ~ ^/data
{
deny all;
}
location ~ .*\.(sh|exe)?$
{
return 403;
}
location ~ .*.(gif|jpg|jpeg|png|bmp)$
{
expires 30d;
}
location ~ .*.(js|css)$
{
expires 1h;
}
Nginx变量
1) $args
存放URL中的请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
2) $content_length
存放请求报文中content_length字段内容
3) $content_type
存放请求报文中content_type字段内容
4) $document_root
存放针对当前请求的根路径
5) $document_uri
存放请求报文中的当前URI,并且不包括请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
/reg/person
6) $host
存放请求报文中的主机部分
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
reg.jd.com
7) $http_user_agent
存放客户端代理信息(浏览器)
8) $http_cookie
存放客户端的cookie信息
9) $limit_rate
存放nginx服务器对网络连接速率的限制,也就是ngnix配置文件中limit_rate指令的值
10) $remote_addr
存放客户端地址
11) $remote_port
存放客户端端口
12) $remote_user
存放客户端的用户名
13) $request_body_file
存放发给后端服务器的本地文件资源名称
14) $request_method
存放客户端请求资源的方法, GET, POST, PUT, DELETE, HEAD
15) $request_filename
存放当前请求的资源文件的路径名
16) $request_uri
存放当前请求的URI,并且带有请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
17) $query_string
与变量$args含义相同
18) $scheme
存放客户端请求使用的协议,如果http, https
19) $server_protocol
存放客户端请求协议的版本 HTTP/1.0 HTTP/1.1
20) $server_addr
存放服务器地址
21) $server_name
存放了客户端请求到达的服务器的名称
22) $server_port
存放了客户端请求到达的服务器的端口号
23) $uri
与变量$document_uri含义相同