測試環(huán)境均為本地,測試軟件為:
nginx-1.6.0,apache-tomcat-7.0.42-1,apache-tomcat-7.0.42-2,apache-tomcat-7.0.42-3
利用nginx做負載均衡,三臺tomcat做WEB具體業(yè)務(wù)處理。
nginx配置nginx.conf:
#Nginx所用用戶和組,window下不指定 #user niumd niumd; #user nobody;#工作的子進程數(shù)量(通常等于CPU數(shù)量或者2倍于CPU)worker_processes 2;#錯誤日志存放路徑#error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info;#指定pid存放文件#pid logs/nginx.pid;events { #使用網(wǎng)絡(luò)IO模型linux建議epoll,F(xiàn)reeBSD建議采用kqueue,window下不指定。 #use epoll; #允許最大連接數(shù) 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"'; #access_log logs/access.log main; access_log logs/access.log; client_header_timeout 3m; client_body_timeout 3m; send_timeout 3m; client_header_buffer_size 1k; large_client_header_buffers 4 4k; sendfile on; tcp_nopush on; tcp_nodelay on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; include gzip.conf; upstream localhost { #根據(jù)ip計算將請求分配各那個后端tomcat,許多人誤認為可以解決session問題,其實并不能。 #同一機器在多網(wǎng)情況下,路由切換,ip可能不同 server localhost:18081; server localhost:18082; server localhost:18083; #根據(jù)IP做分配策略 ip_hash; } #down 表示單前的server暫時不參與負載 #weight 默認為1.weight越大,負載的權(quán)重就越大。 #max_fails :允許請求失敗的次數(shù)默認為1.當超過最大次數(shù)時,返回proxy_next_upstream 模塊定義的錯誤 #fail_timeout:max_fails 次失敗后,暫停的時間。 #backup: 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。 #nginx 的 upstream目前支持 4 種方式的分配 #1)、輪詢(默認) 每個請求按時間順序逐一分配到不同的后端服務(wù)器,如果后端服務(wù)器down掉,能自動剔除。 #2)、weight 指定輪詢幾率,weight和訪問比率成正比,用于后端服務(wù)器性能不均的情況。 #2)、ip_hash 每個請求按訪問ip的hash結(jié)果分配,這樣每個訪客固定訪問一個后端服務(wù)器,可以解決session的問題。 #3)、fair(第三方)按后端服務(wù)器的響應(yīng)時間來分配請求,響應(yīng)時間短的優(yōu)先分配。 #4)、url_hash(第三方) server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://localhost; proxy_redirect off; 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; #允許客戶端請求的最大單文件字節(jié)數(shù) client_body_buffer_size 128k; #緩沖區(qū)代理緩沖用戶端請求的最大字節(jié)數(shù), proxy_connect_timeout 90; #nginx跟后端服務(wù)器連接超時時間(代理連接超時) proxy_send_timeout 90; #后端服務(wù)器數(shù)據(jù)回傳時間(代理發(fā)送超時) proxy_read_timeout 90; #連接成功后,后端服務(wù)器響應(yīng)時間(代理接收超時) proxy_buffer_size 4k; #設(shè)置代理服務(wù)器(nginx)保存用戶頭信息的緩沖區(qū)大小 proxy_buffers 4 32k; #proxy_buffers緩沖區(qū),網(wǎng)頁平均在32k以下的話,這樣設(shè)置 proxy_busy_buffers_size 64k; #高負荷下緩沖大小(proxy_buffers*2) proxy_temp_file_write_size 64k; #設(shè)定緩存文件夾大小,大于這個值,將從upstream服務(wù)器傳 } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443 ssl; # server_name localhost; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #}}Tomcat1配置server.xml:
<?xml version='1.0' encoding='utf-8'?><Server port="18001" shutdown="SHUTDOWN"> <Connector port="18081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="18441" /> <Connector port="18021" protocol="AJP/1.3" redirectPort="18441" /> <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"> </Service></Server>Tomcat1配置server.xml:
<?xml version='1.0' encoding='utf-8'?><Server port="18002" shutdown="SHUTDOWN"> <Connector port="18082" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="18442" /> <Connector port="18022" protocol="AJP/1.3" redirectPort="18442" /> <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"> </Service></Server>Tomcat3配置server.xml:
<?xml version='1.0' encoding='utf-8'?><Server port="18003" shutdown="SHUTDOWN"> <Connector port="18083" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="18443" /> <Connector port="18023" protocol="AJP/1.3" redirectPort="18443" /> <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"> </Service></Server>
分別啟動三臺tomcat,訪問到地址依次是:http://localhost:18081;http://localhost:18082;http://localhost:18083
然后啟動nginx,訪問地址是:http://localhost
(cmd下面運行nginx.exe,關(guān)閉cmd下面運行nginx -s stop)
這樣子根據(jù)客戶端IP做負載均衡的同步策略已基本可滿足需求,但是考慮到客戶端多網(wǎng)卡或者客戶端訪問不同的服務(wù)器時產(chǎn)生session不同步的問題,需要使用memcached做session同步策略,后續(xù)我會跟上配置文檔。
附:以下是來自于互聯(lián)網(wǎng)的三中方法:
1、不用session,通過cookie等方式繞過session 。
貌似這種方式還是會存在問題,假如客戶端禁用cookie怎么辦。
2、應(yīng)用服務(wù)器自行實現(xiàn)共享
如單點登錄,采用中央認證服務(wù)器;或者memcache來存放后端服務(wù)器需要使用的公共數(shù)據(jù)。我曾經(jīng)就有程序采用本地ehcache+memcache來緩存數(shù)據(jù),其中ehcache緩存一些與他機無關(guān)的數(shù)據(jù),memcache緩存一些公共數(shù)據(jù),但這樣往往也容易出現(xiàn)問題。
3、ip_hash方式解決session共享
nginx中的ip_hash技術(shù)能夠?qū)⒛硞€ip的請求定向到同一臺后端,這樣一來這個ip下的某個客戶端和某個后端就能建立起穩(wěn)固的session,ip_hash是在upstream配置中定義的, 配置方式樣例:
upstream backend {
server 127.0.0.1:8080 ;
server 127.0.0.1:9090 ;
ip_hash;
}
ip_hash是容易理解的,但是因為僅僅能用ip這個因子來分配后端,因此ip_hash是有缺陷的,不能在一些情況下使用:
(1)/ nginx不是最前端的服務(wù)器。ip_hash要求nginx一定是最前端的服務(wù)器,否則nginx得不到正確ip,就不能根據(jù)ip作hash。譬如使用 的是squid為最前端,那么nginx取ip時只能得到squid的服務(wù)器ip地址,用這個地址來作分流是肯定錯亂的。
(2)/ nginx的后端還有其它方式的負載均衡。假如nginx后端又有其它負載均衡,將請求又通過另外的方式分流了,那么某個客戶端的請求肯定不能定位到同一 臺session應(yīng)用服務(wù)器上。這么算起來,nginx后端只能直接指向應(yīng)用服務(wù)器,或者再搭一個squid,然后指向應(yīng)用服務(wù)器。最好的辦法是用 location作一次分流,將需要session的部分請求通過ip_hash分流,剩下的走其它后端去。
( 3) upstream_hash(這種方式?jīng)]有嘗試過)
下面是從網(wǎng)絡(luò)上整理的關(guān)于nginx與apache的對比:
1、nginx與apache優(yōu)缺點對比
nginx相對于apache的優(yōu)點: