Ngnix + Tomcat負載均衡架構

1、nginxjavascript

Nginx (發音同 engine x)是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,並在一個BSD-like 協議下發行。  其特色是佔有內存少,併發能力強,事實上nginx的併發能力確實在同類型的網頁伺服器中表現較好。目前中國大陸使用nginx網站用戶有:新浪、網易、 騰訊,另外知名的微網誌Plurk也使用nginx。php

廢話很少說, 先上圖...css

2、Tomcathtml

tomcat服務器就不用多說了吧。咱們能夠準備二、3個tomcat服務器進行測試。廢話很少說,準備環境走起...前端

3、環境準備 java

一、 jdk 1.8.0_102node

二、nginx 1.12.0(在官網上下一個解壓就行,官網:http://nginx.org/);mysql

三、2個或多個tomcat 6.x 7.x 8.x 9.x 均可以(好比我準備的是3個如出一轍的8.x版本,只是配置文件改了而已,一會會詳細怎麼改 ,官網:http://tomcat.apache.org/)linux

4、nginx配置文件nginx

路徑:\nginx-1.12.0\conf\nginx.conf

配置以下:



 [html]
  view plain  copy
 
  1. #Nginx所用用戶和組,window下不指定
    #user  niumd niumd;
    #工做的子進程數量(一般等於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  2048;
    }
     
    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  off;
     
    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  75 20;
    #include    gzip.conf;
     
    #負載均衡配置
    upstream localhost {
    #根據ip計算將請求分配各那個後端tomcat,許多人誤認爲能夠解決session問題,其實並不能。
    #同一機器在多網狀況下,路由切換,ip可能不一樣
    #ip_hash;
    #upstream的負載均衡,weight是權重,能夠根據機器配置定義權重。weigth參數表示權值,權值越高被分配到的概率越大。
    ip_hash;
    server localhost:18081;
    server localhost:18082;
    server localhost:18083;
     
    #nginx的upstream目前支持4種方式的分配
            #一、輪詢(默認)
            #每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除。
            #二、weight
            #指定輪詢概率,weight和訪問比率成正比,用於後端服務器性能不均的狀況。
            #例如:
            #upstream bakend {
            #    server 192.168.0.14 weight=10;
            #    server 192.168.0.15 weight=10;
            #}
            #二、ip_hash
            #每一個請求按訪問ip的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決session的問題。
            #例如:
            #upstream bakend {
            #    ip_hash;
            #    server 192.168.0.14:88;
            #    server 192.168.0.15:80;
            #}
            #三、fair(第三方)
            #按後端服務器的響應時間來分配請求,響應時間短的優先分配。
            #upstream backend {
            #    server server1;
            #    server server2;
            #    fair;
            #}
            #四、url_hash(第三方)
            #按訪問url的hash結果來分配請求,使每一個url定向到同一個後端服務器,後端服務器爲緩存時比較有效。
            #例:在upstream中加入hash語句,server語句中不能寫入weight等其餘的參數,hash_method是使用的hash算法
            #upstream backend {
            #    server squid1:3128;
            #    server squid2:3128;
            #    hash $request_uri;
            #    hash_method crc32;
            #}
     
            #tips:
            #upstream bakend{#定義負載均衡設備的Ip及設備狀態}{
            #    ip_hash;
            #    server 127.0.0.1:9090 down;
            #    server 127.0.0.1:8080 weight=2;
            #    server 127.0.0.1:6060;
            #    server 127.0.0.1:7070 backup;
            #}
            #在須要使用負載均衡的server中增長 proxy_pass http://bakend/;
     
            #每一個設備的狀態設置爲:
            #1.down表示單前的server暫時不參與負載
            #2.weight爲weight越大,負載的權重就越大。
            #3.max_fails:容許請求失敗的次數默認爲1.當超過最大次數時,返回proxy_next_upstream模塊定義的錯誤
            #4.fail_timeout:max_fails次失敗後,暫停的時間。
            #5.backup: 其它全部的非backup機器down或者忙的時候,請求backup機器。因此這臺機器壓力會最輕。
     
            #nginx支持同時設置多組的負載均衡,用來給不用的server來使用。
            #client_body_in_file_only設置爲On 能夠講client post過來的數據記錄到文件中用來作debug
            #client_body_temp_path設置記錄文件的目錄 能夠設置最多3層目錄
            #location對URL進行匹配.能夠進行重定向或者進行新的代理 負載均衡
    }
    server {
    listen       80;
    server_name  localhost;
    location / {
    proxy_connect_timeout   3;
    proxy_send_timeout      30;
    proxy_read_timeout      30;
    proxy_pass http://localhost;
    }
     
    #css|js|ico|gif|jpg|jpeg|png|txt|html|htm|xml|swf|wav這些都是靜態文件,但應分辨,js、css可能常常會變,過時時間應小一些,圖片、html基本不變,過時時間能夠設長一些
            location ~* ^.+\.(ico|gif|jpg|jpeg|png|html|htm)$ {
                root         html;
                access_log   logs/access.log;
                expires      -1s;
            }
     
    gzip on;
            gzip_comp_level 7;
            gzip_min_length  1100; #須要壓縮的最小長度
            gzip_buffers    4 8k;
            gzip_types      text/plain application/javascript text/css text/xml application/x-httpd-php; #指定須要壓縮的文件類型
            output_buffers  1 32k;
            postpone_output  1460;
     
            #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;
            }
    }
    }
  2.  

 

