Nginx HTTP负载均衡/反向代理的相关参数测试

原文地址:http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/03/15/1984976.html

测试目的

(1)弄清楚HTTP Upstream 模块中Server指令的max_failsfail_timeout参 数的关系、它们对后端服务器健康情况的检查起到了什么作用、它们的取值对Http proxy模块中的其它指令是否有直接或间接的影响等……

(2)测试HTTP Proxy模块中proxy_next_upstream、proxy_connect_timeout、proxy_read_timeout、 proxy_send_timeout指令的作用、对nginx性能的影响、对后端服务器响应的处理等……

测试方法

本文测试不会使用压力测试,所有的测试都是通过浏览器手动刷新来实现的。后端服务器使用简单的php程序来实现。

测试环境

Nginx负载均衡/反向代理服务器
系统:CentOS 5.4 64bit
Nginx:0.7.65
IP:192.168.108.10

后端web服务器
系统:CentOS 5.4 64bit
Web环境:apache+php
Web-1 IP:192.168.108.163
Web-2 IP:192.168.108.164

本次测试主要针对HTTP Upstream和HTTP Proxy模块进行,下面测试环境中http upstream 和http proxy模块参数的初始化设置,后文会针对测试的参数进行相应的修改:


upstream test  {
server 192.168.108.163 ;
server 192.168.108.164:80;
}

server {
listen          80;
server_name     .test.com;
index           index.php index.html index.htm;

location / {
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;

proxy_connect_timeout       10s;
proxy_read_timeout          2s;
#proxy_send_timeout          10s;
proxy_pass http://test;
}
}

提出server指令后面的参数部分,以下摘抄nginx wiki 内容

语法:server name [parameters]

parameters包 含:

·weight = NUMBER - 设置服务器权重,默认为1。

·max_fails = NUMBER - 在一定时间内(这个时间在fail_timeout参数中设置)检查这个服务器是否可用时产生的最多失败请求数,默认为1,将其设置为0可以关闭检查,这 些错误在proxy_next_upstream或fastcgi_next_upstream(404错误不会使max_fails增加)中定义。

·fail_timeout = TIME - 在这个时间内产生了max_fails所设置大小的失败尝试连接请求后这个服务器可能不可用,同样它指定了服务器不可用的时间(在下一次尝试连接请求发起 之前),默认为10秒,fail_timeout与前端响应时间没有直接关系,不过可以使用proxy_connect_timeout和 proxy_read_timeout来控制。

·down - 标记服务器处于离线状态,通常和ip_hash一起使用。

·backup - (0.6.7或更高)只用于本服务器,如果所有的非备份服务器都宕机或繁忙。

关于max_fails 参数的理解:根 据上面的解释,max_fails默认为1,fail_timeout默 认为10秒,也就是说,默认情况下后端服务器在10秒钟之内可以容许有一次的失 败,如果超过1次则视为该服务器有问题,将该服务器标记为不可用。等待10秒后再 将请求发给该服务器,以此类推进行后端服务器的健康检查。但如果我将max_fails设置为0, 则代表不对后端服务器进行健康检查,这样一来fail_timeout参数也就没什么意义了。那若后端服务器真的出现 问题怎么办呢?上文也说了,可以借助proxy_connect_timeout和proxy_read_timeout进 行控制。

下面介绍http proxy模块中的相关指令:

proxy_next_upstream
语法: proxy_next_upstream [error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off]
确定在何种情况下请求将转发到下一个服务器。转发请求只发生在没有数据传递到客户端的过程中。

proxy_connect_timeout
后端服务器连接的超时时间_发起握手等候响应超时时间

proxy_read_timeout
连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)

proxy_send_timeout
后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据

proxy_pass
这个指令设置被代理服务器的地址和被映射的URI

开始测试

情况1:后端程序执行时间超过或等于proxy_read_timeout设 置值,max_fails=0 关闭后端服务器健康检查。

Nginx配置修改内容 server 192.168.108.163 max_fails = 0;
server 192.168.108.164 max_fails = 0;
proxy_next_upstream error timeout
proxy_read_timeout 2s
 
后端web服务器
Web1 test.php Web2 test.php
<?php
header(‘RS:Web1‘);
$t = 2;
sleep($t);
echo "sleep {$t}s<br>";
echo "web-1<br>";
?>
<?php
header(‘RS:Web2‘);
$t = 5;
sleep($t);
echo "sleep {$t}s<br>";
echo "web-2<br>";
?>
备注:

