nginx的配置总结

总体而言,nginx的配置比起apache来是要简洁很多,而言容易理解得多的,另外官网的文档也十分的简洁易懂。我们先看一个简化版的配置文件nginx.conf:

#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;
// ... ...
} # another virtual host using mix of IP-, name-, and port-based configuration
#server {
# listen 8000;
   // ... ...
#}
// ... ...
}

 1. 可以看到nginx的配置文件可以分成两大部分

1)对nginx自己的进程的相关的配置:1.worker进程的数量;2.每个进程最多能够处理多少个连接;3.运行nginx的用户;4.日志文件;5.pid文件地址

2)对http服务器的配置,也就是 http 服务器的配置

2. nginx进程相关的配置:

worker_processes 配置worker进程的数量,一般根据负载和CPU来将其设置成:cpu * 核心数,设置的太多会造成对CPU的争用;

worker_connections 配置每个worker进程能够处理多少个连接,一般根据内存,cpu, 负载来配置;

3. http服务器的配置:

nginx处理http的服务器的配置都在http段内。http段中又分为:http的全局配置;针对每个server的配置,也就是针对每个虚拟主机的配置;可以看到在nginx中可以像apache一样配置多个虚拟主机。而且要比apache配置要简单得多。每一个server段配置一个虚拟主机,虚拟主机中主要配置让其监听哪个端口,进来的url如何通过location的配置去访问磁盘上哪个目录中存放的哪个文件,所以location的配置才是重点所在。

(http服务器即http server是指:处理http请求的服务器;虚拟主机是指:处理对某个域名所有访问的虚拟出来的主机,不是一个实际意思上的主机)

4. server的配置:
server {
        listen         80;
        server_name  www.baidu.com;

    location / {}

    // ... ...

}

listen表示监听那个端口,对于http我们一般都是监听80端口。server_name表示我们的域名,也就是网址,比如:www.baidu.com, www.cnblogs.com等等。不同的server可以监听同一个80端口,但是server_name不能相同,也可以server_name相同,但是监听端口不一样。server段中的location段主要配置对于进入本虚拟主机的url的处理。

5. location的配置:
对于根据server端中配置的 listen 监听端口和 server_name 域名而进入对于虚拟主机的url,会根据 location 的匹配情况来访问某个匹配的 location,最后“定位”到服务器上的某个页面,来处理这个请求。而 url 到 location的匹配分为了三种情况:

1) location = pattern { ... } 精确匹配;

2) location    pattern { ... } 前缀匹配,匹配最长的;

3) location ~ pattern { ... } 正则匹配;(~:case-sensitive match, ~*:case-insensitive matching, ^~ 等等)

匹配优先级规则如下:

1> 精确匹配优先级最高,如果有精确并且匹配成功,那么就停止匹配过程,直接使用该匹配结果;

2> 正则表达式优先级第二,正则表达式按照出现的先后顺序进行匹配,匹配成功则立即结束匹配(按正则表达式出现的先后顺序);

3> 如果正则表达式没有匹配成功,则使用最长的前缀匹配结果(按前缀匹配的长度);

官方文档:http://nginx.org/en/docs/http/ngx_http_core_module.html#location

A location can either be defined by a prefix string, or by a regular expression. Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching). To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.

If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.

Also, using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a “/” request happens frequently, defining “location = /” will speed up the processing of these requests, as search terminates right after the first comparison. Such a location cannot obviously contain nested locations.

匹配的处理顺序规则如下:

1> 先从 精确匹配 开始处理,如果匹配,则返回,不在继续下面的步骤;

2> 然后进行 前缀匹配 的处理,处理时,记住最长的匹配结果,还要继续处理后面的匹配;

3> 最后才是 正则匹配,按照在配置文件中的前后顺序开始匹配,如果一有匹配的马上结束;如果处理完了正则匹配,没有发现匹配的,则使用第二步的匹配结果;

如果上面三步都没有匹配上,则会返回nginx的默认首页。

