Nginx配置最详细说明,配上解释

Nginx IT敢客 4个月前 (08-01) 1669次浏览 已收录 0个评论 扫描二维码
文章目录[隐藏]

       人生就是这样,我们喜欢不断的学习进化。这里我又学习到了许多关于 Nginx 的知识点,以及之前我也发过几篇 Nginx 的学习文章,从一份配置清单详解 Nginx 服务器配置Nginx 配置 404 的坑记nginx 配置 conf 大全ngnix 安装及配置详解等等,更多可以看这个Nginx 标签地址页!这里我准备对这个 Nginx 配置做一个最详细的解释了,每个字段要附上一些解释说明,让更多的初学者可以看懂这些内容。

一、安装篇

       这里我也就不详细说明了,可以参考ngnix 安装及配置详解,这个还是比较详细的。

二、配置篇(本文主要内容)

2.1 Nginx 主配置概述

       Linux 下基本上每个服务都会有它的主配置文件,该文件会定义服务应该如果去运行,使用些什么参数,启用些什么功能,相关会涉及到的一些操作文件在哪,所以主配置文件对服务是至关重要的。下面我们来分析一下 Nginx 的主配置文件。

借用一下之前一个网友做的图,这两张图很详细的说明了许多配置层级关系。Nginx 配置最详细说明,配上解释

Nginx 配置最详细说明,配上解释
         Nginx 的主配置文件默认情况下位于 /usr/local/nginx/conf/nginx.conf 以下为 Nginx 配置文件一些参数的注释。

#user nobody;  #指定使用的用户,可以用 user nginx;或者 user root 等;
worker_processes 1;  #开启的进程数,一般设置 1-5
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#定义错误日志,以及记录的日志等级

#pid logs/nginx.pid; #定义 pid 文件位置

events {
	# use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; #use epoll; #使用 epoll(linux2.6 的高性能方式)
	#Nginx 支持如下处理连接的方法(I/O 复用方法),这些方法可以通过 use 指令指定。
	#select - 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-select_module 和 –without-select_module 来启用或禁用这个模块。
	#poll - 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数–with-poll_module 和 –without-poll_module 来启用或禁用这个模块。
	#kqueue - 高效的方法,使用于 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使用双处理器的 MacOS X 系统使用 kqueue 可能会造成内核崩溃。
	#epoll - 高效的方法,使用于 Linux 内核 2.6 版本及以后的系统。在某些发行版本中,如 SuSE 8.2,有让 2.4 版本的内核支持 epoll 的补丁。
	#rtsig - 可执行的实时信号,使用于 Linux 内核版本 2.2.19 以后的系统。可是从 Linux 内核版本 2.6.6-mm2 开始,这个参数就不再使用了.
	#/dev/poll - 高效的方法,使用于 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+.
	#eventport - 高效的方法,使用于 Solaris 10. 为了防止出现内核崩溃的问题, 有必要安装 这个 安全补丁。
	worker_connections 1024; #worker_connections 51200; #每个进程最大连接数(最大连接=连接数 x 进程数)
}
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;
	#打开 gzip 压缩
	#fastcgi_connect_timeout 300;
	#fastcgi_send_timeout 300;
	#fastcgi_read_timeout 300;
	#fastcgi_buffer_size 128k;
	#fastcgi_buffers 4 256k;
	#fastcgi_busy_buffers_size 256k;
	#fastcgi_temp_file_write_size 256k;
	#fastcgi_temp_path /dev/shm;
	#fastcgi 连接超时时间和缓存
	#keepalive_timeout  0;
    keepalive_requests 64;
    keepalive_timeout  30s 30s;
    client_body_buffer_size 64k;
    client_max_body_size 20m;
	
	# 配置轮询服务 fuwu1
    upstream fuwu1 {
        server    127.0.0.1:8089;
        keepalive 16;
    }
	# 配置轮询服务 fuwu2
    upstream fuwu2 {
        server    172.16.0.149:8088;
        server    172.16.0.149:8089;
        server    172.16.0.150:8088;
        server    172.16.0.150:8089;
        keepalive 16;
    }
	# 配置轮询服务 fuwu3
    upstream fuwu2 {
        server 172.16.0.179:8900;
        server 172.16.0.180:8900;
    } 
	
	# server 块
	server {
		listen 80;
		server_name localhost; #主机名 www.aaa.com 等等,多个用空格隔开比如 server_name www.aaa.com www.bbb.com;
		#charset koi8-r;#默认字符编码 charset gb2312
		#access_log logs/host.access.log main;
		location / {
			#pass 路径匹配 能够匹配路径中带“/”的 不过需要注意的是如果之后也有相关“/”匹配项并且使用比此处更精确匹配符,则以之后表达式优先
			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;
		}
		#
		#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 的地址端口
			# 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;
			#不允许访问以.ht 开头的文件
		#}
	}
	
	# 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;
		# server_name localhost;
		# ssl on;
		# ssl_certificate cert.pem;
		# ssl_certificate_key cert.key;
		# ssl_session_timeout 5m;
		# ssl_protocols SSLv2 SSLv3 TLSv1;
		# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
		# ssl_prefer_server_ciphers on;
		
		#以上为 ssl 配置
		# location / {
			# root html;
			# index index.html index.htm;
		# }
	#}
	
	include /root/nginx/modules/*.conf;  # 加载其他模块内容
	include ./vhost/*.conf;  # 加载其他自定义的 server 块内容
}

2.2 Nginx 下的虚拟主机配置

       利用虚拟主机技术,可以把一台真正的主机分成许多 ” 虚拟 ” 的主机,每一台虚拟主机都具有独立的域名和 IP 地址,具有完整的 Internet 服务器( www, FTP,email )功能。 虚拟主机之间完全独立,在外界看来,每一台虚拟主机和一台独立的主机完全一样。效果一样但费用却大不一样了。由于多台 虚拟主机 共享一台真实主机的资源,每个 虚拟主机用户承受的硬件费用、网络维护费用、通信线路的费用均大幅度降低, Internet 真正成为人人用得起的网络 !
       虚拟主机共分为三种:基于IP的虚拟主机,基于端口的虚拟主机和基于名称的虚拟主机。前两种由于受到成本和客户使用习惯的限制,相对使用的没有基于名称的虚拟主机多,以下我们介绍一下三种虚拟主机的配置。

2.2.1 Nginx 基于名称的虚拟主机配置:

       上述配置中, 定义了三个虚拟主机。前两个 server , 通过域名“ http://www.example.com” 和 “ http://www.test.com” 可以分别访问正确的网站。如果浏览器直接通过 IP 地址或者其他指向这台机器的域名访问, 那么访问到的是第三个 server 配置。第三个

server {
	listen 80;
	server_name www.example.com;
	...
}
server {
	listen 80;
	server_name www.test.com;
	...
}
server {
	listen 80 default;
	...
}

server 为一个默认配置, 请注意它没有“ server_name” 指令, 并且“ listen” 指令包含一个“ default” 关键字。

2.2.2 Nginx 基于 IP 的虚拟主机

[root@server nginx]# vi /usr/local/nginx/conf/nginx.conf
server {
	listen 10.0.0.88:80;
	root 88.com;
	index index.html;
}
server {
	listen 10.0.0.87:80;
	root 87.com;
	index index.html;
}
[root@server nginx]# ifconfig eth0:0 10.0.0.88
[root@server nginx]# ifconfig eth0:1 10.0.0.87
[root@server nginx]# mkdir /usr/local/nginx/88.com
[root@server nginx]# echo 'I am your father' > /usr/local/nginx/88.com/index.html
[root@server nginx]# mkdir /usr/local/nginx/87.com
[root@server nginx]# echo 'this is 87.com' > /usr/local/nginx/87.com/index.html

       以上配置了两台虚拟主机,一台 IP 为 10.0.0.88 ,另一台为 10.0.0.87 。它们都监听 80 端口。根据访问的 IP 地址不同,返回不同网站内容。

2.2.3 Nginx 基于端口的虚拟主机

[root@server nginx]# vi /usr/local/nginx/conf/nginx.conf
server {
	listen 80;
	root 80.com;
}
server {
	listen 8080;
	root 8080.com;
}
[root@server nginx]# mkdir /usr/local/nginx/80.com
[root@server nginx]# mkdir /usr/local/nginx/8080.com
[root@server nginx]# echo 'this is 80.com' > /usr/local/nginx/80.com/index.html
[root@server nginx]# echo 'this is 8080.com' > /usr/local/nginx/8080.com/index.html

       以上配置了两台虚拟主机,一台使用相同 IP 。一台使用 80 端口,另一台使用 8080 端口。访问 8080 端口时需要在 URL 后加上 :8080 。

2.3 安全的连接 https

       众所周知,我们在互联网上冲浪,一般都是使用的 http 协议(超文本传输协议),默认情况下数据是明文传送的,这些数据在传输过程中都可能会被捕获和窃听,因此是不安全的。 https 可以说是 http 协议的安全版,就是为了满足对安全性要求比较高的用户而设计的。
       如果您的邮件中有敏感数据,不希望被人窃听;如果您不希望被钓鱼网站盗用帐号信息,如果您希望您在使用邮箱的过程中更安全,那么我们推荐您使用 https 安全连接。

       以下是阿里云针对 nginx 配置 ssl 证书的配置,

server {
    listen 443;
    server_name localhost;
    ssl on;
    root html;
    index index.html index.htm;
    ssl_certificate   cert/1534270813767.pem;  #证书路径
    ssl_certificate_key  cert/1534270813767.key;  #证书路径
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    location / {
        root html;
        index index.html index.htm;
    }
}

2.4 Nginx 日志管理

       做为一个优秀的管理员,应该能够对你所维护的服务器了如指掌,那么日志的阅读就是必不可少的,我们可以通过日志,了解到你的服务器是否正常运行,有谁在访问你的服务器,每天的访问量是多少,有没有非法的不受欢迎的访问等等。
       在 Nginx 主配置中有关 Nginx 日志的相关参数主要有两条。

log_format 指定日志格式

access_log 指定日志存放路径
       对于一个日均 PV 数十万以上的网站来说,日志的增长将会很迅速,一天的日志几个G属于正常情况。所以为了我们单个日志文件不至于太大,我们需要定期的去截断我们的日志。
       不可很可惜, Nginx 默认并不支持我们所熟悉的 cronolog 方式来对每天的日志进行截断,那么我们可以通过以下方法来解决。

[root@example ~]# mv /usr/local/nginx/logs/access.log /usr/local/nginx/logs/access.log1
[root@example ~]# touch /usr/local/nginx/logs/access.log
[root@example ~]# kill -HUP `cat /usr/local/nginx/logs/nginx.pid`

       然后以 crond 的方式或者 logrotate 的方式运行。
       对于习惯使用 cronolog 来做日志分割的管理员来说,无法使用 cronolog 总会成为他心里挥之不去的痛。然而有时候事情总会很奇妙,只要你想去解决,就一定有办法解决。我在这里介绍一种通过管道符文件另僻溪径的方法使用 cronolog 。
       首先下载并编译安装我们 cronolog

[root@example ~]# tar xf cronolog-1.6.2.tar.gz
[root@example ~]# ./configure
[root@example ~]# make && make install
[root@example ~]# service nginx stop
[root@example ~]# mv /usr/local/nginx/logs/access.log
/usr/local/nginx/logs/access.log.bak
[root@example ~]# mkfifo /usr/local/nginx/logs/access.log
[root@example ~]# cronolog /usr/local/nginx/logs/access.log.%Y%m%d <
/usr/local/nginx/logs/access.log &
[root@example ~]# service nginx start

        访问一下自己的主机,然后查看 /usr/local/nginx/logs/ 目录下是否多出个 access.log.%Y%m%d 文件,查看一下这个文件里的内容是否是我们的访问日志。
       这里需要注意的是必需在 Nginx 启动之前执行 cronolog 命令,否则 Nginx 将无法正常启动。
       对于一些你不需要记录的日志内容,我们可以使用以下方式关闭对这些文件的日志记录。

location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)${
	access_log off;
}

2.5 访问控制

       有时我们会有这么一种需求,就是你的网站并不想提供一个公共的访问或者某些页面不希望公开,我们希望的是某些特定的客户端可以访问。那么我们可以在访问时要求进行身份认证,就如给你自己的家门加一把锁,以拒绝那些不速之客。我们在服务课程中学习过 apache 的访问控制,对于 Nginx 来说同样可以实现,并且整个过程和 Apache 非常的相似。

location / {
	root html;
	index index.html index.htm;
	auth_basic "xxxx";
	auth_basic_user_file /usr/local/nginx/passwd.db;
}

       设置密码

[root@example nginx]# htpasswd -c /usr/local/nginx/passwd.db mark
New password: (输入密码)
Re-type new password: (again)
Adding password for user mark

然后访问一下页面测试一下。
另外如果你想阻止别人访问你某些目录下的特定文件,比如我网站主目录下有个 test 目录,我不想让别人访问我 test 目录下的” .txt” 和” .doc” 的文件,那么我们可以通过 deny 的方式来做拒绝。

location ~* \.(txt|doc)$ {
	root html/test;
	deny all;
}

此处 ~* 代表不区分大小写方式匹配。

2.6 Rewrite 规则

2.6.1 什么是 Rewrite

       Rewrite 对称 URL Rewrite ,即 URL 重写,就是把传入 Web 的请求重定向到其他 URL 的过程。 URL Rewrite 最常见的应用是 URL 伪静态化,是将动态页面显示为静态页面方式的一种技术。比如 http://www.123.com/news/index.asp?id=123 使用 URLRewrite 转换后可以显示为 http://www.123.com/news/123.html
       对于追求完美主义的网站设计师,就算是网页的地址也希望看起来尽量简洁明快。形如 http://www.123.com/news/index.asp?id=123 的网页地址,自然是毫无美感可言,而用 UrlRewrite 技术,你可以轻松把它显示为 http://www.123.com/news/123.html
       理论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页面的评分一般要高于动态页面。所以, UrlRewrite 可以让我们网站的网页更容易被搜索引擎所收录。
       从安全角度上讲,如果在 url 中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客利用,对你的系统造成一定的破坏,所以静态化的 url 地址可以给我们带来更高的安全性。

2.6.2 Rewrite 相关指令

Nginx Rewrite 相关指令有 if 、 rewrite 、 set 、 return 等。

if (condition) { … }

if 可以支持如下条件判断匹配符号

~ 为区分大小写匹配
~* 为不区分大小写匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配
-f 和!-f 用来判断是否存在文件
-d 和!-d 用来判断是否存在目录
-e 和!-e 用来判断是否存在文件或目录
-x 和!-x 用来判断文件是否可执行

在匹配过程中可以引用一些 Nginx 的全局变量,更多的变量请参考 http://wiki.nginx.org/NginxHttpCoreModule 的 Variables 部分

$args, 请求中的参数;
$document_root, 针对当前请求的根路径设置值;
$host, 请求信息中的"Host",如果请求中没有 Host 行,则等于设置的服务器名;
$limit_rate, 对连接速率的限制;
$request_method, 请求的方法,比如"GET"、"POST"等;
$remote_addr, 客户端地址;
$remote_port, 客户端端口号;
$remote_user, 客户端用户名,认证用;
$request_filename, 当前请求的文件路径名
$query_string, 与$args 相同;
$scheme, 所用的协议,比如 http 或者是 https
$server_protocol, 请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr, 服务器地址,如果没有用 listen 指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name, 请求到达的服务器名;
$document_uri 与$uri 一样,URI 地址;
$server_port, 请求到达的服务器端口号;

       看了一大堆也许会有点晕,当然有时晕着晕着也就习惯了。不过我们还是先来看两个例子。这样更有助于理解。
例 1 匹配访问的 url 地址是否是个目录

if (-d $request_filename) {
	…;
}

例 2 匹配访问的地址是否以 www 开头

if ($hosts ~* ^www) {
	…;
}

rewrite 指令根据表达式来重定向 URI ,或者修改字符串。可以应用于 server,location, if 环境下 每行 rewrite 指令最后应该根一个 flag 标记,支持的 flag 标记有

last 相当于 Apache 里的[L]标记,表示完成 rewrite
break 本条规则匹配完成后,终止匹配,不再匹配后面的规则
redirect 返回 302 临时重定向,浏览器地址会显示跳转后的 URL 地址
permanent 返回 301 永久重定向,浏览器地址会显示跳转后 URL 地址

last 和 break 标记的区别在于, last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求,而 break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配。另有些时候必须使用 last ,比如在使用 alias 指令时,而使用 proxy_pass 指令时则必须使用 break 。
例 3 :以下这段 rewrite 会导致死循环

location /abc/ {
	rewrite “^/abc/(.*)\.html$” /abc/index.html last;
}

我们应该将上面的 last 改成 break 以避免死循环。
redirect 和 permanent 区别则是返回的不同方式的重定向,对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说 301 的重定向更加友好,如果我们把一个地址采用 301 跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。
使用 302 重定向时,搜索引擎 ( 特别是 google) 有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的 URL 更好的话,也许地址栏不会更改,那么很有可能出现 URL 劫持的现像。
我们在做 URI 重写时,有时会发现 URI 中含有相关参数,如果需要将这些参数保存下来,并且在重写过程中重新引用,我们可以用到 () 和 $N 的方式来解决。

例 4 :匹配访问的 url 地址是否是个目录,如果是则自动加个 /

if (-d $request_filename) {
	rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}

例 5 :用户访问的网址为 http://www.test.com/php/abc.html 重写后真实地址是 www.test.com/php/login.php?user=abc

location ~* /php/.*\.html$ {
	rewrite /php/(.*)\.html /login.php?user=$1 last;
}

例 6 :用户访问地址为 /uplook/11-22-33.html 重写后真实地址为/uplook/11/22/33.html

location /uplook/ {
	rewrite /uplook/([0-9]+)-([0-9]+)-([0-9]+).html /uplook/$1/$2/$3.html last;
}

set 指令是用于定义一个变量,并且赋值。应用于 server,location,if 环境。

语法格式为: set $变量名 变量值

例 7 :当访问任意目录下的 whoami.html 都重定向到 /who.html

location ~* .*/whoami\.html$ {
	set $who 'who.html';
	rewrite .*  /$who break;
}

return 指令用于返回状态码给客户端,应用于 server , location , if 环境。
例 8 :如果访问的  .sh  结尾的文件则返回 403 操作拒绝错误

location ~* .*\.sh$ {
	return 403;
}

2.7 Nginx 反向代理

2.7.1 反向代理及其特点

       反向代理( Reverse Proxy )方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的 客户端,此时代理服务器对外就表现为一个服务器。
       反向代理又称为 Web 服务器加速,是针对 Web 服务器提供加速功能的。它作为代理 Cache ,但并不针对浏览器用户,而针对一台或多台特定 Web 服务器(这也是反向代理名称的由来)。代理服务器可以缓存一些 web 的页面,降低了 web 服务器的访问量,所以可以降低 web 服务器的负载。 web 服务器同时处理的请求数少了,响应时间自然就快了。同时代理服务器也存了一些页面,可以直接返回给客户端,加速客户端浏览。实施反向代理,只要将反向代理设备放置在一台或多台 Web 服务器前端即可。当互联网用户访问某个 WEB 服务器时,通过 DNS 服务器解析后的 IP 地址是代理服务器的 IP 地址 , 而非原始 Web 服务器的 IP 地址 , 这时代理服务器设备充当 Web 服务器,浏览器可以与它连接,无需再直接与 Web 服务器相连。因此,大量 Web 服务工作量被转载到反向代理服务上。不但能够很大程度上减轻 web 服务器的负担,提高访问速度,而且能够防止外部网主机直接和 web 服务器直接通信带来的安全隐患。

