本文主要对nginx的配置做重点说明,关于nginx的其它基本概念,建议参考官网描述,这里推荐Nginx Beginner's Guide这篇文档,对初学者快速认识nginx很有帮助。
显然,发挥nginx强大优势的前提是熟悉其配置文件并进行合理的配置,而学习nginx配置时,最重要的一点是建立如下概念:
The most important is that nginx is a reverse proxy first and HTTP server second, its first concern is not files but rather URLs, this changes the way we have to configure nginx.
也即,nginx的强大之处在于其高性能的反向代理功能(接收请求并传递给下游真正处理请求的servers;等待下游响应并返回给请求发起方),其次,它也能像普通webserver那样提供静态文件访问功能。
我们以nginx源码编译安装后的默认配置文件(conf/nginx.conf.default)为例,对重要的配置项进行说明。#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
1. Nginx配置文件区块层级关系
要熟悉nginx配置文件,首先要清楚区块划分及区块间的层级关系,关于这一点,UNDERSTANDING THE NGINX CONFIGURATION INHERITANCE MODEL一文对各区块层级划分、层级或配置项类型、配置项的继承关系及嵌套区块定义等方面均做了详细且带实例的说明,这里不再赘述。我们需要牢记其中3个区块间的层级关系:http->server->location,它们是nginx配置过程中的关键区块。
2. Server区块(Virtual Host)
server block主要目的是创建virtual server,其最重要的设置项有3个:
1) listen
设置侦听地址、端口号、UNIX-domain socket的路径。可以只设置侦听地址(ip或hostname),这种情况下默认侦听80端口,也可以只指定侦听端口号。此外,还可以设置是否是default server, connection是否ssl加密,proxy_protocol,等等。
详细的设置语法和设置项可以参考这里的官方文档。
2) server_name
设置该server block的域名,支持精确域名、带通配符的域名和正则表达式这3种格式,具体规则见这里。nginx接收到请求URL后,会根据各server block配置的server_name搜索处理本次请求的server,第1个match成功(请求URL的header指定的域名与server_name做匹配)的server block负责处理URL请求。从文档可知,具体的搜索顺序优先级如下(由高到低):
a. the exact name
b. the longest wildcard name starting with an asterisk, e.g. “*.example.com”
c. the longest wildcard name ending with an asterisk, e.g. “mail.*”
d. the first matching regular expression (in order of appearance in the configuration file)
实际上,配置server_name时,精确域名、由*开头的通配域名、由*结尾的通配域名被会分别存储在与listen port关联的3个hash表中。nginx根据server_name搜索server block时,会按上述顺序依次搜索这3个hash表,只要有1个hash表的某项配置命中,则搜索结束,此时,用户请求URL会交给该成功匹配的server_name所属的server区块来处理。若3个hash表均搜索失败,则会依次搜索正则表达式格式的server_name。由于reg exp match相对最慢,故其搜索优先级最低。
因此,在实际使用时,我们应该尽可能配置精确域名。
此外,若需配置很多server名或某个server域名非常长,则应该分别优化server_names_hash_max_size和server_names_hash_bucket_size这2个配置项,具体说明可见这篇文档的Optimization部分。
3) location
详见下一小节的说明
3. Location区块
关于location block,需要清楚如下几个重要规则:
1) 除命名location(named location)区块外,其余location区块均作用在不带query参数的URL上,且每次只会有1个location区块起作用。这也是目录配置通常置于最顶层区块的原因,因为定义在location /的root目录设置不能被用于location /images,而若将root目录设置在server区块,则所有的location区块均可使用该设置(当然,在location区块中可以改写本区块的root目录设置),无论是消除重复代码还是后续维护方面,均要方便得多。
2) nginx会根据location区块的server_name来分配请求URL。nginx对URL和location区块的match规则如下(官网文档在这里):
a. 首先查找由前缀字符串(prefix string)定义的location区块,在前缀字符串匹配成功的所有location区块中,最长前缀匹配的那个block会由nginx记录下来;
b. 接着nginx按在配置文件中定义的先后顺序检查由正则表达式定义的location区块,当正则匹配成功某个区块后,查找结束,该区块负责处理URL,整个match过程随之结束;
c. 若没有由正则指定的location区块匹配成功,则返回第1步记录的最长前缀匹配的区块,整个match过程结束。
几点特别说明:
a. 由正则表达式定义的location区块具有较低的搜索优先级,但具有较高的匹配优先级。这一点与nginx搜索server_name的规则不同(server_name是按搜索优先级匹配,一旦匹配成功就立即结束搜索),需引起特别注意。
b. location还可以用等号(=)做精确配置,它具有最高的匹配优先级,只要命中精确匹配的location,nginx对location区块的搜索立即结束。
3) 配置的具体语法规则详见官网文档,这里不赘述。
在熟悉主要区块(http/server/location)基本配置规则的前提下,配置nginx来实现反向代理服务器其实很简单,在location区块通过配置proxy_pass或fastcgi_pass即可实现。
此外,还可以配置哪个source address的request代理到哪个下游服务(proxy_bind),是否对下游响应头做buffer及buffer区大小(proxy_buffering/proxy_buffer_size),是否对响应结果做cache(proxy_cache),等等。
详细的配置语法可分别参考文档Module ngx_http_proxy_module和Module ngx_http_fastcgi_module。
【参考资料】
1. UNDERSTANDING THE NGINX CONFIGURATION INHERITANCE MODEL2. NGINX CONFIGURATION PRIMER
3. Nginx Beginner’s Guide
======================= EOF ===================