我这里的两台后端web服务器,他们的主页文件均为一个test.php程序,该程序分别sleep了2秒和5秒,等于和超过了 proxy_read_timeout的时间,[max_fails=0] 即关闭后端服务器健康检查。[proxy_next_upstream error timeout] 说明碰到错误或超时的情况切到下一个后端服务器。如此设置后利用curl命令对nginx发起连接请求,看nginx会作何反应。

测试开始:

(1)curl -I -w %{time_total}:%{time_connect}:%{time_starttransfer} www.test.com/test.php
HTTP/1.1 504 Gateway Time-out
Server: nginx/0.7.65
Date: Tue, 18 May 2010 02:43:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 183
Connection: keep-alive

4.008:0.002:4.007

说明:

连续请求3次后得到的http返回结果是一样的,均为504 Gateway Time-out 错误。这种情况只有在后端服务器都有问题的时才会出现这个错误,很显然我这里的proxy_read_timeout设置的时间太短,后端程序还没来得及 把程序执行完,nginx就迫不及待的将请求甩给upstream定义的另一台服务器上了,当发现另外一台服务器同样2秒没有返回后,nginx这回没有 服务器可用,只有返回504 Gateway Time-out 。这也是为什么最后的time_total时间是4秒。(经查看两台web服务器的访问日志得知,均有一条访问记录,且返回代码为200,说明nginx 确实来过,但没有等到执行完成就匆匆的离去了)如果我有3台服务器,在保证任何不变的情况下,time_total时间一定会是6秒,因为nginx会一 个接一个的将3台服务器都走一遍。

-----------------------------------------------------------------------------------------------------------------------

好了,确认是我proxy_read_timeout设置时间太短后,我将它的值设置为3秒,再通过curl命令访问:

(2)curl -I -w %{time_total}:%{time_connect}:%{time_starttransfer} www.test.com/test.php
HTTP/1.1 200 OK
Server: nginx/0.7.65
Date: Tue, 18 May 2010 03:07:58 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.1.6
RS: Web1

5.042:0.005:5.042

说明:通过3次连续请求,得到的结果是一样的,RS:Web1 也就是说我这三次的请求都甩到了web1上。但我web1中的程序只需要2秒后就可以返回结果,但为什么我通过nginx代理后时间总是我的 程序执行时间+proxy_read_timeout时间呢?

-----------------------------------------------------------------------------------------------------------------------

继续将proxy_read_timeout设置为4s

(3)curl -I -w %{time_total}:%{time_connect}:%{time_starttransfer} www.test.com/test.php
HTTP/1.1 200 OK
Server: nginx/0.7.65
Date: Tue, 18 May 2010 03:15:25 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.1.6
RS: Web1

6.004:0.000:6.004

三次请求后结果也是一样,这次花的时间更长了,但确实是程序执行时 间+proxy_read_timeout 时间。但为什么每次都需要6秒呢?按照upstream中定义的权重应该是平分请求的,最起码 应该有2秒的时候。经过分析得知:最终返回给用户请求的是web1,那么当再次请求的时候一定会分给web2,由于web2是sleep 5秒的,因此经过proxy_read_timeout的时间(4s)后会跳到web1,结果还是web1返回的请求,所花时间就是nginx在web2 等待的时间+web1执行的时间,以此类推下一次nginx自然的还会分给web2……。如果有更多的后端web,则判断下一个请求服务器可以看当前返回 给最终用户的是那台服务器,然后根据upstream中定义的顺序向下查询(权重一样的情况)

结论:

(1)上面的三次测试分别将proxy_read_timeout的值设置为2s、3s、4s的情况进行的。最终的测试结果也都在后面做了解释与说 明。由于我关闭了后端服务器的健康检查(max_fails=0)因此判断后端服务器情况的唯一依据便是proxy_read_timeout参数,如果 这个参数设置得过小,但后端程序的执行或多或少会超过这个时间的话,这种情况nginx的效率是非常低的。

(2)上面的测试都是后端服务器正常但执行超时的情况下nginx根据proxy_read_timeout和 proxy_next_upstream的值来选择下一个服务器,那如果我后端服务器直接报错的情况呢?可以想到如果报错信息在 proxy_next_upstream 中有定义的话nginx还会跳到下一台服务器。否则直接将保存信息返回给nginx从而最终呈献给用户

