负载均衡,我认为是nginx最重要的功能了。那什么是负载均衡呢。
比如有一个服务,它访问量很大,一台机器吃不消了,怎么办,我们准备两台。分一部分的请求出来。现在有两台服务器提供这个服务。我们访问其中一个就行,这就有另外一个问题,就像通往某个地方有两条路,万一所有人都选择走同一条路,那这条路不是还堵吗?这就用到了负载均衡的功能了。
负载均衡目前有自带的三种方式,还有两种常用的第三方策略。
1.RR(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务某一台机器down掉了,能自动剔除。
简单配置
upstream springboot_test{
server 127.0.0.1:8084;
server 127.0.0.1:8085;
}
location / {
proxy_pass http://springboot_test;
}
1 #user nobody; 2 worker_processes 1; 3 4 #error_log logs/error.log; 5 #error_log logs/error.log notice; 6 #error_log logs/error.log info; 7 8 #pid logs/nginx.pid; 9 10 11 events { 12 worker_connections 1024; 13 } 14 15 16 http { 17 include mime.types; 18 default_type application/octet-stream; 19 20 #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 21 # '$status $body_bytes_sent "$http_referer" ' 22 # '"$http_user_agent" "$http_x_forwarded_for"'; 23 24 #access_log logs/access.log main; 25 26 sendfile on; 27 #tcp_nopush on; 28 29 #keepalive_timeout 0; 30 keepalive_timeout 65; 31 32 #gzip on; 33 34 upstream springboot_test{ 35 server 127.0.0.1:8084 weight=1; 36 server 127.0.0.1:8085 weight=2; 37 } 38 39 server { 40 listen 9000; 41 server_name localhost; 42 43 #charset koi8-r; 44 45 #access_log logs/host.access.log main; 46 47 location / { 48 proxy_pass http://springboot_test; 49 } 50 51 #error_page 404 /404.html; 52 53 # redirect server error pages to the static page /50x.html 54 # 55 error_page 500 502 503 504 /50x.html; 56 location = /50x.html { 57 root html; 58 } 59 60 # proxy the PHP scripts to Apache listening on 127.0.0.1:80 61 # 62 #location ~ .php$ { 63 # proxy_pass http://127.0.0.1; 64 #} 65 66 # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 67 # 68 #location ~ .php$ { 69 # root html; 70 # fastcgi_pass 127.0.0.1:9000; 71 # fastcgi_index index.php; 72 # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; 73 # include fastcgi_params; 74 #} 75 76 # deny access to .htaccess files, if Apache's document root 77 # concurs with nginx's one 78 # 79 #location ~ /.ht { 80 # deny all; 81 #} 82 } 83 84 85 # another virtual host using mix of IP-, name-, and port-based configuration 86 # 87 #server { 88 # listen 8000; 89 # listen somename:8080; 90 # server_name somename alias another.alias; 91 92 # location / { 93 # root html; 94 # index index.html index.htm; 95 # } 96 #} 97 98 99 # HTTPS server 100 # 101 #server { 102 # listen 443 ssl; 103 # server_name localhost; 104 105 # ssl_certificate cert.pem; 106 # ssl_certificate_key cert.key; 107 108 # ssl_session_cache shared:SSL:1m; 109 # ssl_session_timeout 5m; 110 111 # ssl_ciphers HIGH:!aNULL:!MD5; 112 # ssl_prefer_server_ciphers on; 113 114 # location / { 115 # root html; 116 # index index.html index.htm; 117 # } 118 #} 119 120 }
2.权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
例如:
upstream springboot{
server localhost:8084 weight=9;
server localhost:8085 weight=1;
}
那么10次一般只会有一次会访问到8085,9次会访问8084.
3.ip_hash
上面的两种方式都存在一个问题,那就是下一个请求来的时候,请求可能分到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的问题。比如,把登录信息保存到session中,那么跳转到另外一台服务器的时候就需要重新登录了。所以很多时候我们需要一个用户只询问同一台服务器,那么就需要用ip_hash了。ip_hash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一台后端服务器,可以解决session问题。
upstream springboot{
ip_hash;
server localhost:8084;
server localhost:8085;
}
4.fair(第三方)
按后端服务器的响应时间来分配请求,相应时间短的优先分配。
upstream springboot{
fair;
server localhost:8084;
server localhost 8085;
}
5.url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效,在upstream 中加入hash语句,server语句中不能写入weight等其他参数,hash_method里使用hash算法。
upstream springboot{
hash $request_url;
hash_method crc32;
server localhost:8084;
server localhost:8085;
}
注意:4和5需要安装第三方模块才能使用。