nginx+tomcat負載均衡策略

測試環境均爲本地,測試軟件爲:php

nginx-1.6.0,apache-tomcat-7.0.42-1,apache-tomcat-7.0.42-2,apache-tomcat-7.0.42-3
html

利用nginx作負載均衡,三臺tomcat作WEB具體業務處理。前端

nginx配置nginx.conf:node

#Nginx所用用戶和組,window下不指定  
#user  niumd niumd;  
#user  nobody;

#工做的子進程數量(一般等於CPU數量或者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 {
    #使用網絡IO模型linux建議epoll,FreeBSD建議採用kqueue,window下不指定。  
    #use epoll;  
      
    #容許最大鏈接數
    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 {  
      #根據ip計算將請求分配各那個後端tomcat,許多人誤認爲能夠解決session問題,其實並不能。  
      #同一機器在多網狀況下,路由切換,ip可能不一樣  
        
      server localhost:18081;  
      server localhost:18082;  
      server localhost:18083; 
      #根據IP作分配策略
      ip_hash; 
     }  
     #down 表示單前的server暫時不參與負載
     #weight  默認爲1.weight越大,負載的權重就越大。
     #max_fails :容許請求失敗的次數默認爲1.當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤
     #fail_timeout:max_fails 次失敗後,暫停的時間。
     #backup: 其它全部的非backup機器down或者忙的時候,請求backup機器。因此這臺機器壓力會最輕。

    #nginx 的 upstream目前支持 4 種方式的分配 
    #1)、輪詢(默認) 每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除。 
    #2)、weight 指定輪詢概率,weight和訪問比率成正比,用於後端服務器性能不均的狀況。 
    #2)、ip_hash 每一個請求按訪問ip的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決session的問題。  
    #3)、fair(第三方)按後端服務器的響應時間來分配請求,響應時間短的優先分配。  
    #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;	#容許客戶端請求的最大單文件字節數  
            client_body_buffer_size     128k;	#緩衝區代理緩衝用戶端請求的最大字節數,  
            proxy_connect_timeout       90;	#nginx跟後端服務器鏈接超時時間(代理鏈接超時)  
            proxy_send_timeout          90;	#後端服務器數據回傳時間(代理髮送超時)  
            proxy_read_timeout          90;	#鏈接成功後,後端服務器響應時間(代理接收超時)  
            proxy_buffer_size           4k;	#設置代理服務器(nginx)保存用戶頭信息的緩衝區大小
            proxy_buffers               4 32k;	#proxy_buffers緩衝區,網頁平均在32k如下的話,這樣設置  
            proxy_busy_buffers_size     64k;	#高負荷下緩衝大小(proxy_buffers*2)  
            proxy_temp_file_write_size  64k;	#設定緩存文件夾大小,大於這個值,將從upstream服務器傳  
        }

        #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:18083linux

而後啓動nginx,訪問地址是:http://localhostnginx

(cmd下面運行nginx.exe,關閉cmd下面運行nginx -s stop)git


這樣子根據客戶端IP作負載均衡的同步策略已基本可知足需求,可是考慮到客戶端多網卡或者客戶端訪問不一樣的服務器時產生session不一樣步的問題,須要使用memcached作session同步策略,後續我會跟上配置文檔。github

附:如下是來自於互聯網的三中方法:
一、不用session,經過cookie等方式繞過session 。
      貌似這種方式仍是會存在問題,假如客戶端禁用cookie怎麼辦。
二、應用服務器自行實現共享
    如單點登陸,採用中央認證服務器;或者memcache來存放後端服務器須要使用的公共數據。我曾經就有程序採用本地ehcache+memcache來緩存數據,其中ehcache緩存一些與他機無關的數據,memcache緩存一些公共數據,但這樣每每也容易出現問題。
三、ip_hash方式解決session共享  
        nginx中的ip_hash技術可以將某個ip的請求定向到同一臺後端,這樣一來這個ip下的某個客戶端和某個後端就能創建起穩固的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不是最前端的服務器。ip_hash要求nginx必定是最前端的服務器,不然nginx得不到正確ip,就不能根據ip做hash。譬如使用 的是squid爲最前端,那麼nginx取ip時只能獲得squid的服務器ip地址,用這個地址來做分流是確定錯亂的。
      (2)/ nginx的後端還有其它方式的負載均衡。假如nginx後端又有其它負載均衡,將請求又經過另外的方式分流了,那麼某個客戶端的請求確定不能定位到同一 臺session應用服務器上。這麼算起來,nginx後端只能直接指向應用服務器,或者再搭一個squid,而後指向應用服務器。最好的辦法是用 location做一次分流,將須要session的部分請求經過ip_hash分流,剩下的走其它後端去。
      (3) upstream_hash(這種方式沒有嘗試過)  
web

下面是從網絡上整理的關於nginx與apache的對比:apache

一、nginx與apache優缺點對比