2.7.2 Nginx 反向代理

Nginx proxy 是 Nginx 的王牌功能,利用 proxy 基本可以实现一个完整的 7 层负载均衡,它有这 些特色:
1.  功能强大,性能卓越,运行稳定。
2. 配置简单灵活。
3. 能够自动剔除工作不正常的后端服务器。
4. 上传文件使用异步模式。
5. 支持多种分配策略,可以分配权重,分配方式灵活。
在 nginx 的反向代理优点介绍中,提到了异步传输模式 下面就来讲解下传统的代理( apache/squid )的同步传输和 nginx 的异步传输的差异。
看图:

Nginx 配置最详细说明,配上解释
   squid 同步传输:浏览器发起请求,而后请求会立刻被转到后台,于是在浏览器和后台之间就建立了一个通道。在请求发起直到请求完成,这条通道都是一直存 在的。
   nginx 异步传输:浏览器发起请求,请求不会立刻转到后台,而是将请求数据( header )先收到 nginx 上,然后 nginx 再把这个请求发到后端, 后端处理完之后把数据返回到 nginx 上, nginx 将数据流发到浏览器,这点和 lighttpd 有点不同, lighttpd 是将后端数据完全接收后才发 送到浏览器。
  那么这到底有什么好处呢?
   1) 假设用户执行一个上传文件操作,因为用户网速又比较慢,因此需要花半个小时才能把文件传到服务器。 squid 的同步代理在用户开始上传后就和后台建立了连 接,半小时后文件上传结束,由此可见,后台服务器连接保持了半个小时;而 nginx 异步代理就是先将此文件收到 nginx 上,因此仅仅是 nginx 和用户 保持了半小时连接,后台服务器在这半小时内没有为这个请求开启连接,半小时后用户上传结束, nginx 才将上传内容发到后台,nginx 和后台之间的带宽 是很充裕的,所以只花了一秒钟就将请求发送到了后台,由此可见,后台服务器连接保持了一秒。同步传输花了后台服务器半个小时,异步传输只花一秒,可见优化 程度很大。
   2) 在上面这个例子中,假如后台服务器因为种种原因重启了,上传文件就自然中断了,这对用户来说是非常恼火的一件事情,想必各位也有上传文件传到一半被中断的 经历。用 nginx 代理之后,后台服务器的重启对用户上传的影响减少到了极点,而 nginx 是非常稳定的并不需要常去重启它,即使需要重启,利用 kill -HUP 就可以做到不间断重启 nginx 。
   3) 异步传输可以令负载均衡器更有保障,为什么这么说呢?在其它的均衡器( lvs/haproxy/apache 等)里,每个请求都是只有一次机会的,假如用 户发起一个请求,结果该请求分到的后台服务器刚好挂掉了,那么这个请求就失败了;而 nginx 因为是异步的,所以这个请求可以重新发往下一个后台,下一个 后台返回了正常的数据,于是这个请求就能成功了。还是用用户上传文件这个例子,假如不但用了 nginx 代理,而且用了负载均衡,nginx 把上传文件发往 其中一台后台,但这台服务器突然重启了, nginx 收到错误后,会将这个上传文件发到另一台后台,于是用户就不用再花半小时上传一遍。
   4) 假如用户上传一个 10GB 大小的文件,而后台服务器没有考虑到这个情况,那么后台服务器岂不要崩溃了。用 nginx 就可以把这些东西都拦在 nginx 上, 通过 nginx 的上传文件大小限制功能来限制,另外 nginx 性能非常有保障,就放心的让互联网上那些另类的用户和 nginx 对抗去吧。