下面举个例子,实现的功能是,对于某个网站www.website.com,访问其首页时,使用http协议,除了首页之外的其他页面则使用https协议:

location = / {
root html;
index index.html index.htm;
}
location = /index.html {
root html;
}
location ~ ^/(.*) {
rewrite ^/(.*) https://$host/$1 permanent;
}

如果直接输入浏览器的是:www.website.com 则匹配的是第一个精确匹配:location = / ,得到访问的真实url:www.website.com/index.html,然后第二次精确匹配了第二个:location = /index.html,他会到 html目录中去找 index.html页面。

如果访问的不是 www.website.com 也不是 www.website.com/index.html,那么第一个和第二个精确匹配的Location都不会批评,所以会匹配后面的正则匹配,而正则匹配使用了url重写的技术,将其url重写为使用https协议的url:https://www.website.com/xxx

另外注意一点,http段中server_name匹配的是域名:www.website.com,而location匹配的是域名后面的url地址,location的匹配是不管前面的域名部分的。

6. location中的rewrite配置:

重写的作用是:用户浏览器访问的是 url1, 通过重写,将 url1 重写成 url2,就可以让其去访问 url2,用户浏览器显示的是重写之后的 url2 地址。(所以一般如果需要重写成非 80 端口的url时,为了不在用户浏览器地址上显示端口,一般我们不使用 rewrite, 而是使用 proxy_pass,所以我们应该根据不同的情况选择使用rewrite还是proxy_pass). 官方文档地址:http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

rewrite 经常用到的指令