nginx相對於apache的優勢:  (1)輕量級,一樣起web 服務,比apache佔用更少的內存及資源  (2)抗併發,nginx 處理請求是異步非阻塞的,而apache 則是阻塞型的,在高併發下nginx 能保持低資源低消耗高性能  (3)高度模塊化的設計,編寫模塊相對簡單  (4)社區活躍,各類高性能模塊出品迅速啊  apache 相對於nginx 的優勢:  (1)rewrite:比nginx 的rewrite 強大  (2)動態頁面:模塊超多,基本想到的均可以找到  (3)少bug ,nginx 的bug 相對較多  (4)超穩定  存在就是理由,通常來講,須要性能的web 服務,用nginx 。若是不須要性能只求穩定,那就apache 吧。 後者的各類功能模塊實現得比前者,例如ssl 的模塊就比前者好,可配置項多。這裏要注意一點,epoll(freebsd 上是 kqueue )網絡 IO 模型是nginx 處理性能高的根本理由,但並非全部的狀況下都是epoll 大獲全勝的,若是自己提供靜態服務的就只有寥寥幾個文 件,apache 的select 模型或許比epoll 更高性能。固然,這只是根據網絡IO 模型的原理做的一個假設,真正的應用仍是須要實測了再說 的。  二、做爲 Web 服務器:相比 Apache,Nginx 使用更少的資源,支持更多的併發鏈接,體現更高的效率,這點 使 Nginx 尤爲受到虛擬主機提供商的歡迎。在高鏈接併發的狀況下,Nginx是Apache服務器不錯的替代品: Nginx在美國是作虛擬主機生 意的老闆們常常選擇的軟件平臺之一. 可以支持高達 50,000 個併發鏈接數的響應, 感謝Nginx爲咱們選擇了 epoll and kqueue 做爲開發模型. Nginx 做爲負載均衡服務器: Nginx 既能夠在內部直接支持 Rails 和 PHP 程序對外進行服務, 也能夠支持做爲 HTTP代理 服務器對外進行服務. Nginx採用C進行編寫, 不管是系統資源開銷仍是CPU使用效率都比 Perlbal 要好不少.  做爲郵件代理服務器: Nginx 同時也是一個很是優秀的郵件代理服務器(最先開發這個產品的目的之一也是做爲郵件代理服務器), Last.fm 描述了成功而且美妙的使用經驗. Nginx 是 一個安裝很是的簡單 , 配置文件很是簡潔(還可以支持perl語法), Bugs 很是少的服務器: Nginx 啓動特別容易, 而且幾乎能夠作到 7*24不間斷運行,即便運行數個月也不須要從新啓動. 你還可以不間斷服務的狀況下進行軟件版本的升級 .  三、Nginx 配置簡潔, Apache 複雜  Nginx 靜態處理性能比 Apache 高 3倍以上  Apache 對 PHP 支持比較簡單,Nginx 須要配合其餘後端用  Apache 的組件比 Nginx 多  如今 Nginx 纔是 Web 服務器的首選  四、最核心的區別在於apache是同步多進程模型,一個鏈接對應一個進程;nginx是異步的,多個鏈接(萬級別)能夠對應一個進程  五、nginx處理靜態文件好,耗費內存少.但無疑apache仍然是目前的主流,有不少豐富的特性.因此還須要搭配着來.固然若是能肯定nginx就適合需求,那麼使用nginx會是更經濟的方式.  apache有先天不支持多核心處理負載雞肋的缺點,建議使用nginx作前端,後端用apache。大型網站建議用nginx自代的集羣功能 六、 從我的過往的使用狀況來看,nginx的負載能力比apache高不少。最新的服務器也改用nginx了。並且nginx改完配置能-t測試一下配置有沒有問題,apache重啓的時候發現配置出錯了,會很崩潰,改的時候都會很是當心翼翼如今看有好多集羣站,前端nginx抗併發,後端apache集羣, 配合的也不錯。 七、nginx處理動態請求是雞肋,通常動態請求要apache去作,nginx只適合靜態和反向。  八、從我個人的經驗來看,nginx是很不錯的前端服務器,負載性能很好,在老奔上開nginx,用webbench模擬10000個靜態文件請求絕不吃力。apache對php等語言的支持很好,此外apache有強大的支持網路,發展時間相對nginx更久. 九、 Nginx優於apache的主要兩點: (1).Nginx自己就是一個反向代理服務器  (2).Nginx支持7層負載均衡;其餘的固然,Nginx可能會比 apache支持更高的併發,可是根據NetCraft的統計,2011年4月的統計數據,Apache依然佔有62.71%,而Nginx是 7.35%,所以總得來講,Aapche依然是大部分公司的首先,由於其成熟的技術和開發社區已經也是很是不錯的性能。  十、你對web server的需求決定你的選擇。大 部分狀況下nginx都優於APACHE,好比說靜態文件處理、PHP-CGI的支持、反向代理功能、前端Cache、維持鏈接等等。在 Apache+PHP(prefork)模式下,若是PHP處理慢或者前端壓力很大的狀況下,很容易出現Apache進程數飆升,從而拒絕服務的現象。  十一、能夠看一下nginx lua模塊:https://github.com/chaoslaw...apache比nginx多的模塊,可直接用lua實現apache是最流行的,why?大多數人懶得更新到nginx或者學新事物  十二、對於nginx,我喜歡它配置文件寫的很簡潔,正則配置讓不少事情變得簡單運行效率高,佔用資源少,代理功能強大,很適合作前端響應服務器  1三、Apache在處理動態有優點,Nginx併發性比較好,CPU內存佔用低,若是rewrite頻繁,那仍是Apache吧
相關文章
相關標籤/搜索