2.7.3 Nginx 反向代理配置

修改 Nginx 主配置文件,在 http 全局配置部分加入如下内容:

http {
	… …
	client_max_body_size 300m;
	#允许客户端请求的最大单个文件字节数,它出现在请求头部的 Content-Length 字段。 (可以更改此参数达到限制用户上传文件大小的目的)
	client_body_buffer_size 128k;
	#这个指令可以指定连接请求使用的缓冲区大小,默认值:8k/16k 。如果客户端请求一个文件大于 128k,则 Nginx 会尝试在硬盘上创建临时文件。如果硬盘满了,则会报错。
	client_body_temp_path /dev/shm/client_body_temp;
	#这个指令指定连接请求试图写入缓存文件的目录路径。
	proxy_connect_timeout 600;
	#跟后端服务器连接的超时时间,发起握手等候响应超时时间
	proxy_read_timeout 600;
	#默认值:proxy_read_timeout 60。决定读取后端服务器应答的超时时间,它决定 nginx 将等待多久时间来取得一个请求的应答。超时时间是指完成了两次握手后并且状态为 established 的超时时间,而不是所有的应答时间。 相对于 proxy_connect_timeout,这个时间可以扑捉到一台将你的连接放入连接池延迟处理并且没有数据传送的服务器,注意不要将此值设置太低,某些情况下代理服务器将花很长的时间来获得页面应答 。如果被代理服务器在设置的时间内没有传递数据,nginx 将关闭连接。
	proxy_send_timeout 600;
	#设置代理服务器转发请求的超时时间,同样指完成两次握手后的时间,如果超过这个时间代理服务器没有数据转发到后端服务器,nginx 将关闭连接。
	proxy_buffer_size 16k;
	#默认值:proxy_buffer_size 4k/8k 。设置从后端服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头。
	proxy_buffers 4 32k;
	#设置用于读取应答(来自后端服务器)的缓冲区数目和大小,告诉 Nginx 保存单个用的几个 Buffer,最大用多大空间
	proxy_busy_buffers_size 64k;
	#如果系统很忙的时候可以申请更大的 proxy_buffers,官方推荐*2
	proxy_temp_file_write_size 64k;
	#设置在写入 proxy_temp_path 时缓存临文件数据的大小,在预防一个工作进程在传递文件时阻塞太长。
	proxy_temp_path /dev/shm/proxy_temp;
	#类似于 http 核心模块中的 client_body_temp_path 指令,指定一个目录来缓冲比较大的被代理请求。
	upstream server_pool  {
		server 192.168.0.88:80 weight=4 max_fails=2 fail_timeout=30s;
		server 192.168.0.89:80 weight=2 max_fails=2 fail_timeout=30s;
	}
	#HTTP 负载均衡模块。upstream 这个字段设置一群服务器,可以将这个字段放在 proxy_pass 和 fastcgi_pass 指令中作为一个单独的实体,它们可以是监听不同端口的服务器,并且也可以是同时监听 TCP 和 Unix socket 的服务器。 服务器可以指定不同的权重,默认为 1。
	… …
}

