一、Hello world
(1)、前期環境準備
準備兩個解壓版tomcat,如何同時啟動兩個tomcat,請看我的另一篇文章《一臺機器同時啟動多個tomcat》。
(2)、nginx官網下載解壓版nginx。
(3)、創建一個簡單的web項目。為了直觀的區分訪問的哪個tomcat,在頁面寫上標記8081、8082。
(4)、分別部署到對應的tomcat下。如圖:
2、配置nginx
進入nginx-1.10.1conf路徑,修改配置文件nginx.conf。
1、配置服務器組,在http{}節點之間添加upstream配置。(注意不要寫localhost,不然訪問速度會很慢)
upstream nginxDemo {
server 127.0.0.1:8081; #服務器地址1
server 127.0.0.1:8082; #服務器地址2
}
2、修改nginx監聽的端口號80,改為8080。
server {
listen 8080;
......
}
3、在location{}中,利用proxy_pass配置反向代理地址;此處“http://”不能少,後面的地址要和第一步upstream定義的名稱保持一致。
location / {
root html;
index index.html index.htm;
proxy_pass http://nginxDemo; #配置方向代理地址
}
如下圖:
3、啟動nginx和tomcat,訪問
我是Windows系統,所以直接在nginx-1.10.1目錄下雙擊nginx.exe即可。
可在任務管理器中查看
最後在瀏覽器輸入地址:http://localhost:8080/nginxDemo/index.jsp,每次訪問就會輪流訪問tomcat了(如果F5刷新不管用,建議試試鼠標指針放到地址欄,點擊Enter鍵)。
到這裡,一個非常簡單的負載均衡就配置完成了,是不是很簡單呢,O(∩_∩)O哈哈~
二、nginx負載均衡策略
1、輪詢(默認)
每個web請求按時間順序逐一分配到不同的後端服務器,如果後端服務器down掉,能自動剔除。
upstream nginxDemo {
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
2、最少鏈接
web請求會被轉發到連接數最少的服務器上。
upstream nginxDemo {
least_conn;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
3、weight 權重
指定輪詢幾率,weight和訪問比率成正比,用於後端服務器性能不均的情況,weight默認是1。
#服務器A和服務器B的訪問比例為:2-1;比如有3個請求,前兩個會訪問A,三個訪問B,其它規則和輪詢一樣。
upstream nginxDemo {
server 127.0.0.1:8081 weight=2; #服務器A
server 127.0.0.1:8082; #服務器B
}
4、ip_hash
每個請求按訪問ip的hash值分配,這樣同一客戶端連續的Web請求都會被分發到同一服務器進行處理,可以解決session的問題。當後臺服務器宕機時,會自動跳轉到其它服務器。
upstream nginxDemo {
ip_hash;
server 127.0.0.1:8081 weight=2; #服務器A
server 127.0.0.1:8082; #服務器B
}
基於weight的負載均衡和基於ip_hash的負載均衡可以組合在一起使用。
5、url_hash(第三方)
url_hash是nginx的第三方模塊,nginx本身不支持,需要打補丁。
nginx按訪問url的hash結果來分配請求,使每個url定向到同一個後端服務器,後端服務器為緩存服務器、文件服務器、靜態服務器時比較有效。缺點是當後端服務器宕機的時候,url_hash不會自動跳轉的其他緩存服務器,而是返回給用戶一個503錯誤。
upstream nginxDemo {
server 127.0.0.1:8081; #服務器A
server 127.0.0.1:8082; #服務器B
hash $request_url;
}
6、fair(第三方)
按後端服務器的響應時間來分配請求,響應時間短的優先分配。
upstream nginxDemo {
server 127.0.0.1:8081; #服務器A
server 127.0.0.1:8082; #服務器B
fair;
}
三、集群/分佈式環境下session處理策略
因為很多朋友提到session的管理問題,所以接下來決定寫一下在集群/分佈式環境下session處理策略。
1、為什麼要處理session?
這個問題想必大多數朋友都知道,在搭建完集群或者分佈式環境之後,如果不做任何處理的話,網站將頻繁的出現用戶未登錄的現象。比如:集群中有A、B兩臺服務器,用戶第一次訪問網站時,Nginx將用戶請求分發到A服務器,這時A服務器給用戶創建了一個Session,當用戶第二次訪問網站時,假設Nginx將用戶請求分發到了B服務器上,而這時B服務器並不存在用戶的Session,所以就會出現用戶未登錄的情況,這對用戶來說是不可忍受的。
所以我們在搭建集群/分佈式環境之後,必須考慮的一個問題就是用戶訪問產生的session如何處理,即session的共享機制。
我們將處理Session的方式大致分為三種:Session保持(也有人叫黏性Session)、Session複製、Session共享。
2、Session保持(或者叫黏性Session)
Session保持(會話保持)就是將用戶鎖定到某一個服務器上。比如上面說的例子,用戶第一次請求時,負載均衡器(Nginx)將用戶的請求分發到了A服務器上,如果負載均衡器(Nginx)設置了Session保持的話,那麼用戶以後的每次請求都會分發到A服務器上,相當於把用戶和A服務器粘到了一塊,這就是Session保持的原理。Session保持方案在所有的負載均衡器都有對應的實現。而且這是在負載均衡這一層就可以解決Session問題。
優點:非常簡單,不需要對session做任何處理。
缺點:1、負責不均衡了:由於使用了Session保持,很顯然就無法保證負載的均衡。
2、缺乏容錯性:如果後端某臺服務器宕機,那麼這臺服務器的Session丟失,被分配到這臺服務請求的用戶還是需要重新登錄,所以沒有徹底的解決問題。
適用場景:發生故障對客戶產生的影響較小;服務器發生故障是低概率事件。
實現方式:以Nginx為例,在upstream模塊配置ip_hash屬性即可實現粘性Session,具體可以參考2.4章節。
3、Session複製
針對Session保持的容錯性缺點,我們可以在所有服務器上都保存一份用戶的Session信息。這種將每個服務器中的Session信息複製到其它服務器上的處理辦法就稱為會話複製。當任何一臺服務器上的session發生改變時,該節點會把session的所有內容序列化,然後廣播給所有其它節點,不管其他服務器需不需要session,以此來保證Session同步。
優點:可容錯,各個服務器間的Session能夠實時響應。
缺點:將session廣播同步給成員,會對網絡負荷造成一定壓力;
如果session量大的話可能會造成網絡堵塞,拖慢服務器性能,特別是session保存的對象較大,並且對象變化較快時;從而也使應用水平擴展受到限制;
session內容的序列化,也消耗了系統的性能;
實現方式侷限,必須在同一種組件之間實現(比如用的tomcat,則必須全部用tomcat)。
實現方式:tomcat本身已支持該功能,可以參考官方文檔。官網介紹已經很詳細,這裡不再介紹。而且這種處理方式,在大的集群中也不推薦生產環境使用。
tomcat的會話複製分為兩種:
全局複製(DeltaManager):複製會話中的變更信息到集群中的所有其他節點。
非全局複製(BackupManager):它會把Session複製給一個指定的備份節點。
4、Session共享
Session共享的實現方式有很多種,比如memcached、Redis、DB等;核心思想是修改tomcat的session存儲機制,使之能夠把session序列化,然後存放到memcached中。
使用Session共享可以分為兩種機制:
黏性Session處理方式:
Tomcat本地Session為主Session,Memcached 中的Session為備Session。用戶訪問時首先在tomcat中創建session,然後將session複製一份放到對應的memcahed上。memcache只起備份作用,讀寫都在tomcat上。當某一個tomcat掛掉後,集群將用戶的訪問定位到備tomcat上,然後根據cookie中存儲的SessionId找session,找不到時,再去相應的memcached上取session,找到之後將其複製到備tomcat上。
非黏性Session處理方式:
Tomcat本地Session為中轉Session,Memcached為主備Session。創建的session都往memcached上寫,讀取都從memcached讀取,tomcat本身不存儲session。
實現方式1:Tomcat+Nginx+MSM+memcached
a、相關jar包放到tomcat/lib目錄下:
Java memcached客戶端:spymemcached.jar
MSM:1. 核心包,memcached-session-manager-{version}.jar
2. Tomcat版本對應的jar包:memcached-session-manager-tc{tomcat-version}-{version}.jar
序列化工具包:可選kryo(據說效率比較快),javolution,xstream等,不設置時使用jdk默認序列化。
b、Tomcat文件tomcat\\conf\\context.xml添加:
黏性處理方式:
<manager>
memcachedNodes="n1:192.168.2.61:11211,n2:192.168.2.66:11211"
requestUriIgnorePattern=".*\\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
非黏性處理方式:
<manager>
memcachedNodes="n1:192.168.2.61:11211,n2:192.168.2.66:11211"
sticky="false"
lockingMode="auto"
requestUriIgnorePattern=".*\\.(ico|png|gif|jpg|css|js)$"
sessionBackupAsync= "false"
sessionBackupTimeout= "100"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
/<manager>/<manager>閱讀更多 IT生涯 的文章