情况2:打开后端服务器健康检查,测试程序执行时间超过或等于proxy_read_timeout值或后端服务器直接报错的情况

Nginx配置修改内容 server 192.168.108.163 max_fails = 1;
server 192.168.108.164 max_fails = 1;
proxy_next_upstream error timeout http_500 http_502 http_504
proxy_read_timeout 2s
 
后端web服务器
Web1 test.php Web2 test.php
<?php
header(‘RS:Web1‘);
$t = 2;
sleep($t);
echo "sleep {$t}s<br>";
echo "web-1<br>";
?>
<?php
header(‘RS:Web2‘);
header(‘http/1.1 500 Internal Server Error ‘);
#$t = 5;
#sleep($t);
echo "sleep {$t}s<br>";
echo "web-2<br>";
?>
备注:

开启了后端服务器健康检查
proxy_read_timeout 2s (下面会随着测试变更)
Web1程序仍然sleep 2s
修改了Web2程序,让他直接返回500错误

测试开始:

(1)连续测试三次结果如下:

curl -I -w %{time_total}:%{time_connect}:%{time_starttransfer} www.test.com/test.php
HTTP/1.1 504 Gateway Time-out
Server: nginx/0.7.65
Date: Tue, 18 May 2010 07:01:48 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 183
Connection: keep-alive

2.005:0.001:2.005

curl -I -w %{time_total}:%{time_connect}:%{time_starttransfer} www.test.com/test.php
HTTP/1.1 502 Bad Gateway
Server: nginx/0.7.65
Date: Tue, 18 May 2010 07:01:50 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 173
Connection: keep-alive

0.001:0.001:0.001

curl -I -w %{time_total}:%{time_connect}:%{time_starttransfer} www.test.com/test.php
HTTP/1.1 504 Gateway Time-out
Server: nginx/0.7.65
Date: Tue, 18 May 2010 07:01:57 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 183
Connection: keep-alive

2.005:0.001:2.005

说明:

第1次请求所用时间是2秒,web1执行超时,web2返回了500错误,upstream没有更多的后端,因此nginx直接把504扔出来了, 同时标记web2,web1不可用。查看后端2台web服务器的访问日志,均有nginx代理的访问记录。
第2次请求时间很短,报502错误,说明没有可用的后端服务器接受请求。查看后端两台web服务器访问日志,没有任何变化,说明这两台服务器被nginx 标记为不可用,没有把请求转向后端,直接返回用户502错误
第3次请求同第1次

(2)修改 proxy_read_timeout 3s 连续访问6次后结果以及2台web服务器的日志情况
curl -I -w %{time_total}:%{time_connect}:%{time_starttransfer} www.test.com/test.php
HTTP/1.1 200 OK
Server: nginx/0.7.65
Date: Tue, 18 May 2010 07:30:15 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.1.6
RS: Web1

2.003:0.001:2.002

访问日志

