Tomcat負載均衡、調優核心應用進階學習筆記(三):LNMT nginx+tomcat、LAMT apache+tomcat、session會話保持、不錯的站點

LNMT nginx+tomcat

由於nginx處理請求的能力優於tomcat
有一個前端節點
兩個tomcat node節點
將三個節點設置爲host-only(主機之間能夠通訊也能夠和主機通訊,可是不能和外網通訊)php

前端節點css

//配置網卡,若是被使用了就換一個數字
ifconfig eth1 192.168.10.254/24 up

node1節點html

//配置網卡,若是被使用了就換一個數字
ifconfig eth1 192.168.10.6/24 up
//配置完以後經過前端節點 curl訪問node1節點,看看是否成功例如
//curl http://192.168.10.6:8080

node2節點前端

 

前端節點安裝nginxjava

//這裏只是一種方式,爲了學習linux記錄下,安裝nginx的形式不少,這段能夠忽略
//lfgps https://www.jb51.net/LINUXjishu/117788.html
lfgps 
ls
...
get nginx-1.4.7-1.el6.ngx.x86_64.rpm
//以上是從遠端將nginx包拿過來
//rpm https://www.jb51.net/LINUXjishu/10984.html
rpm -ivh nginx-1.4.7-1.el6.ngx.x86_64.rpm
//查看目錄
rpm -ql nginx

ps:這個目錄和我知道的不太同樣,通過查閱 https://segmentfault.com/q/1010000000141674node

vim nginx.conf
//裏面沒有定義server,可是有include
http{
	include /etc/nginx/conf.d/ *.conf
}

cd conof.d
//定義了server
vi default.conf
//啓動nginx
service nginx start

訪問 http://173.16.00.6 顯示welcom to nginxmysql

編輯server配置,定義咱們須要的locationlinux

server{
	location /{
		proxy_pass http://192.168.10.6:8080;
	}
}

訪問:http://172.16.100.6/ 就會跳轉到tomcat頁面nginx

動靜分離git

server{
	location /{
		root /web/htdocs;
		index index.jsp index.html index.htm;
	}
	//只有請求的是jsp的時候纔會去請求後端,剩下的(靜態資源)都由 上面的location提供
	//$匹配字符串的結束位置。
	location ~*\.(jsp|do)${
		proxy_pass http://192.168.10.6:8080;
	}
	location ~*\.(jpg|jpeg|gif|png|pdf|doc|rar|exe|zip|)${
		proxy_pass http://192.168.10.7:8080;
	}
}

代理多個tomcat

http{
	upstram tomcat {
		server 192.168.10.6:8080;
		server 192.168.10.7:8080;
	}
	server{
		location ~*\.(jsp|do)${
			proxy_pass http://tomcat;
		}
	}
}

LAMT apache+tomcat

基於mod_proxy

單節點

mod_proxy(http,https,ajp,注意ajp是mod_proxy之上的一個獨立的模塊)

apache環境(不詳細,自行查閱)

tar xf httpd-2.4.2
cd httpd-2.4.2

/configure --prefix=/usr/local/apache --sysconfdir=/etc/httpd --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre 
--with-apr=/usr/local/apra --with-apr-util=/usr/local/apr-util -enable-proxy --enable-proxy-http --enable-proxy-ajp
make && make install

tar xf tomcat-connectors-1.2.37-src.tar.gz
cd tomcat-connectors-1.2.37-src/native/
./configure --with-apxs=/usr/local/apache/bin/apxs
make && make install
//查看模塊
httpd -M
//輸出
proxy_module(shared)
proxy_http_module(shared)
proxy_ajp_moudle(shared)
//說明成功

在httpd.conf的全局配置段或虛擬主機中添加以下內容:

ProxyVia Off
ProxyRequest Off
<Proxy *>
	Request all granted
</Proxy>
	ProxyPass / ajp://172.16.100.1:8009/
	ProxyPassReverse /ajp://172.16.100.1:8009/
<Location />
	Requie all granted
</Location>

或讓apache跟Tomcat的http鏈接器進行整合:

ProxyVia Off
ProxyRequests Off
ProxyPass / http://172.16.100.1:8080/
ProxyPassReverse / http://172.16.100.1:8080/
<Proxy *>
	Require all grantes
</Proxy>
<Location />
	Require all granted
</Location>

關於如上 apache 指令的說明:
ProxyPreserveHost{On|Off}:若是啓用此功能,代理會將用戶請求報文中的 Host:行發送給後端的服務器,而再也不使用Proxy Pas 指定的服務器地址。若是想在反向代理機,則須要開啓此項,不然就無需打開此功能。以下圖,爲了肯定是傳給www.a.com仍是傳給www.b.org,是否把用戶請求的host守護向後轉發。
在這裏插入圖片描述
上圖中www.a.com和www.b.org是兩個虛擬主機,用戶如何知道請求哪一個虛擬主機呢?(虛擬主機中有host),在請求報文中有host守護,用戶請求哪一個,就構建到相應報文中,總的來講上面的做用就是是否將用戶請求的host轉發給後面。虛擬主機指的是相似於nginx中http{server{location}}中的server

ProxyVia[On|Off|Full|Block}用於控制在 http 首部是否使用 Via:,主要用於在多級代理中控制代理請求的流向。默認爲 0ff,即不啓用此功能:0n 表示每一個請求和響應報文均添加 via::Fu1 表示每一個 via:行都會添加當前apache 服務器的版本號信息;Block 表示每一個代理請求報文中的 via:都會被移除

ProxyRequests(on|off):是否開 apache 正向代理的功能:啓用此項時爲了代理 htp 協議必須啓用modproxyhttp 樸塊**。同時,若是爲 apache 設置了ProxyPass ,即反向代理則必須將 ProxyRequests 設置爲 Off**

ProxyPass [path] ! | url [key= value key= value key=value…]]:path其實是url,|url 的url是後端主機的url,後面的key value是代理時所使用的選項,檢查幾回,超時時間是多少等。在url上使用!表示取反,path不帶到服務器上去。將後端服務器某 URL(url) 與當前服務器的某虛擬路徑(path)關聯起來做爲提供服務的路徑,path 爲當前服務器上的某虛擬徑,url 爲後端服務器上某 URL 路徑。使用此指令時必須將 ProxyRequests 的值設置爲 0,須要注意的是,若是 path 以「/」結尾,則對應的 u1 也必須以「結尾,反之亦然
如上ProxyPass / http://172.16.100.1:8080/ /就是虛擬路徑 http://172.16.100.1:8080 就是後端的url

另外 modproxy 模塊在 httpd2.1 的版本以後支持與後端服務器的鏈接池功能,鏈接在按需建立在能夠保存至鏈接池中以備進一步使用。鏈接池大小或其它設定能夠經過在 ProxyPass 中使用 key-value 的方式定義。經常使用的 key 以下所示:
◇min:鏈接池的最小容量,此值與實際鏈接個數無關,僅表示鏈接池最小要初始化的空間大小,鏈接池表示後端所能接受用戶請求時的虛擬的默認留出的鏈接數的個數。
◇max:鏈接池的最大容量,每一個 MPM 都有本身獨立的容量;都值與 MPM 自己有關,如 Prefork 的老是爲 1,而其它的則取決於 ThreadsPerchi1d 指令的值。
◇loadfactor:用於負載均衡集羣配置中,定義對應後端服務器的權重,取值範圍爲 1-100
◇ retry:當 apache 將請求發送至後端服務器獲得錯誤響應時等待多長時間之後再重試。單位是秒鐘。(proxy模塊會自動檢測後端模塊的健康狀態,一轉發不在線,就要重試,重試之後仍是沒有響應,就將這個主機,自動從可用服務器中移除了,一旦發現上線了,還能自動添加進來。)

若是 Proxy 指定是以 ba1 ancer://開頭,即用於負彀均衡集羣時,其還能夠接受一些特殊的參效,以下所示:
◇lbmethod:apache實現負載均衡的調度方法,默認是byrequests,即基於權重將統計請求個數進行調度,bytraffic則執行基於權重的流量計數調度 ,bybusyness經過考量每一個後端服務器的當前負載進行調度
◇maxattempts放棄請求以前實現故障轉移的次效,默認爲 1,其最大值不該該大於總的節點數。
◇nofailover:取值爲On或Off,設置爲On時表示後端服務器故障時,用戶的session將損失,所以,在後端服務器不支持session複製時,可將其設置爲On
◇stickysession:調度器的 sticky session 的名字,根據 web 程序語言的不一樣,其值JSESSIONID(若是後端是tomcat或者jetty使用這個,表示使用javasessionid號保持) 或 PHPSESSIONID(php服務用phpsessionid)。
述指令除了能在 ban1 ancer://或 Proxy Pass 中設定以外,也可以使用 Proxy set 指令直接進行設置,如:

<Proxy balancer: //hotcluster>
Balancermemberhttp://wwwl.magedu.com8080loadfactor-l
alancermemberhttp://www2.magedu.com8080loadfactor=2
ProxySet lbmethod=bytraffic
</Proxy>

ProxyPassReverse:用於讓 apache 調整 HTTP 重定向響應報文中的 Location、ContentLocation 及 URI 標籤所對應的 URL,在反向代理環境中必須使用此指令避免重定向報文繞過 proxy 服務器(加入一個用戶請求的是根下的bbs,我給重定向到flow,而flow沒有卸載proxypass中,就繞過了proxy)

cd /etc/httpd/conf
vi httpd.conf
//也能夠本身在別的配置文件中設置
cd ../conf.d/
vi mod_proxy.conf
//添加
ProxyVia Off
ProxyRequests Off
ProxyPreserveHost On
//容許哪些用戶來訪問的2.2上能夠不用配置
//<Proxy *>
// Require all grantes
//</Proxy>
ProxyPass / http://192.168.10.6:8080
//避免重定向保溫繞過proxy服務器
ProxyPassReverse / http://192.168.10.6:8080
//location訪問,在2.2不用,由於默認是都訪問的。
<Location />
	Require all granted
</Location>

//檢查
httpd -t
//啓動
service httpd  start

訪問 http://172.16.100.6 會轉發到 192.168.10.6:8080的tomcat
上面沒有實現動靜分離,由於不多經過apache實現動靜分離,因此此處省略

由於apache有很大的好處是可使用ajp協議
修改上面的配置文件

ProxyPass / ajp://192.168.10.6:8009
//避免重定向保溫繞過proxy服務器
ProxyPassReverse / ajp://192.168.10.6:8009

經過 ss -tnlp 查看8009是否被監聽了

注意apache此時經過ajp協議和tomcat進行通訊,http協議不用了就能夠關掉了,關掉的好處是用戶想經過瀏覽器直接訪問tomcat訪問不到了(瀏覽器不接受ajp協議),因此若是用apache代理,最好使用ajp協議
因此ajp的好處:高效的(二進制協議)、拒絕用戶直接向tomcat發送請求。

重啓

service httpd restart

訪問 http://172.16.100.6 依然可以訪問通
配置user的配置文件,經過tomcat首頁發現也可以進入manager頁面

配置基於mod_proxy的負載均衡

保證conf.d文件下只有一個mod_proxy.conf或者mod_jk.conf,這裏是mod_proxy的因此只留下mod_proxy.conf
這裏負載均衡基於
paroxy_balancer_module模塊

◇lbmethod:apache實現負載均衡的調度方法,默認是byrequests,即基於權重將統計請求個數進行調度,bytraffic則執行基於權重的流量計數調度 ,bybusyness經過考量每一個後端服務器的當前負載進行調度

在httpd.conf的全局配置中配置以下內容:

ProxyRequests Off
//hotcluster是一個名字能夠隨便取
<proxy balancer: //lbcluster1>
//route-TomcatA 須要在tomcat也必須在Engine定義jvmroot選項
//loadfactor權重
BalancerMember ajp: //172. 16. 100. 1: 8009 loadfactor=10 route-TomcatA
BalancerMember ajp: //172.16. 100.2: 8009 loadfactor=10 route=TomcatB
//lbmethod 負載均衡的調度方
Proxy set lbmethod=bytraffic
</proxy>

<VirtualHost * 80>
ServerAdminadmin@maged.com
Servernamewww.magedu.com
//經過balancer進行反向代理,stickysession -jsessionid session會話保持
//綁定了sessionid以後就只能在訪問一個節點了
//session保持的理解在下面的mod_jk的負載均衡有
ProxyPass / balancer://lbcluster1/ stickysession=JSESSIONID
ProxyPassReverse / balancer://lbclusterl/
</VirtualHost>

訪問 http://172.16.100.6/testapp

mod_proxy的balance 模塊是有管理頁面的

vi httpd.conf
//添加:
<location /lbmanager>
//若是是這個訪問路徑就走這balancer-manager的處理器
	SetHandler balancer-manager
</location>
ProxyPass /lbmanager ! //這裏的!意思是訪問的是/lbmanager則不向後面代理

訪問:http://172.16.100.6/lbmanager
在這裏插入圖片描述

基於mod_jk(須要編譯安裝)

單節點

注意:這裏使用了lftps,具體根據實際狀況安裝(自行下載,解壓安裝)

lftps
cd Sources/tomcat-connector
get tomcat-connector-1.2.37-src.tar.gz
tar -xvf tomcat-connector-1.2.37-src.tar.gz
cd tomcat-connector-1.2.37-src

mod jk是AsF的一個項目,是一個工做於 apache端基於AP協議與 Tomcat通訊的逹接器,它是 apache的一個模塊,是AP協議的客戶端(服務端是 Tomcat的A]P鏈接器

# tar xf tomcat-connectors-1. 2. 37-src.tar.gz
#cd tomcat-connectors-1.2.37-src/native/
//並無apxs
rpm -ql httpd | grep apxs
//由於這個功能是他的開發功能,因此須要安裝,若是httpd是編譯安裝的話,這個功能默認就有了,若是是rpm安裝的,確保要裝上httpd的devel包。
yun -y install httpd-devel
rpm -ql httpd | grep apxs
// 出現 /usr/sbin/apxs ,這裏的路徑不容的話注意修改上面的配置
//apxsk可以實現獨立像apache添加第三方模塊的鉤子,任意第三方模塊,都必須告訴模塊鉤子在什麼地方,編譯完成以後,自動安裝在apache所在的目錄當中
#./configure --with-apxsk/usr/bin/install/apxs
#make && make install
//若是安裝完成會生成一個mod_jk的模塊 mod_jk.so
cd /usr/lib64/httpd/modules
//發現有mod_jk.so
ls
cd /etc/httpd/conf.d
//對mod_proxy.conf 進行重命名 mod_proxy.conf.bak

apache要使用modjk逹接器,須要在啓動時加載此逹接器模塊。爲了便於管理與modjk模塊相關的配置,這裏使用一個專門的配置文件letc/httpd/extra/httpd_jk.conf來保存相關指令及其設置。其內容以下:

#t Load the mod jk
//在配置文件中加載mod_jk.so模塊
LoadModule jk module modules/mod jk.so
//使用jk簡寫的worksfile,一個apache的子進程,mod_jk就是經過子進程來實現向後代理的,這裏給出配置文件
//這個配置文件默認不存在,須要本身定義,名稱也能夠本身定義
JkworkerSfile/etc/httpd/extra/workers.properties
//日誌文件保存的目錄
JkLogFile logs/mod_jk.log
//模塊的日誌級別
kLogLevel debug
//把哪些url的訪問轉發值tomcat,這裏表示把根目錄下的任何路徑,轉發到TomcatA
//這裏的tomcatA是上面的workers.properties中給tomcat命名的一個名稱,叫jvmroot,java虛擬機的路由名稱
JkMount /* TomcatA //狀態信息,start1另一個可以實現工做的work JkMount /status/ stat1 

除了須要使用 Loadmodule指令在 apache中裝載模塊外, mod jk還須要在 apache的主配置文件中設置其它一些指令來配置其工做屬性。如 JkWorkersFile則用於指定保存了worker相關工做屬性定義的配置文件, JkLogFile則用於指定mdjk模塊的日誌文件, JkLogLevel則可用於指定日誌的級別(info, error,debug),此外還可使用JkRequestLogFormat自定義日誌信息格式。而 JkMount(格式: JkMount< URL to match>< Tomcat worker name>)指定則用於控制URL與 Tomcat workers的對應關係。

爲了讓apache能使用/etc/httpd/extra/httpd-jk.conf配置文件中的配置信息,須要編輯/etc/httpd/httpd.conf添加以下一行:

Include/etc/httpd/extra/httpd-jk.conf

對於 apache代理來講,每個後端的 Tomcat實例中的 engine均可以視做一個 worker,而每個 worker的地址、鏈接器的端口等信息都須要在 apache端指定以便 apache能夠識別並使用這些 worker。約定俗成,配置這些信息的文件一般爲 workers.properties,其具體路徑則是使用前面介紹過的 JkwlorkersFi1e指定的,在 apache啓動時, mod jk會掃描此文件獲取每個 worker的配置信息。好比,咱們這裏使用/etehttpd/extra/workers.properties

workers. properties文件通常由商指令組成:一是 mod jk能夠鏈接的各 worker名稱列表,二是每個 worker的屬性配置信息。它們分別遵循以下使用語法

worker.list = a comma separated list of worker names
worker. <worker name> .<property> = <property value>

其中 worker.list指令能夠重複指定屢次,而 worker name則是 Tomcat中 engine組件 jvmRoute參數的值。如

worker. TomcatA host=172.16.100. 1

根據其工做機制的不一樣, worker有多種不一樣的類型,這是須要爲每一個 worker定義的一項屬性 woker,< work name>,type.常見的類型以下:
◇ajp13:此類型表示當前 worker爲一個運行着的 Tomcat實例,使用ajp1.3向後端創建鏈接的worker,因此這是一種專門實現反向代理的worker
◇lb:lb即1 oad ba1 ancing,專用於負載均衡場景中的 woker;此 worker並不真正負責處理用戶請求,而是將用戶請求調度給其它類型爲ajp13的 worker 專門負載均衡的
◇status:用戶顯示分佈式環境中各實際 worker工做狀態的特殊 worker,它不處理任何請求,也不關聯到任何實際工做的 worker實例。具體示例如誚參見後文中的配置 專門輸出狀態信息的
worker其它常見的屬性說明
◇host: Tomcat7的 worker實例所在的主機;
◇port: Tomcat7實例上AJP1.3鏈接器的端口;
◇ connection_ pool minsize:最少要保存在鏈接池中的鏈接的個數;默認爲poo1size/2;
◇ connection pool timeout:鏈接池中鏈接的超時時長;
◇ mount:由當前 worker提供的 context路徑,若是有多個則使用空格格開;此屬性能夠由Jkmount指令替代;
◇ retries:錯誤發生時的重試次數;
◇ socket timeout: mod jk等待 worker響應的時長,默認爲,即無限等待
◇ socket keepalive:是否啓用 keep alive的功能,1表示啓用,表示禁用
◇ lbfactor: worker的權重,能夠在負載均衡的應用場景中爲 worker定義此屬性;

另外,在負轂均衡模式中,專用的屬性還有:
◇ba1 ance workers:用於負載均衡模式中的各 worker的名稱列表,須要注意的是,出如今此處的 worker名稱必定不能在任何 worker.1ist屬性列表中定義過,而且 worker.list屬性中定義的 worker名字必須包含負載均衡 worker。具體示例請參見後文中的定義
◇ method:能夠設定爲R、τ或B:默認爲R,即棖挹請求的個數進行調度:T表示根據已經發送給 worker的實際流贔大小進行調度:B表示根據實際負戟狀況進行調度。
◇ sticky session:在將某請求調度至某 worker後,源於此址的全部後續請求都將直接調度至此 worker,實現將用戶 session與某 worker綁定,默認爲值爲1,即啓用此功
能。若是後端的各 worker之間支持 sesson複製,則能夠將此屬性值設爲8
根據前文中的指定,這裏使用/etc/httpd/extra/workers.properties來定義一個名爲Tomcat的worker,併爲其指定幾個屬性,文件內容以下

worker.list=TomcatA, stat1
worker.TomcatA.port=8009
worker.Tomcat.host=172. 16.100. 1
worker.TomcatA.type=ajp13
worker.TomcatA.lbfactor=1
worker statl.type=status
vi mod_jk.conf

#t Load the mod jk
//在配置文件中加載mod_jk.so模塊
LoadModule jk module modules/mod jk.so
//使用jk簡寫的worksfile,一個apache的子進程,mod_jk就是經過子進程來實現向後代理的,這裏給出配置文件
//這個配置文件默認不存在,須要本身定義,名稱也能夠本身定義
JkworkerSfile/etc/httpd/extra/workers.properties
//日誌文件保存的目錄
JkLogFile logs/mod_jk.log
//模塊的日誌級別
kLogLevel notice
//把哪些url的訪問轉發值tomcat,這裏表示把根目錄下的任何路徑,轉發到TomcatA
//這裏的tomcatA是上面的workers.properties中給tomcat命名的一個名稱,叫jvmroot,java虛擬機的路由名稱
JkMount /* TomcatA //狀態信息,start1另一個可以實現工做的work JkMount /status/ statA 
vi workers.properties

worker.list=TomcatA, statA
worker.TomcatA.type=ajp13
worker.TomcatA.port=8009
worker.Tomcat.host=192.168.10.6
worker.TomcatA.lbfactor=1
worker statA.type=status
//檢查語法
service httpd configtest
//重啓
service httpd restart

至此,一個基於mdjk模塊與後端名爲 Tomcat的 worker通訊的配置已經完成,重啓htpd服務便可生效
訪問:http://172.16.100.6 到達tomcat頁面
訪問:http://172.16.100.6/manager/status 可以到達tomcat的管理頁面

//查看日誌
tail /var/log/httpd/mod_jk.log
tail /awr/log/httpd/access_log

訪問:http://172.16.100.6/status 可以輸出狀態信息
在這裏插入圖片描述
注意:全部的信息詳細說明都在上圖的legend中

配置基於mod_jk的負載均衡

簡單來講就是多家一個work
一、爲了不用戶直接訪問後端Tomcat實例,影響負載均衡的效果,建議在Tomcat7的各實例上禁用HTTP/1.1鏈接器。
二、爲每個 Tomcat7實例的引擎添加 jvmRoute參數,並經過其爲當前引擎設置全局唯一標識符。以下所示。須要注意的是,每個實例的 jvmRoute的值均不能相同
< Engine name=」 Standalone」 defaultHost=」1 localhost」 jvmRoute=」 Tomcat」>
然後去配置a
修改/etc/httpd/extra/httpd-jk.conf爲以下內容

LoadModule
odule modules/mod jk.so
Jkworkersfile/etc/httpd/extra/workers.properties
OkLogFile logs/mod jk. log
JkLogLevel debug
JkMount / lbcluste
JkMount /status/

編輯/etc/httpd/extrayworkers.properties添加以下內容

worker.list lbcluster1, stat1
worker.TomcatA type aj
worker.Tomcat.host = 172.16.100.1
worker.TomcatA.port 8009
worker.Tomcat.bfactor =5
worker.TomcatB.type ajp13
worker.Tomcat.host 172.16 100.2
worker.TomcatB.port =8009
worker.Tomcat.lbfactor =5
worker.lbcluster1.type=1b
worker.lbvA.Sticky_session=0
//把tomcatA和tomcatB歸併到lbcluster1
worker.lbcluster1.balance_workers=tomcatA,TomcatB
worker.stat1.type-status
service httpd configtest
service httpd restart

在這裏插入圖片描述
發現有兩個節點

在兩個tomcat(注意上面是不一樣的ip)節點中作以下
演示效果,在TomcatA上某context中(如/test),提供以下頁面
index.jsp

<%@ page language="java"%>
<html>
	<head><title>TomcatA</title></head>
	<body>
		<h1><font color="red">TomcatA </font></h1>
		<table align" centre" border="1">
		<tr>
		<td>Session ID</td>
		< session setAttribute("abc","abc"):%>
		<td><%- session. getId( %></td>
		</tr>
		<tr>
		<td>Created on</td>
		<td><%- session. getCreationTime ( %></td>
		</tr>
		</table>
	</body>
</html>

演示效果,在TomcatB上某context中(如/test),提供以下頁面
index.jsp

<%@ page language="java"%>
<html>
	<head><title>TomcatB</title></head>
	<body>
		<h1><font color="blue">TomcatB </font></h1>
		<table align" centre" border="1">
		<tr>
		<td>Session ID</td>
		< session setAttribute("abc","abc"):%>
		<td><%- session. getId( %></td>
		</tr>
		<tr>
		<td>Created on</td>
		<td><%- session. getCreationTime ( %></td>
		</tr>
		</table>
	</body>
</html>

訪問http://172.16.100.6/testapp/
在這裏插入圖片描述

不斷刷新會一會tomcatA,一會tomcatB, 而且session的值是一直在發生變化的
,沒有綁定session,若是綁定了session,可能就不會負載均衡了

若是不但願一變

修改tomcat的配置文件,session是和jvmRoute屬性有關聯的

vi tomcat/conf/server.xml
//添加一個jvm路由jvmRoute="TomcatA",跟前端worker保持一致
<Engine name-"Catalina" defaultHost-"localhost" jvmRoute="TomcatA">
vi tomcat/conf/server.xml
//添加一個jvm路由jvmRoute="TomcatB",跟前端worker保持一致
<Engine name-"Catalina" defaultHost-"localhost" jvmRoute="TomcatB">

編輯/etc/httpd/extrayworkers.properties修改以下內容

worker.lbvA.Sticky_session=1

session會話保持

注意上面的mod_proxy和mod_jk負載均衡經過stack session保持session,破壞了負載均衡,該怎麼辦呢?session複製和session服務器

  1. session複製:
    tomcat支持session集羣,僅可以在小規模節點中使用的方式。
    在節點之間經過多播或廣播等方式,來實現sessoin會話的共享,每個節點在本地接受用戶會話以後,會將會話信息,經過網絡發送給其餘節點,由於每一個節點都有整個集羣中的全部會話信息,若是有三十萬個會話,意味着每一個節點上都有三十萬個會話,消耗資源,每一個節點的會話,都要複製多份給其餘的主機,帶寬佔用量很大,因此這種集羣方式,不太適用有較多節點的服務
    因此將session放在一個高興能的服務器中
  2. session服務器:
    tomcat支持將會話保存在memcached中。
    雙寫:在兩個memcached中都寫一份

在這裏插入圖片描述
memcached是保存在內存中,若是斷點了呢?因此還能夠是一些具備持久功能的服務器好比redis

Tomcat會話管理

十二、 Manager
Manger對象用於實現HP會話管理的功能, Tomcat6中有5種 Manger的實現:

  1. StandardManager
    Tomcat6的默認會話管理器,用於非集羣環境中對單個處於運行狀態的 Tomcat實例會話進行管理。當 Tomcat關閉時,這些會話相關的數據會被寫入磁盤上的一個名叫 SESSION.ser的文件,並在 Tomcat下次啓動時讀取此文件。可是斷電的狀況下是來不及的。
  2. PersistentManager
    當一個會話長時間處於空閒狀態時會被寫入到swap(磁盤)會話對象,這對於內存資源比較吃緊的應用環境來講比較有用,斷電的狀況下有用,可是那些沒來得及寫在磁盤上的仍是會丟失
  3. DeltaManager
    用於 Tomcat 集羣(複製集羣)的會話管理器,它經過將改變了會話數據同步給集羣中的其它節點實現會話複製。這種實現會將全部會話的改變同步給集羣中的每個節點,也是在集羣環境中用得最多的一種實現方式,就是上面的session複製,十分不適用於大規模節點的服務,對於中型的(三五臺)就已經很消耗資源了,兩三臺仍是能夠的。
  4. BackupManager
    用於 Tomcat-集羣的會話管理器,與 DeltaManager不一樣的是,某節點會話的改變只會同步給集羣中的另外一個而非全部節點,萬一其中一個節點發生故障,另外一還仍是有保存的,並且不會複製太多。可是若是所有斷電呢?
    注意:DeltaManager和BackupManager都是保存在內存中的,對於斷電是不可避免的
  5. SimpleTcpReplication Manage
    Tomcat4時用到的版本,過於老舊了

1三、 Stores
PersistentManager必須包含一個 Store元素以指定將會話數據存儲至何處。這一般有兩種實現方式: Filestore和] DBCStore
1四、 Resources
常常用於實如今 Context中指定須要裝載的但不在 Tomcat本地磁盤上的應用資源,如]ava類,HTM頁面,]5P文件等。
1五、cluster
專用於配置 Tomcat集羣的元素,可用於 Engine和Host容器中,在用於 Engine容器中時, Engine中的全部Host均支持集羣功能。在 Cluster元素中,須要直接定義一個 Manage
r元素,這個 Manager元素有一個其值爲og. apache. cata1 ina. ha, session. DeltaManager或org. apache, catalina.ha, session
BackupManager的c1 assName屬性。同時, Cluster中還須要分別定義一個 Channel和 ClusterListener元素
15.一、 Channel
用於cluster中給集羣中同一組中的節點定義通訊「信道」。 Channel中須要至少定以Membership(成員關係管理)、 Receiver(接收管理)和 Sender(發送管理)三個元素,此外還有一個可選元素 Interceptor(檢查會話信息)。每一個節點能夠有多個虛擬主機,節點集羣中都是相同的,因此每一個節點的虛擬主機a就是一組,虛擬主機a和虛擬主機b(這裏的a b只是舉個栗子)都是互不干擾的,而channel就是用來節點之間通訊的。
15.二、 Membership
用於 Channel中配置同一通訊信道上節點集羣組中的成員狀況,即監控加入當前集羣組中的節點並在各節點間傳遞心跳信息,並且能夠在接收不到某成員的心跳信息時將
從集羣節點中移除。 Tomcat6中 Membership的實現是org. apache. catalina, tribes, membership. Mcastservice。
15.三、 Sender
用於 Channe1中配置「複製信息」的發送器,實現發送須要同步給其它節點的數據至集羣中的其它節點。發送器不須要屬性的定義,但能夠在其內部定義一個 Transport元素
15.4 Transpor
用於 Sender內部,配置數據如何發送至集羣中的其它節點。 Tomcat6有兩種 Transport的實現

  1. PooledMultiSender
    基於]ava阻塞式IO,能夠將一次將多個信息併發發送至其它節點,但一次只能傳送給一個節點
    2 )PooledParallelSener
    基於]ava非阻塞式I0,即NIO,能夠一次發送多個信息至一個或多個節點。

15.5 Receiver
用於 Channe1定義某節點如何從其它節點的 Sender接收復制數據, Tomcat6中實現的接收方式有兩種 BioReceiver和 NioReceiver

標準會話管理器和持久會話管理器
標準會話管理器( StandardManager):

<Manager className="org. apache. catalina. session. StandardManager
//最大保持時間
maxInactiveInterval=7200"/>

默認保存於$ CATALINA HOME/rk/Cata1ina/< hostname》/< webapp-name>/下的 SESSIONS,ser文件中。
maxActiveSessions:最多容許的活動會話數量,默認爲-1,表示不限制;
axInactivelnterya1:非活動的會話超時時長,默認爲60s;
athname:會話文件的保存目錄;

持久會話管理器( PersistentManager)
將會話數據保存至持久存儲中,而且能在服務器意外停止後從新啓動時從新加載這些會話信息。持久會話管理器支持將會話保存至文件存儲(Fi1 eStore)
或JDBC存儲( JDBCStore)中
保存至文件中的示例

<Manager className"org. apache. catalina. session. PersistentManage
//重啓的時候要不要保存到磁盤上去
saveOnRestart=true">
<Store className="org. apache. catalina. session. Filestore
//保存的目錄
directory=/data/tomcat-sessions"/>
</Manager>

每一個用戶的會話會被保存至 directory指定的目錄中的文件中,文件名爲< session id, session,並經過後臺線程每隔一段時間(
checkInterva1參數定義,默認爲60秒)檢查一次超時會話
保存至JDBCStorel中的示例

<Manager className="org. apache. catalina. session. PersistentManager
saveonRestart=true>
<Store className="org. apache. catalina. sessionlJDBCStore
driver Name="com. mysql jdbc Driver
connectionURL-"jdbc: mysql: //localhost: 3306/mydb?user=jb; pas sword=pw"/>

負載均衡,且實現會話綁定要注意給每一個 tomcat實例的 egine容器一個 jvmRoute屬性!此名稱要跟前端調度模塊使用名稱保持一致!
另外,在mod_proy實現負載均衡的會話綁定時,還要使用 sticksession=JSESSIONID(字符要大寫)!

須要在Engine或者host容器中添加一個cluster的組件,明確打開session集羣(tomcat會話集羣)

session複製

Tomcat Cluster配置:

注意 Membership和 Receiver

若是對總體的Engine作cluster,就放在nginx中,若是隻對某一個主機作集羣,就放在某個特定的host中

//所使用的類SimpleTcpCluster
<Cluster CyassName="org.apache.catalina.ha.tcp.SimpleTcpCluster"
//指明會話管理器爲deltamanager
	<Manager className="org.apache.catalina.ha.session.DeltaManager"
	expireSessionsonShutdown="false"
	notifyListenersOnReplication="true"/>
	<Channel className="org.apache.catalina.tribes.group.Group.Channel">
	//使用McastService來實現,多播的方式
	<Membership className="org.apache.catalina.tribes.membership.McastService"
		//多播的地址
		address="228.0.0.4"
		//端口
		port="45564"
		//每隔多久向外播放一次本身的心跳信息 ms
		frequency="500"
		//若是多久沒有得到對方的心跳,就將對方設置爲不可用的 ms
		dropTime="3000"/>
	//接受其餘人的心跳會話信息,NioReceiver,高效的網絡通訊方式
	<Receiver className"org. apache. catalina. tribes. transport nio. NioReceiver"
		//跟其餘主機傳遞心跳和會話機制使用的外部的ip地址,必定不能使127.0.0.1
		//若是隻有一個網卡,並且只有一個跟其餘主機通訊的地址,auto便可
		//若是有多塊網卡,一個面向前端的主機,另一個專門用來實現心跳信息傳遞和繪畫信息傳遞。
		//那麼這裏就須要寫成心跳傳遞的網卡。
		address="auto"
		//端口
		port="4000"
		//自動綁定,咱們一次性能夠接收多少個
		autoBind="100"
		//挑選的超時時間,receiver進來不少會話和心跳信息,要判斷哪一個能夠哪一個不可用
		selectortimeout= "5000"
		//最大線程數
		maxThread="6"/>
	<Sender  className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
		<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
	</Sender>
	<Interceptor className="org.apache.catalina.tribes. group.interceptors.TcpFailure.Detector"/>
	<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor "/
	/channel>
	//這兩個保持默認就行
	<Valve className"org.apache.catalina.ha.tcp.Replication.Valve"
	filter=""/>
	<Valve className="org.apache.catalina.ha.session. vmRouteBindervalve"/>
	<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
		tempDir="/tmp/war-temp/"
		deployDir="/tmp/war-deploy/"
		watchDira"/tmp/war-listen/"
		watchEnabled="false"/>
//監聽器,jvm中各個節點之間一些內部的信息傳遞的工具
	<ClusterListener className="org. apache. catalina.ha.session.JvmRouteSessionIDBinderListener"/>
	<ClusterListener className"org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

172.16.100.6 172.16.100.7 兩個主機

cd tomcat/conf
//備份server.xml
cp server.xml server.xml.bak
vi server.xml
//找到Engine,在Engine內部粘貼就能夠
<Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatB">
//注意可能粘貼的時候格式亂了,這個時候能夠選擇用 nano(和vim做用差很少)

//修改membership中的 address="228.101.60.4" (舉個栗子),注意兩個tomcat使用同樣的
//reciver的地址使用auto就能夠,其餘的都不用改

把相同的配置複製到172.16.100.7節點上
修改

//修改成TomcatB
<Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatB">
//多播地址保持一致,不用修改,reciver還用auto便可

注意 這個配置tomcat六、七、8多是不同的,最好到tomcat官網查看詳細文檔

例如在tomcat7中
在這裏插入圖片描述
確保web.xml中有distributable

若是WEB-INF目錄下沒有,會使用tomcat/conf目錄下默認的web.xml
兩個節點都要添加

vi web.xml
//在和<servlet>同級的地方加上
<distributable/>

可能會報錯 invalid argument

命令行執行

//添加一個路由,目標網絡228.0.0.4 實際地址格式255.255.255.255
//route文章https://blog.csdn.net/u011857683/article/details/83795435
route add -net 228.0.0.4 netmask 255.255.255.255 dev eth0

發現有waitFormembers等字樣,在等待另外一個節點,啓動另外一個,再查看日持,發現已經開始傳遞了
訪問 http://172.16.100.6/testapp
在這裏插入圖片描述
在這裏插入圖片描述
session會話信息是不變的


總結:構建 DeltaManager集羣步驟:
一、在各節點的server.xml的engine後host容器添加如上內容:注意修改membership組件中的address=「xxx.x.xx.x」 建議修改reciver中的address爲本機可以傳遞心跳信息的地址
二、在各節點爲使用的組播地址添加組播路由 格式:
route add -net $MACAST_ADDRESS netmask 255.255.255.255 dev eth0
三、在相應應用程序的web.xml中添加


這種方式只適用於小規模節點的項目。

session服務器

一個開源項目(支持memcached和couchbase)
Msm:http://code.googlecom/p/memcached-session-manager/
http://repol.mavenorg/maven2/de/javakaffee/msm/
能夠谷歌搜索關鍵字 tomcat memcached session等
支持tomcat六、七、8 點擊網站中的wiki有配置詳細說明
在這裏插入圖片描述
在這裏插入圖片描述
配置tomat1默認優先使用memcached2,經過相似雙寫機制,會話也保存在memcached1中,若是memcached2發生故障,就會使用memcached1的。

須要將jar包放在tomcat目錄的相應目錄下
在這裏插入圖片描述
放在tomcat的lib目錄下
此外還須要幾個文檔,這幾個文檔是爲了將會話序列化的,由於要將會話保存在memcached中,數據必須是可序列化的,即上圖第二個方框的內容也放入到lib目錄下

定義在context或者host(若是沒有context 的狀況下)中

具體內容查看官方網站

<Context>
	<Manager Name="de.avakaffee.web.msm.MemcachedBackupSessionManager"
	//定義兩個節點的服務器地址和端口自
	memcachedNodes="nl: host1. yourdomain com: 11211, n2: host2. yourdomain com:11211"
	//備用節點n1
	failoverNodes="n1"
	//對於那些不作session緩存,圖片等會致使session緩存命中率低下 
	reqstUriIgnorePattern=". \. (ico|pngl|gif|jpg|css|js)$"
	//序列化工具,這裏使用哪一個,上面圖中的jar文件就應該放在lib目錄中
	transcoderFactoryclass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
	/>
</Context>

附 若是是php的話,如何將會話保存到memcached中

前提:
一、配置各php支持使用 memcache
二、安裝配置好 memcached服務器,這裏假設其地址爲172.16.208.11,端口爲11211:
、配置php將會話保存至 memcached中
編輯php.ini文件,確保以下兩個參數的值分別以下所示:

session.save_handler=memcache
//persistent基於持久鏈接方式 weight權重爲1 timeout超時時間 interval重試時間點
session.save_path="tcp://172 16.200. 11: 11211?persistent=1&weight=1&timeout=1&retry_interval=15

測試
新建php頁面 setsess,php,爲客戶端設置啓用 session

<?php
sessioni_start();
if (!iss($_SESSION['www.MageEdu.com'])){
	$_SESSION['www.MageEdu.com']=time();
}
print $_SESSION['www.MageEdu.com'];
print "<br><br>";
print "Session ID: " . session_id();
?>

新建php頁面 showsess,php,獲取當前用戶的會話ID

<?php
session_start();
Memcache obj = new Memcache;
Memcache_ obj->connect('172 16.200. 11', 11211);
Smysess=session_id();
var_dump($Memcache_obj->get($mysess));
Memcache_obj->close();

不錯的站點(外面)推薦

www.sourceforge.org
www.slideshare.net
www.wordpress.com
http://codegoogle.com
http://www.github.com

相關文章
相關標籤/搜索