修改 Nginx 主配置文件,在 server 中 location / 配置部分做如下修改:

server {
	… …
	location / {
		proxy_pass http://server_pool/;
		#确定需要代理的 URL,端口或 socket。
		proxy_redirect off;
		#如果需要修改从后端服务器传来的应答头中的"Location"和"Refresh"字段,可以用这个指令设置。
		proxy_set_header X-Real-IP $remote_addr;
		#这个指令允许将发送到后端服务器的请求头重新定义或者增加一些字段。 这个值可以是一个文本,变量或者它们的组合。
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Host $host;
		proxy_next_upstream error timeout invalid_header http_500 http_502 http_503
		http_504 http_404;
		#确定在何种情况下请求将转发到下一个服务器:
		#error - 在连接到一个服务器,发送一个请求,或者读取应答时发生错误。
		#timeout - 在连接到服务器,转发请求或者读取应答时发生超时。
		#invalid_header - 服务器返回空的或者错误的应答。
		#http_500 - 服务器返回 500 代码。
		#http_502 - 服务器返回 502 代码。
		#http_503 - 服务器返回 503 代码。
		#http_504 - 服务器返回 504 代码。
		#http_404 - 服务器返回 404 代码。
		#off - 禁止转发请求到下一台服务器。
	}
	… …
}

