1 链接
个人博客: alex-my.xyz
CSDN: blog.csdn.net/alex_my
2 关于缓存
- 这里使用proxy_cache来实现缓存。
- 关于fastcgi_cache请看:
- proxy_cache配置和fastcgi_cache配置差不多, 所以本文并没有写。
- 使用proxy_cache后,符合条件的请求,将会直接从反向代理服务器中获取数据,不会向源服务器进行请求。
- 可以在反向代理服务器中使用proxy_cache, 在源服务器中使用fastcgi_cache。
3 环境说明
- 默认已创建nginx运行环境,如果没有,mac可以参考http://alex-my.xyz/web/Mac搭建lnmp环境。
- 均在本地进行测试。
- nginx version: nginx/1.4.3
- php version: 5.4.21
4 环境搭建
- 以下均在mac环境下。
-
nginx配置
- nginx配置目录:
/usr/local/etc/nginx
-
nginx.conf
worker_processes 2; error_log /usr/local/var/logs/nginx/error.log debug; pid /usr/local/var/run/nginx.pid; worker_rlimit_nofile 1024; 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" $host $request_time $upstream_response_time $scheme ' '$cookie_evalogin'; access_log /usr/local/var/logs/nginx/access.log main; sendfile on; keepalive_timeout 65; port_in_redirect off; # 导入各个网站的详细配置 include /usr/local/etc/nginx/sites-enabled/*.conf; }
- 通过
nginx.conf
最后一行导入各个服务器详细配置 -
sites-enabled/test_server_a.conf
server { listen 8010; server_name 127.0.0.1; root /Users/alex/WWW/test_proxy_1.com; error_page 404 /404.html; location /{ index index.html index.htm index.php; if (-e $request_filename) { break; } if (!-e $request_filename) { rewrite ^/(.*)$ /index.php/$1 last; break; } } location ~ .+\.php($|/) { root /Users/alex/WWW/test_proxy_1.com; fastcgi_index index.php; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; fastcgi_pass 127.0.0.1:9000; include fastcgi_params; } access_log /Users/alex/WWW/logs/test_proxy_1/access.log; error_log /Users/alex/WWW/logs/test_proxy_1/error.log; }
-
sites-enabled/test_server_b.conf
server { listen 8020; server_name 127.0.0.1; root /Users/alex/WWW/test_proxy_2.com; error_page 404 /404.html; location /{ index index.html index.htm index.php; if (-e $request_filename) { break; } if (!-e $request_filename) { rewrite ^/(.*)$ /index.php/$1 last; break; } } location ~ .+\.php($|/) { root /Users/alex/WWW/test_proxy_2.com; fastcgi_index index.php; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; fastcgi_pass 127.0.0.1:9000; include fastcgi_params; } access_log /Users/alex/WWW/logs/test_proxy_2/access.log; error_log /Users/alex/WWW/logs/test_proxy_2/error.log; }
- 以上搭建了两个服务器做为源服务器,这两个服务器是对用户隐藏的。
-
test_proxy.conf
upstream test_proxy { server 127.0.0.1:8010; server 127.0.0.1:8020; } server { listen 8080; server_name localhost; location / { index index.php; proxy_pass http://test_proxy; proxy_redirect off; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } }
- 以上搭建了一个反向代理服务器,是对客户端公开的。
- upstream里面可以是ip地址,也可以是域名。
- 客户端通过访问该反向代理服务器,反向代理服务器向源服务器获取信息。
- nginx配置目录:
- 按照配置文件,在相应的位置创建日志文件夹,网站文件夹。
-
为了测试方便,网站只含有一个文件
index.php
<?php function print_message($flag, $message) { echo date('Y-m-d H:i:s')."\t {$flag} \t {$message} <br>"; } // 127.0.0.1:8010 打开这个 print_message("NAME", "A is here"); // 127.0.0.1:8020 打开这个 // print_message("NAME", "B is here"); print_message("GET", json_encode($_GET)); print_message("POST", json_encode($_POST));
5 测试
- 运行
nginx -s reload
重载配置。 - 浏览器中输入对外公开的反向代理服务器的地址
127.0.0.1:8080
。 - 浏览器会通过轮询源服务器轮流显示
A is here
,B is here
。
6 upstream
-
在前面的示例中,使用了该功能实现轮询源服务器的功能, 也是默认的负载均衡配置。
upstream test_proxy { server 127.0.0.1:8010; server 127.0.0.1:8020; } server { listen 80; location / { proxy_pass http://test_proxy; } }
- 除了轮询外,upstream还有其它的分配策略。
-
weight
- 允许指定轮询权重,特别是当源服务器性能不同的情况下适用, 权重越高,被访问的比率也越大。
upstream test_proxy { server 127.0.0.1:8010 weight=5; server 127.0.0.1:8020 weight=1; }
-
ip_hash
- 根据请求的ip地址的hash结果进行分配,这样,每个访客会访问同一个源服务器,解决session问题。
- 不过,实际上当用户切换ip或者改变源服务器数量时,都可能使得用户访问的源服务器不同。解决session的问题需要用另外的方法。
upstream test_proxy { ip_hash; server 127.0.0.1:8010; server 127.0.0.1:8020; server 127.0.0.1:8030; }
-
least_conn
- 把请求放给连接数较少的源服务器,通过比较每个源服务器的conns/weight,来选取值最小的源服务器。
upstream test_proxy { least_conn; server 127.0.0.1; server 10.12.47.20; server 10.12.47.21; server 10.12.47.22 down; server 10.12.47.22 backup; }
- down: 表示该服务器不参与负载。
- backup: 当其它服务器繁忙或者都失效的时候,就会启用这台服务器,平常不参与负载。
7 keepalive
- 资料: 我为什么要谈KeepAlive, 写的很好,很清晰。
- 资料: nginx keepalive_timeout 设置策略, 关于保持时长的设置。
- 资料: Nginx upstream 长连接
- 资料: 记一次线上由nginx upstream keepalive与http协议”协作”引起的接口报错率飙高事件
- HTTP1.1支持该功能,HTTP1.0需要在header中设置
"Connection: Keep-Alive"
才行。 -
如果是在FastCGI中使用,需要另外开启
fastcgi_keep_conn on
;upstream fastcgi_backend { server 127.0.0.1:9000; keepalive 8; } server { ... location /fastcgi/ { fastcgi_pass fastcgi_backend; fastcgi_keep_conn on; ... } }
-
示例
upstream test_proxy { server 127.0.0.1; server 10.12.47.20; server 10.12.47.21; server 10.12.47.22 down; server 10.12.47.22 backup; keepalive 64; }
8 健康检查
- 反向代理将会对源服务器进行健康检查,如果源服务器返回
connect refuse
,time out
或invalid_header
,如果次数累计到max_fails
,那么会认为源服务器已经挂掉,将会在fail_timeout
分钟内或者全部节点够挂掉之前不会再去连接。 - 如果在配置中有设置了
proxy_next_upstream
,那么可以对500,502,503,504,429也会叠加max_fails
。 - 即使在
proxy_next_upstream
中配置了403, 404, 即使触发了也不会叠加max_fails
。 - 当
fail_timeout
后或者全部节点包括备用节点都挂了,那么会将失效的节点置为有效。 -
max_fails
默认为1,设置为0表示不检查。 -
fail_timeout
默认为10秒。 - 示例
upstream test_proxy {
server 10.12.47.20 weight=5;
server 10.12.47.21:8080 max_fails=3 fail_timeout=30s;
server backup.alex-my.xyz backup;
}
server {
listen 80;
location / {
proxy_pass http://test_proxy;
proxy_next_upstream http_500 http_502 http_503 http_504 http_429 error timeout invalid_header;
}
}
- 当为写请求的时候,请慎用
proxy_next_upstream
, 向源服务器1请求超时,会将请求分配的下一个源服务器2。这样就会触发多次处理,比如充值多次。 -
fail_timeout
需要设置适当的值,当一个请求在源服务器上需要大量时间完成时,如果超过了fail_timeout
,那么反向代理服务器就会请求下一个源服务器,如此反复,源服务器就容易出事了。