5、Tomcat配置文件

apache-tomcat-8.5.16.1\conf\server.xml

... 

 <Server port="18006" shutdown="SHUTDOWN">

...

<Connector port="18081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 

...

<Connector port="18009" protocol="AJP/1.3" redirectPort="8443" /> 

 ...

 

 apache-tomcat-8.5.16.2\conf\server.xml

 ...

<Server port="18007" shutdown="SHUTDOWN"> 

 ...

<Connector port="18082" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 

...

<Connector port="28009" protocol="AJP/1.3" redirectPort="8443" /> 

...

 

apache-tomcat-8.5.16.3\conf\server.xml

 ...

<Server port="18008" shutdown="SHUTDOWN"> 

...

<Connector port="18083" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> 

 ...

 <Connector port="38009" protocol="AJP/1.3" redirectPort="8443" />

...

 

OK,須要配置的就配置好了,咱們再作一件事,咱們選用歡迎頁,爲了區別歡迎頁,咱們修改一下index.jsp頁面,apache-tomcat-8.5.16.1\webapps\ROOT\index.jsp,隨意區分一下就好。而後分別啓動nginx和三個tomcat(nginx.exe、startup.bat)

 

 

 

(由於編譯器不讓我放圖片,放一個網上找的,真的日狗,在網頁上覆製圖片粘貼能夠,更日血的是,本身寫一個簡單靜態頁面加載截圖不能複製圖片粘貼。。。)

 

由於咱們在上面說了,改tomcat的歡迎頁,因此每次刷新的時候呢,三個歡迎頁就會輪流替換,在實際項目中也是同樣的原理,可是有一點不足,session共享問題,這麼作session是不共享的。也是不知足高併發,這只是一個演示的demo。

 

 

怎樣實現session共享呢?
 
 

 查了一些資料,看了一些別人寫的文檔,總結以下,實現nginx session的共享

 

服務器有多臺,用nginx作負載均衡,這樣同一個IP訪問同一個頁面會被分配到不一樣的服務器上,若是session不一樣步的話,就會出現不少問題,好比說最多見的登陸狀態,下面提供了幾種方式來解決session共享的問題:

 

一、不使用session,換用cookie session是存放在服務器端的,cookie是存放在客戶端的,咱們能夠把用戶訪問頁面產生的session放到cookie裏面,就是以cookie爲中轉站。你訪問web服務器A,產生了session而後把它放到cookie裏面,當你的請求被分配到B服務器時,服務器B先判斷服務器有沒有這個session,若是沒有,再去看看客戶端的cookie裏面有沒有這個session,若是也沒有,說明session真的不存,若是cookie裏面有,就把cookie裏面的sessoin同步到服務器B,這樣就能夠實現session的同步了。

說明:這種方法實現起來簡單,方便,也不會加大數據庫的負擔,可是若是客戶端把cookie禁掉了的話,那麼session就無從同步了,這樣會給網站帶來損失;cookie的安全性不高,雖然它已經加了密,可是仍是能夠僞造的。

 

二、session存在數據庫(MySQL等)中 後臺能夠配置將session保存在數據庫中,這種方法是把存放session的表和其餘數據庫表放在一塊兒,若是mysql也作了集羣了話,每一個mysql節點都要有這張表,而且這張session表的數據表要實時同步。

說明:用數據庫來同步session,會加大數據庫的IO,增長數據庫的負擔。並且數據庫讀寫速度較慢,不利於session的適時同步。

 

三、session存在memcache或者Redis中 memcache能夠作分佈式,配置文件中設置存儲方式爲memcache,這樣會創建一個session集羣,將session數據存儲在memcache中。

說明:以這種方式來同步session,不會加大數據庫的負擔,而且安全性比用cookie大大的提升,把session放到內存裏面,比從文件中讀取要快不少。可是memcache把內存分紅不少種規格的存儲塊,有塊就有大小,這種方式也就決定了,memcache不能徹底利用內存,會產生內存碎片,若是存儲塊不足,還會產生內存溢出。

 

四、nginx中的ip_hash技術可以將某個ip的請求定向到同一臺後端,這樣一來這個ip下的某個客戶端和某個後端就能創建起穩固的session,ip_hash是在upstream配置中定義的:

[html]  view plain  copy
 
  1. upstream localhost  
  2.     {   
  3.              server localhost:18006;   
  4.              server localhost:18007;  
  5.              ip_hash;  
  6.     }  
  7.     server  
  8.     {  
  9.              listen 80;  
  10.              location /  
  11.              {  
  12.                      proxy_pass  
  13.                     localhost;  
  14.              }  
  15.  }  

 

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分流,剩下的走其它後端去。

 

五、upstream_hash 爲了解決ip_hash的一些問題,可使用upstream_hash這個第三方模塊,這個模塊多數狀況下是用做url_hash的,可是並不妨礙將它用來作session共享。它的原理是這樣的:瀏覽器A去訪問nginx,nginx根據IP的hash去訪問某一個服務器,至此,之後的每次訪問都會是這個服務器在運做,因此纔有的session同步,瀏覽器B、C、D...也去訪問nginx,nginx還會根據B、C、D的IP_hash訪問的服務器可能仍是原來的服務器也有多是新的服務器。它們以後的訪問都會是各自第一次訪問你的服務器,只有服務器崩了,纔會去別的服務器,從而實現session共享。

 

 

 

 
至此window下nginx+tomcat負載均衡配置結束。
相關文章
相關標籤/搜索