1> 首先是 if 指令,对满足if条件的url 才进行重写:if  (条件) {  // 设定条件,再进行重写 }

2> rewrite 指令: rewrite xxx yyy; 将 xxx 重写为 yyy;

3> break 指令,用了避免循环重写;

if 条件的编写

<1> “=”来判断相等, 用于字符串比较;

<2> “~” 用正则来匹配(此处的正则区分大小写);

<3> ~* 不区分大小写的正则;

<4> -f -d -e 来判断是否为文件,目录,是否存在;

7. location的proxy_pass(反向代理)配置:

proxy_pass的功能看是和rewrite很相似,其实是不一样的,一般用于实现反向代理,rewrite是重新浏览器访问的地址,浏览器显示的是重写之后的地址,而proxy_pass不会改变浏览器的地址,他只是将浏览器的访问发送到另一个地址。使用proxy_pass一定要注意,不要丢失cookie,以及丢失了客户端的原始地址。不然会造成各种问题,一般的使用方法如下:(官网文档地址:http://nginx.org/en/docs/http/ngx_http_proxy_module.html)

nginx的配置总结

这里通过 proxy_pass 反向代理了后端的tomcat。实际处理请求的是后面的tomcat,但是直接处理用户请求的是nginx,所以称为代理,即nginx代理了tomcat,为什么又是反向呢?因为正向代理是指浏览器代理用户来访问页面,所以与正向代理相反的代理称为反向代理。

8. nginx的gzip压缩的配置:

在官方有详细的文档:http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip

gzip的压缩参数可以在下面Context中指定的地方配置:

nginx的配置总结

http段,server段,location段,以及location中的if语句中都可以进行 gzip 压缩相关的配置。

经常使用的参数有

gzip on|off;    #是否开启gzip

gzip_buffers 32 4K| 16 8K   #缓冲(压缩时使用几块款冲内存块,每块内存多大)

gzip_comp_level [1-9]     #推荐6 压缩级别(级别越高,压的越小,越浪费CPU计算资源)

gzip_disable          #正则匹配UA 什么样的Uri不进行gzip

gzip_min_length 200      # 开始压缩的最小长度,单位为k

gzip_types text/plain  application/xml # 对哪些类型的文件用压缩 如txt,xml,html ,css,可选值可以参见安装目录下的mime.types文件:

nginx的配置总结

gzip_vary on|off        # 是否传输gzip压缩标志

gzip_proxied                 # 设置当nginx做为反向代理服务器时,是否启用压缩

gzip_proxied 可以设置为下列值

off – 关闭所有的代理结果数据压缩,这是默认值!
expired – 启用压缩,如果header中包含”Expires”头信息
no-cache – 启用压缩,如果header中包含”Cache-Control:no-cache”头信息
no-store – 启用压缩,如果header中包含”Cache-Control:no-store”头信息
private – 启用压缩,如果header中包含”Cache-Control:private”头信息
no_last_modified – 启用压缩,如果header中包含”Last_Modified”头信息
no_etag – 启用压缩,如果header中包含“ETag”头信息
auth – 启用压缩,如果header中包含“Authorization”头信息
any – 无条件压缩所有结果数据

gzip启用压缩的示例:

gzip on;
gzip_disable "MSIE [1-6]\.";
gzip_min_length 200;
gzip_buffers 4 8k;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/html text/css application/javascript text/xml

在浏览器端查看gzip压缩是否起作用:

nginx的配置总结

另外要注意:图片,视频,mp3等等资源不要启用压缩,因为他们本身的格式就是压缩过的,已经很难压缩,而且浪费CPU,一般只是压缩文本类型的资源。

9. nginx的缓存 expires 的配置:

一般使用 expires 来设置过期时间,可以在 location 或者 if 段里面设置expires,如下所示:

location /images/ {
expires 1d;
}

单位分别可以是: expires 30s -秒,expires 30m -分钟,expires 2h -小时,expires 1d -天。

我们可以从浏览器端看出相关设置是否起作用:

nginx的配置总结

nginx的配置总结

http协议中的:304 Not Modified 表示缓存中的资源在服务端没有进行过修改,不需要进行重新传输;

Cache-Control max-age=86400 正好是1天对应的秒数,表示可以缓存一天;

Etag: 的作用是通过一个资源的签名值来判断改资源在服务端是否进行了修改;

Expires: 表示资源过期时间;

If-Modified-Since: 表示从这个时间以来,资源是否进行了修改;

If-None-Match: 表示资源的签名是否匹配;

主要通过响应头中是否有 Expires 和 Cache-Control 字段来判断服务器端的expires是否起作用

这些都是请求和响应的头部信息中的内容。

10. http 304 深入理解

浏览器客户端向服务器请求页面,服务器在向浏览器发送页面时,也会发送该页面在服务器的最后修改时间(利用响应头中的Last_Modified),而浏览器时会对访问过的页面进行缓存的,当下一次再次访问改页面时,浏览器会在HTTP请求头标签 If-Modified-Since 中把浏览器端缓存页面的最后修改时间一起发到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行比较。如果时间一致,那么返回HTTP状态码304(不返回文件内容),客户端接到之后,就直接把本地缓存文件显示到浏览器中。这就是304的含义。

所以整个过程是:

1> 响应头中的Last_Modified -->> 下次请求时请求头中的If-Modified-Since -->> 服务器进行比较 目前的最新的 修改时间 和 If-Modified-Since的大小关系。

2> 响应头中的Etag -->>下次请求时请求头中资源的签名If-None-Match -->> 到底服务器之后,会将请求头中的Etag和服务器上目前改资源的签名是否一致,如果一致,则表示该资源没有进行过修改。

所以304的出现,需要上面的两个条件同时满足。另外注意304在浏览器端禁用了缓存时是不会出现的。所以304实际上需要三个条件。

11. prox_pass 反向代理实现动静分离

    server {
listen ;
server_name z.com; gzip on;
gzip_buffers 4k;
gzip_comp_level ;
gzip_min_length ;
gzip_types text/css text/xml application/x-javascript;
access_log tomcat.log; # static resources begin
location ~ .*\.(gif|jpg|gpeg|png|bmp|swf)$ {
root html;
#proxy_pass http://192.168.1.200:8080$request_uri; #tomcat server
expires 30d; # 2h; 60s; 2d;
}
location ~ .*\.(js|css)?$ {
root html;
#proxy_pass http://192.168.1.200:8080$request_uri; #tomcat server
expires 1h;
}
# static resources end # active resources, then proxy pass to tomcat
location / {
proxy_set_header Host $host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://192.168.1.200:8080$request_uri; #tomcat server
#proxy_pass http://tomcat_server$request_uri;
}
}

上面将 图片,css,js等静态资源,是利用nginx来处理的,放在 nginx 的 html 总目录下面。而对于其它的动态资源,则发送给tomcat进行处理。

12. upstream 实现负载均衡

    upstream tomcat_server {
server 192.168.1.200: weight= fail_timeout=2s max_fails=;
server 192.168.1.200: weight= fail_timeout=2s max_fails=;
}
server {
listen ;
server_name z.com; gzip on;
gzip_buffers 4k;
gzip_comp_level ;
gzip_min_length ;
gzip_types text/css text/xml application/x-javascript;
access_log tomcat.log; # static resources begin
location ~ .*\.(gif|jpg|gpeg|png|bmp|swf)$ {
root html;
#proxy_pass http://192.168.1.200:8080$request_uri; #tomcat server
expires 30d; # 2h; 60s; 2d;
}
location ~ .*\.(js|css)?$ {
root html;
#proxy_pass http://192.168.1.200:8080$request_uri; #tomcat server
expires 1h;
}
# static resources end # active resources, then proxy pass to tomcat
location / {
proxy_set_header Host $host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
#proxy_pass http://192.168.1.200:8080$request_uri; #tomcat server
proxy_pass http://tomcat_server$request_uri;
}
}

使用 upstream 定义了一台负载均衡的虚拟服务器tomcat_server,后面由两台tomcat组成,然后通过 proxy_pass http://tomcat_server$request_uri; 向负载均衡服务器 tomcat_server 发送请求。

13. centos配置多台tomcat实例的方法

1)在 /etc/profile 文件中加入:

export JAVA_HOME=/usr/local/jdk
export JRE_HOME=/usr/local/jdk/jre CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib export TOMCAT_HOME=/usr/local/tomcat
export TOMCAT_HOME2=/usr/local/tomcat2 export CATALINA_HOME=/usr/local/tomcat
export CATALINA_HOME2=/usr/local/tomcat2 export CATALINA_BASE=/usr/local/tomcat
export CATALINA_BASE2=/usr/local/tomcat2 export CLASSPATH=$CLASSPATH:$CATALINA_HOME/lib

2)然后将 tomcat复制一份:

cp -r tomcat/ tomcat2/

3)然后进入 tomcat2 目录下的的 bin 目录,修改 其中的catalina.sh 文件,在文件最前面加入:

export CATALINA_BASE=$CATALINA_BASE2
export CATALINA_HOME=$CATALINA_HOME2

原因是 ,利用 startup.sh 启动 tomcat 时会先执行 catalina.sh,而 catalina.sh 用到了环境变量 CATALINA_BASE 和 CATALINA_HOME,所以不如果进行修改的话,即使你在 tomcat2/bin/ 目录下执行 startup.sh, 也会去启动 tomcat,而不会去启动 tomcat2.

14. nginx的配置文件中使用的一些 变量参数来自于:

nginx/conf/ 下面的文件:

[root@localhost conf]# pwd
/usr/local/nginx/conf
[root@localhost conf]# ls
fastcgi.conf fastcgi_params.default mime.types nginx.conf.backup scgi_params uwsgi_params.default
fastcgi.conf.default koi-utf mime.types.default nginx.conf.default scgi_params.default win-utf
fastcgi_params koi-win nginx.conf nginx.conf.static_active uwsgi_params
[root@localhost conf]# cat fastcgi.conf fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param HTTPS $https if_not_empty; fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
上一篇:转载:第2章 Nginx的配置 概述《深入理解Nginx》(陶辉)


下一篇:史上最全的maven pom.xml文件教程详解