Web1
[18/May/2010:15:30:00
[18/May/2010:15:30:03
[18/May/2010:15:30:05
[18/May/2010:15:30:08
[18/May/2010:15:30:11
[18/May/2010:15:30:13

Web2

[18/May/2010:15:30:00
[18/May/2010:15:30:11

说明:

由访问日志可知:
第1次请求是被分到web2上的,由于它返回了500错误,因此请求被转到web1,并标记web2不可用。
第2次至第4次均将请求给了web1,第四次请求完毕后距第一请求已经过去了8秒。
第5次请求时已经是fail_timeout参数默认的10s也就是标记web2不可用的时间已经过去了,因此在第5 次访问实际上和第一次情况是一样的。

结论:

(1proxy_next_upstream参数很有用,他可以避免很多 错误
(2max_fails 参数在繁忙的大型系统中建议设置为3,如果没有几个后端服务器的话保持默认即可。
(3proxy_read_timeout要根据自身程序而定,不要过大,也不 要太小。如果是php程序,请参照php.ini中的max_execution_time选项值。

时间: 2024-12-28 16:18:59

Nginx HTTP负载均衡/反向代理的相关参数测试的相关文章

nginx做负载均衡反向代理的配置

nginx.conf配置文件内容: #根据服务器核心数设定 worker_processes  1; error_log    /usr/local/nginx/logs/nginx_error.log    crit; pid          /usr/local/nginx/nginx.pid; worker_rlimit_nofile   51200; events {      use epoll;      worker_connections 51200; } http {    

Nginx 负载均衡反向代理

一.集群介绍以及常用集群硬件知识介绍及选型 1.负载均衡以及高可用集群的作用1).负载均衡集群的作用:a.分担用户访问请求及数据流量(负载均衡)b.保持业务连续性,即 7x24 小时服务(高可用性)c.应用于 web 业务及数据库从库等服务器的业务.负载均衡集群典型的开源软件:LVS.Nginx.Haproxy2).高可用集群的作用:a.当一台机器宕机时,另外一台机器接管宕机的机器的 IP 资源和服务资源,提供服务.b.常用于不易实现负载均衡的应用,比如负载均衡器,主数据库.主存储对之间.高可用

nginx的负载均衡,代理等功能详解

Nginx的负载均衡: (1)nginx的算法: upstream目前支持 4 种方式的分配 1).轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. 2).weight 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况. 2).ip_hash 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题. 3).fair(第三方) 按后端服务器的响应时间来分配请求,响应时间短的优先

nginx域名转发 负载均衡 反向代理

公司有三台机器在机房,因为IP不够用,肯定要分出来,所以要建立单IP 多域名的反向代理, 就是当请求www.abc.com 跳转到本机, 请求www.bbc.com 跳转到192.168.0.35 机器上去, 前提 192.168.0.35 装了nginx和php环境. #vi /usr/local/nginx/conf/nginx.conf #修改其中的配置 upstream www # www可自定义,下面的名称可以用到 { server xxx.xxx.xxx.xxx:80 max_fai

nginx配置+虚拟主机+负载均衡+反向代理

nginx启动+控制+配置文件 /usr/local/nginx/nginx    #启动 /usr/local/nginx/nginx -s reload    #重新加载配置文件,不需重启nginx进程 ##nginx.conf配置文件详解 nginx的配置文件相比apache,比较清晰.简单,大致分为几块: main events    {     .... } http    {     ...     upstream PROJECT_NAME    {        ##负载均衡服务

nginx 负载均衡 反向代理

A(主).B.C服务器.A为主服务器 原理: 域名解析到A服务器,A服务器分配给到B.C服务器上 核心配置(该配置方法主服务器不提供服务): upstream nginx.cn { #ip_hash; #server 192.168.1.228:80 weight=5; #server 192.168.1.224:80 weight=5; server 192.168.1.228:80; server 192.168.1.240:80; } server{ listen       80; se

nginx四层负载均衡配置

nginx四层负载均衡配置代理Mysql集群 环境如下: ip 192.168.6.203 Nginx ip 192.168.6.*(多台) Mysql 步骤一 查看Nginx是否安装stream模块 没安装则进行安装 操作步骤如下 至此 已保证在没中断服务的情况下成功添加stream模块 步骤二 配置 mysql负载均衡案例 修改Nginx配置文件nginx.conf 内容如下图 测试步骤如下 后端Mysql需做好读写分离 创建好相应权限的用户 到客户端连接Nginx创建wuguiyunwei

nginx和tomcat实现反向代理、负载均衡和session共享

这类的文章非常多,nginx和tomcat实现反向代理.负载均衡实现非常easy,能够參照http://blog.csdn.net/liuzhigang1237/article/details/8880752 但tomcat借助memcache实现session共享非常麻烦(和jar的版本号有关),这里做个记录. 我的tomcat的版本号是7.0.53,须要加入的jar是: couchbase-client-1.2.0 javolution-5.4.3.1 Memcached-Java-Clie

Debian/Ubuntu下Nginx的安装、反向代理和负载均衡的基本配置

源码安装 去Nginx官网下载最新稳定版,这里用的是nginx-1.6.3版. 下载完成后解压缩,进入该目录执行: ./configure 如果你的机器上没有安装PCER库.zlib库等,这一步会出错. sudo apt-get install libpcre3-dev zlibc zlib-bin 然后执行: sudo make sudo make install 完成后,nginx会默认安装在/usr/local/nginx目录下. 反向代理的基本配置 nginx默认使用的配置文件在/use