前言
本文是runoob教程的搬运,稍微修改了原文中的一些错误拼写的问题,顺便对一些概念进行了更详细的解释,欢迎批评指正!
Nginx常用功能
-
Http代理,反向代理:作为web服务器最常用的功能之一,尤其是反向代理。
这里我给来2张图,对正向代理与反向代理做个诠释,具体细节,大家可以翻阅下资料。
Nginx在做反向代理时,提供性能稳定,并且能够提供配置灵活的转发功能。Nginx可以根据不同的正则匹配,采取不同的转发策略,比如图片文件结尾的走文件服务器,动态页面走web服务器,只要你正则写的没问题,又有相对应的服务器解决方案,你就可以随心所欲的玩。并且Nginx对返回结果进行错误页跳转,异常判断等。如果被分发的服务器存在异常,他可以将请求重新转发给另外一台服务器,然后自动去除异常服务器。
-
负载均衡
Nginx提供的负载均衡策略有2种:内置策略和扩展策略。内置策略为轮询,加权轮询,Ip hash。扩展策略,就天马行空,只有你想不到的没有他做不到的啦,你可以参照所有的负载均衡算法,给他一一找出来做下实现。
上3个图,理解这三种负载均衡算法的实现
Ip hash算法,对客户端请求的ip进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题。
-
Nginx配置文件结构
如果你下载好啦,你的安装文件,不妨打开conf文件夹的nginx.conf文件,Nginx服务器的基础配置,默认的配置也存放在此。
在 nginx.conf 的注释符号为: #
nginx 文件结构:
... #全局块events { #events块... }http #http块 {... #http全局块server #server块{ ... #server全局块location [PATTERN] #location块{...}location [PATTERN] {...}}server{...}... #http全局块 }
- 全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
- events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
- http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
- server块:配置虚拟主机的相关参数,一个http中可以有多个server。
- location块:配置请求的路由,以及各种页面的处理情况。
下面给大家上一个配置文件,作为理解。
########### 每个指令必须有分号结束。################# #user administrator administrators; #配置用户或者组,默认为nobody nobody。 #worker_processes 2; #允许生成的进程数,默认为1 #pid /nginx/pid/nginx.pid; #指定nginx进程运行文件存放地址 error_log log/error.log debug; #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg events {accept_mutex on; #设置网路连接序列化,防止惊群现象发生,默认为onmulti_accept on; #设置一个进程是否同时接受多个网络连接,默认为off#use epoll; #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventportworker_connections 1024; #最大连接数,默认为512 } http {include mime.types; #文件扩展名与文件类型映射表default_type application/octet-stream; #默认文件类型,默认为text/plain#access_log off; #取消服务日志 log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式access_log log/access.log myFormat; #combined为日志格式的默认值sendfile on; #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。sendfile_max_chunk 100k; #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。keepalive_timeout 65; #连接超时时间,默认为75s,可以在http,server,location块。upstream mysvr { server 127.0.0.1:7878;server 192.168.10.121:3333 backup; #热备}error_page 404 https://www.baidu.com; #错误页server {keepalive_requests 120; #单连接请求上限次数。listen 4545; #监听端口server_name 127.0.0.1; #监听地址 location ~*^.+$ { #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。#root path; #根目录#index vv.txt; #设置默认页proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表deny 127.0.0.1; #拒绝的ipallow 172.18.5.54; #允许的ip } } }
上面是nginx的基本配置,需要注意的有以下几点:
-
几个常见配置项:
-
$remote_addr 与 $http_x_forwarded_for 用以记录客户端的ip地址;
-
$remote_user :用来记录客户端用户名称;
-
$time_local : 用来记录访问时间与时区;
-
$request : 用来记录请求的url与http协议;
-
$status : 用来记录请求状态;成功是200;
-
$body_bytes_s ent :记录发送给客户端文件主体内容大小;
-
$http_referer :用来记录从那个页面链接访问过来的;
-
$http_user_agent :记录客户端浏览器的相关信息;
-
-
惊群现象:一个网路连接到来,多个睡眠的进程被同时叫醒,但只有一个进程能获得链接,这样会影响系统性能。
-
每个指令必须有分号结束。
Nginx 反向代理与负载均衡详解
- 设置 404 页面导向地址
error_page 404 https://www.runnob.com; #错误页
proxy_intercept_errors on; #如果被代理服务器返回的状态码为400或者大于400,设置的error_page配置起作用。默认为off。
- 如果我们的代理只允许接受get,post请求方法的一种
proxy_method get; #支持客户端的请求方法。post/get;
- 设置支持的http协议版本
proxy_http_version 1.0 ; #Nginx服务器提供代理服务的http协议版本1.0,1.1,默认设置为1.0版本
-
如果你的nginx服务器给2台web服务器做代理,负载均衡算法采用轮询,那么当你的一台机器web程序iis关闭,也就是说web不能访问,那么nginx服务器分发请求还是会给这台不能访问的web服务器,如果这里的响应连接时间过长,就会导致客户端的页面一直在等待响应,对用户来说体验就打打折扣,这里我们怎么避免这样的情况发生呢。这里我配张图来说明下问题。
如果负载均衡中其中web2发生这样的情况,nginx首先会去web1请求,但是nginx在配置不当的情况下会继续分发请求道web2,然后等待web2响应,直到我们的响应时间超时,才会把请求重新分发给web1,这里的响应时间如果过长,用户等待的时间就会越长。
下面的配置是解决方案之一。
proxy_connect_timeout 1; #nginx服务器与被代理的服务器建立连接的超时时间,默认60秒 proxy_read_timeout 1; #nginx服务器向被代理服务器组发出read请求后,等待响应的超时间,默认为60秒。 proxy_send_timeout 1; #nginx服务器向被代理服务器组发出write请求后,等待响应的超时间,默认为60秒。 proxy_ignore_client_abort on; #客户端断网时,nginx服务器是否中断对被代理服务器的请求。默认为off。
下面是对每个配置项的具体解释:
proxy_connect_timeout 1;
这个指令设置了Nginx与被代理服务器建立连接的超时时间,单位是秒。在你的例子中设置为1秒。这意味着如果Nginx在1秒内未能成功与后端服务器建立连接,它就会放弃尝试,并可能返回一个错误给客户端。默认值通常是60秒,所以这个设置显著缩短了等待时间,适合于对响应速度要求较高的场景。
proxy_read_timeout 1;
此指令定义了Nginx等待从后端服务器读取响应的超时时间,单位也是秒。在这个例子中设置为1秒。这表示一旦Nginx发送请求到后端服务器后,它会等待最多1秒钟来接收响应。如果在这段时间内没有收到任何数据,连接将被关闭。通常情况下,默认值是60秒,这样低的设置可能会导致一些正常的但响应较慢的操作失败。
proxy_send_timeout 1;
它指定了Nginx向后端服务器发送请求的超时时间,同样以秒为单位。这里设置为1秒。这个超时是在已经建立了连接之后,Nginx尝试发送请求到后端服务器的时间限制。如果在这个时间内无法完成请求的发送,连接将会被关闭。默认值同样是60秒。
proxy_ignore_client_abort on;
当设置为on时,即使客户端中断了请求(例如断网或主动取消),Nginx也会继续尝试完成对后端服务器的请求,而不是立即终止它。这对于某些需要确保操作完整性的应用场景非常有用。默认情况下,这个选项是off,即如果客户端中断请求,Nginx也会尝试中断对后端服务器的请求。
综上所述,这些配置主要用于优化Nginx作为反向代理时的性能和可靠性,特别是当你希望快速响应用户请求或处理高并发量的情况下。不过需要注意的是,过于严格的超时设置(如这里的1秒)可能会导致正常请求因为短暂延迟而失败,因此应该根据实际情况调整这些参数。
-
proxy_next_upstream指令,这个指令是Nginx中用于定义在遇到特定错误或异常情况时,如何将请求转发给upstream组中的下一个服务器的重要配置。这个指令允许你指定在哪些情况下尝试下一个服务器,从而提高系统的可靠性和容错能力。
- proxy_next_upstream指令详解
- timeout:当与后端服务器建立连接、发送请求或读取响应时发生超时时,Nginx会尝试将请求传递给upstream组中的下一个服务器。这对应于你在问题中提到的几种超时情况(如proxy_connect_timeout、proxy_read_timeout等)。
- error:在建立连接、发送请求到被代理服务器或读取响应信息时如果发生错误(例如网络错误),Nginx会尝试将请求转发给下一个服务器。
- invalid_header:如果从被代理服务器收到的响应头无效或无法解析,Nginx会尝试将请求转发给下一个服务器。
- http_500 | http_502 | http_503 | http_504:这些选项分别对应于被代理服务器返回的HTTP状态码500(内部服务器错误)、502(错误网关)、503(服务不可用)和504(网关超时)。如果后端服务器返回了这些状态码之一,Nginx会尝试将请求转发给upstream组中的下一个服务器。
- http_404:虽然不太常见于proxy_next_upstream中使用,但如果指定了,当后端服务器返回404(未找到)状态码时,Nginx也会尝试将请求转发给下一个服务器。
- off:这个值不是一种错误条件,而是表示禁用此功能。如果设置为off,那么无论发生什么类型的错误,Nginx都不会尝试转发请求到下一个服务器。
- proxy_next_upstream指令详解
-
如果你想通过http获取客户的真实ip而不是获取代理服务器的ip地址,那么要做如下的设置。
proxy_set_header Host $host; #只要用户在浏览器中访问的域名绑定了 VIP VIP 下面有RS;则就用$host ;host是访问URL中的域名和端口 www.taobao.com:80 proxy_set_header X-Real-IP $remote_addr; #把源IP 【$remote_addr,建立HTTP连接header里面的信息】赋值给X-Real-IP;这样在代码中 $X-Real-IP来获取 源IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#在nginx 作为代理服务器时,设置的IP列表,会把经过的机器ip,代理机器ip都记录下来,用 【,】隔开;代码中用 echo $x-forwarded-for |awk -F, '{print $1}' 来作为源IP
这些指令用于配置Nginx作为反向代理时如何设置HTTP请求头,以便将客户端的真实信息传递给后端服务器。以下是对每个指令的详细解释:
-
proxy_set_header Host $host;
- 作用:这个指令设置了HTTP请求头中的Host字段。
- 解释:
- $host变量包含的是用户在浏览器中访问的域名和端口(如果没有指定端口,则使用默认端口,如HTTP为80,HTTPS为443)。
- 当Nginx作为反向代理时,它会将原始请求中的Host头部信息传递给后端服务器。这样,后端服务器可以看到客户端实际请求的域名,而不是代理服务器的地址。
- 例如,如果用户访问http://www.taobao.com:80,那么$host的值就是www.taobao.com。
-
proxy_set_header X-Real-IP $remote_addr;
-
作用:这个指令设置了自定义的HTTP请求头X-Real-IP。
-
解释:
-
$remote_addr变量表示客户端的IP地址,即发起请求的实际用户的IP地址。
-
这个指令将客户端的真实IP地址通过X-Real-IP头部传递给后端服务器。这样,即使请求经过了Nginx代理,后端服务器仍然可以获取到客户端的真实IP地址。后端应用代码中,可以通过读取X-Real-IP头部来获取客户端的真实IP地址。例如,在PHP中可以使用$_SERVER['HTTP_X_REAL_IP']
-
-
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-
作用:这个指令设置了标准的HTTP请求头X-Forwarded-For。
-
解释:
-
$proxy_add_x_forwarded_for变量是一个特殊的变量,它会在现有的X-Forwarded-For头部基础上添加当前客户端的IP地址(即$remote_addr),并用逗号分隔。
-
如果请求中已经存在X-Forwarded-For头部(通常是由于之前经过其他代理服务器),则新值会追加到现有值之后。否则,它会简单地设置为客户端的IP地址。
-
这样做的目的是记录请求经过的所有代理服务器的IP地址以及客户端的真实IP地址。这对于需要追踪请求路径的应用非常有用。
-
-
-
Nginx 负载均衡详解
在文章Nginx 配置详解中我说啦nginx有哪些中负载均衡算法。这一结我就给如何操作配置的给大家做详细说明下。
首先给大家说下upstream这个配置的,这个配置是写一组被代理的服务器地址,然后配置负载均衡的算法。这里的被代理服务器地址有两种写法。
upstream mysvr { server 192.168.10.121:3333;server 192.168.10.122:3333;
}
server {....location ~*^.+$ { proxy_pass http://mysvr; #请求转向mysvr 定义的服务器列表 }
}
然后,就来点实战的东西。
1、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB.....
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #热备 }
2、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB....
upstream mysvr {
server 127.0.0.1:7878;server 192.168.10.121:3333;
}
3、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB....
upstream mysvr {
server 127.0.0.1:7878 weight=1;server 192.168.10.121:3333 weight=2;
}
4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333;ip_hash;
}
5、如果你对上面4种均衡算法不是很理解,可以查看Nginx 配置详解,可能会更加容易理解点。
到这里你是不是感觉nginx的负载均衡配置特别简单与强大,那么还没完,咱们继续哈,这里扯下蛋。
关于nginx负载均衡配置的几个状态参数讲解。
-
down,表示当前的server暂时不参与负载均衡。
-
backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
-
max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
-
fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。
upstream mysvr {
server 127.0.0.1:7878 weight=2 max_fails=2 fail_timeout=2;server 192.168.10.121:3333 weight=1 max_fails=2 fail_timeout=1;
}