使用nginx做负载均衡的两大模块:
nginx 的负载均衡功能依赖于 ngx_http_upstream_module模块,所支持的代理方式有 proxy_pass(一般用于反向代理),fastcgi_pass(一般用于和动态程序交互),memcached_pass,proxy_next_upstream,fastcgi_next_pass,memcached_next_pass 。
upstream 模块应该放于http{}标签内。
模块写法:
- upstream backend {
- ip_hash;
- server backend1.example.com weight=5;
- server backend2.example.com:8080;
- server backup1.example.com:8080 backup;
- server backup2.example.com:8080 backup;
- }
-
实例一:
- upstream dynamic {
- zone upstream_dynamic 64k;
-
- server backend1.example.com weight=5;
- server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
- server 192.0.2.1 max_fails=3;
- server backend3.example.com resolve;
-
- server backup1.example.com:8080 backup;
- server backup2.example.com:8080 backup;
- }
-
语法解释:
server IP 调度状态
server指令指定后端服务器IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。
例:如果max_fails是5,他就检测5次,如果五次都是502.那么,他就会根据fail_timeout 的值,等待10秒,再去检测。
server 如果接域名,需要内网有DNS服务器,或者在负载均衡器的hosts文件做域名解析。server后面还可以直接接IP或IP加端口。
- upstream backend {
- server backend2.example.com:8080;
- server backup1.example.com:8080 backup;
- keepalive 100;
- }
-
通过该指令配置了每个worker进程与上游服务器可缓存的空闲连接的最大数量。
当超出这个数量时,最近最少使用的连接将被关闭。keepalive指令不限制worker进程与上游服务器的总连接。
- location / {
- # 支持keep-alive
- proxy_http_version 1.1;
- proxy_set_header Connection "";
- proxy_pass http://backup;
- }
-
连接池配置建议
location作用:基于一个指令设置URI。
基本语法:
- Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
- location @name { ... }
- Default: —
- Context: server, location
-
匹配是有优先级的,不是按照nginx的配置文件进行。
官方的例子:
- location = / {
- [ configuration A ]
- }
- location / {
- [ configuration B ]
- }
- location /documents/ {
- [ configuration C ]
- }
- location ^~ /images/ {
- [ configuration D ]
- }
- location ~* \.(gif|jpg|jpeg)$ {
- [ configuration E ]
- }
-
结论:
测试用的例子:
- location / {
- return 401;
- }
- location = / {
- return 402;
- }
- location /documents/ {
- return 403;
- }
- location ^~ /images/ {
- return 404;
- }
- location ~* \.(gif|jpg|jpeg)$ {
- return 500;
- }
-
测试结果(重点看):
- [root@lb01 conf]# curl -I -s -o /dev/null -w "%{http_code}\n" http://10.0.0.7/
- 402
- [root@lb01 conf]# curl -I -s -o /dev/null -w "%{http_code}\n" http://10.0.0.7/index.html
- 401
- [root@lb01 conf]# curl -I -s -o /dev/null -w "%{http_code}\n" http://10.0.0.7/documents/document.html
- 403
- [root@lb01 conf]# curl -I -s -o /dev/null -w "%{http_code}\n" http://10.0.0.7/images/1.gif
- 404
- [root@lb01 conf]# curl -I -s -o /dev/null -w "%{http_code}\n" http://10.0.0.7/dddd/1.gif
- 500
-
结果总结:
匹配的优先顺序,=>^~(匹配固定字符串,忽略正则)> 完全相等>~*>空>/ 。
工作中尽量将'='放在前面
proxy_pass 指令属于ngx_http_proxy_module 模块,此模块可以将请求转发到另一台服务器。
写法:
- proxy_pass http://localhost:8000/uri/;
-
实例一:
- upstream blog_real_servers {
- server 10.0.0.9:80 weight=5;
- server 10.0.0.10:80 weight=10;
- server 10.0.0.19:82 weight=15;
- }
- server {
- listen 80;
- server_name blog.etiantian.org;
- location / {
- proxy_pass http://blog_real_servers;
- proxy_set_header host $host;
- }
- }
-
配置如下:
-
- log_format commonlog '$remote_addr - $remote_user [$time_local] "$request" '
- '$status $body_bytes_sent "$http_referer" '
- '"$http_user_agent" "$http_x_forwarded_for"';
-
rs_apache节点的httpd.conf配置
- LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{U
- ser-Agent}i\"" combined修改日志记录
- apache
- LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b" common
-
Nginx提供了health_check语句来提供负载(upstream)时的键康检查机制(注意:此语句需要设置在location上下文中)。
支持的参数有:
一个简单的设置如下,将使用默认值:
- location / {
- proxy_pass http://backend;
- health_check;
- }
-
对就应用,我们可以专门定义一个API用于健康检查:/api/health_check,并只返回HTTP状态码为200。并设置两次检查之间的间隔值为1秒。这样,health_check语句的配置如下:
- health_check uri="/api/health_check" interval;
-
匹配match的方法
- http {
- server {
- ...
- location / {
- proxy_pass http://backend;
- health_check match=welcome;
- }
- }
-
- match welcome {
- status 200;
- header Content-Type = text/html;
- body ~ "Welcome to nginx!";
- }
- }
-
match 例子举例
- [root@lb01 conf]# cat nginx.conf
- worker_processes 1;
- events {
- worker_connections 1024;
- }
- http {
- include mime.types;
- default_type application/octet-stream;
- sendfile on;
- keepalive_timeout 65;
- #blog lb by oldboy at 201303
- upstream blog_real_servers {
- server 10.0.0.9:80 weight=1 max_fails=1 fail_timeout=10s;
- server 10.0.0.10:80 weight=1 max_fails=2 fail_timeout=20s;
-
- }
- server {
- listen 80;
- server_name blog.etiantian.org;
- location / {
- proxy_pass http://blog_real_servers;
- include proxy.conf;
- }
- }
- }
-
- [root@lb01 conf]# cat proxy.conf
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_connect_timeout 90;
- proxy_send_timeout 90;
- proxy_read_timeout 90;
- proxy_buffer_size 4k;
- proxy_buffers 4 32k;
- proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k;
-
- ## Only allow these request methods ##
- if ($request_method !~ ^(GET|HEAD|POST)$ ) {
- return 444;
- }
-
最终实现:
-
- [root@lb01 conf]# cat nginx.conf
- worker_processes 1;
- events {
- worker_connections 1024;
- }
- http {
- include mime.types;
- default_type application/octet-stream;
- sendfile on;
- keepalive_timeout 65;
- #blog lb by oldboy at 201303
-
- upstream static_pools {
- server 10.0.0.9:80;
- }
- upstream dynamic_pools {
- server 10.0.0.10:80;
- }
- upstream upload_pools {
- server 10.0.0.9:80;
- }
-
- server {
- listen 80;
- server_name blog.biglittleant.cn;
-
- location / {
- proxy_pass http://static_pools;
- include proxy.conf;
- }
-
- location /static/ {
- proxy_pass http://static_pools;
- include proxy.conf;
- }
-
- location ~* \.(gif|jpg|jpeg)$ {
- proxy_pass http://static_pools;
- include proxy.conf;
- }
-
- location /dynamic/ {
- proxy_pass http://dynamic_pools;
- include proxy.conf;
- }
- location /upload/ {
- proxy_pass http://upload_pools;
- include proxy.conf;
- }
- }
- }
-
- server {
- listen 80;
- server_name blog.etiantian.org;
- location / {
- if ($http_user_agent ~* "android")
- {
- proxy_pass http://android_pools;
- }
- if ($http_user_agent ~* "iphone")
- {
- proxy_pass http://iphone_pools;
- }
- proxy_pass http://pc_pools;
- include extra/proxy.conf;
- }
- access_log off;
- }
-