Nginx 的 upstream 目前支持 5 种方式的分配
1  轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
2   weight
指定轮询几率, weight 和访问比率成正比,用于后端服务器性能不均的情况。
例如:

upstream bakend {
	server 192.168.0.88 weight=10;
	server 192.168.0.89 weight=10;
}

3   ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
例如:

upstream bakend {
	ip_hash;
	server 192.168.0.88:80;
	server 192.168.0.89:80;
}

4   fair (第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
例如:

upstream bakend {
	server 192.168.0.88:80;
	server 192.168.0.89:80;
	fair;
}

5   url_hash (第三方)

按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,后端服务
器为缓存时比较有效。
例如:

upstream backend {
	server 192.168.0.88:3128;
	server 192.168.0.89:3128;
	hash $request_uri;
	hash_method crc32;
}

每个设备的状态设置为 :
1. down 表示单前的 server 暂时不参与负载
2. weight 默认为 1.weight 越大,负载的权重就越大。
3. max_fails :允许请求失败的次数默认为 1. 当超过最大次数时,返回 proxy_next_upstream 模块定义的错误
4. fail_timeout:max_fails 次失败后,暂停的时间。
5. backup : 其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。所以这台机器压力会最轻。
Nginx 支持同时设置多组的负载均衡,用来给不用的 server 来使用。

 


IT 敢客 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Nginx 配置最详细说明,配上解释
喜欢 (4)
[313176056@qq.com]
分享 (0)
IT敢客
关于作者:
“我所做的一切都是为了方便我的生活~~~“
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址