- 會話保持
- Tomcat Cluster
- Tomcat實現(xiàn)會話粘滯
- Tomcat實現(xiàn)會話集群
- Tomcat實現(xiàn)會話服務(wù)器
一那婉、會話保持
三種實現(xiàn)方式:
- session sticky:會話粘滯
- source_ip:源IP地址綁定
nginx: ip_hash
haproxy: source
lvs: sh - cookie:cookie綁定
nginx:hash
haproxy: cookie
- source_ip:源IP地址綁定
- session cluster:會話集群
delta session manager - session server:會話服務(wù)器
redis(store), memcached(cache)
二逢享、Tomcat Cluster:Tomcat 集群
httpd或nginx作為調(diào)度器房午,三種實現(xiàn)方式:
- nginx + tomcat cluster
- httpd + tomcat cluster
httpd: mod_proxy, mod_proxy_http, mod_proxy_balancer
tomcat cluster: http connector - httpd + tomcat cluster
httpd: mod_proxy, mod_proxy_ajp, mod_proxy_balancer
tomcat cluster: ajp connector
(一)nginx作為調(diào)度器
(1)配置tomcat cluster
ntpdate 172.18.0.1
// 分別將兩臺主機(jī)命名為node1.hellopeiyang.com和node2.hellopeiyang.com
hostnamectl set-hostname node1.hellopeiyang.com
hostnamectl set-hostname node2.hellopeiyang.com
yum install java-1.8.0-openjdk-devel tomcat tomcat-webapps tomcat-admin-webapps tomcat-docs-webapp tomcat-webapps
systemctl start tomcat
mkdir -pv /usr/share/tomcat/webapps/myapp/WEB-INF
vim /usr/share/tomcat/webapps/myapp/index.jsp
// node1主機(jī)上的內(nèi)容
<%@ page language="java" %>
<html>
<head><title>TomcatA</title></head>
<body>
<h1><font color="red">TomcatA.magedu.com</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("magedu.com","magedu.com"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
// node2主機(jī)上的內(nèi)容
<%@ page language="java" %>
<html>
<head><title>TomcatB</title></head>
<body>
<h1><font color="blue">TomcatB.magedu.com</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("magedu.com","magedu.com"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
分別測試node1和node2的tomcat服務(wù)说墨,成功運行
(2)配置nginx調(diào)度器
ntpdate 172.18.0.1
yum install nginx
systemctl start nginx
hostnamectl set-hostname www.hellopeiyang.com
vim /etc/nginx/nginx.conf
upstream tcsrvs {
server 192.168.136.130:8080;
server 192.168.136.131:8080;
}
server {
listen 80 default_server;
server_name www.hellopeiyang.com;
root /usr/share/nginx/html;
location / {
proxy_pass http://tcsrvs;
}
}
nginx -t
nginx -s reload
登錄nginx服務(wù)器的文本服務(wù),成功調(diào)度
(二)httpd作為調(diào)度器,通過http協(xié)議
-
BalancerMember:定義后端服務(wù)器
語法:BalancerMember [balancerurl] url [key=value [key=value ...]]
status:狀態(tài)
D:服務(wù)器不可用
H:服務(wù)器只有在其他服務(wù)器都不可用時才提供服務(wù)loadfactor:負(fù)載因子,即權(quán)重
lbmethod:調(diào)度算法
byrequests:默認(rèn)舔庶,按照設(shè)置的權(quán)重調(diào)度,相當(dāng)于wrr
bytraffic:按照流量調(diào)度
bybusyness:按照存在的連接調(diào)度陈醒,相當(dāng)于lc-
實現(xiàn)httpd通過http協(xié)議調(diào)度
- tomcat cluster 保持不變惕橙,現(xiàn)在配置httpd服務(wù)
ntpdate 172.18.0.1
yum install httpd
vim /etc/httpd/conf.d/httpd-tomcat.conf
<proxy balancer://tcsrvs>
BalancerMember http://192.168.136.130:8080
BalancerMember http://192.168.136.131:8080
ProxySet lbmethod=byrequests
</Proxy>
<VirtualHost *:80>
ServerName www.hellopeiyang.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://tcsrvs/
ProxyPassReverse / balancer://tcsrvs/
<Location />
Require all granted
</Location>
</VirtualHost>
systemctl start httpd
測試成功進(jìn)行調(diào)度
(三)httpd作為調(diào)度器,通過ajp協(xié)議
- tomcat cluster 保持不變孵延,現(xiàn)在配置httpd服務(wù)
mv /etc/httpd/conf.d/httpd-tomcat.conf /etc/httpd/conf.d/httpd-tomcat.conf.bak
vim /etc/httpd/conf.d/ajp-tomcat.conf
<proxy balancer://tcsrvs>
BalancerMember ajp://192.168.136.130:8009 loadfactor=2
BalancerMember ajp://192.168.136.131:8009 loadfactor=1
ProxySet lbmethod=byrequests
</Proxy>
<VirtualHost *:80>
ServerName www.hellopeiyang.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://tcsrvs/
ProxyPassReverse / balancer://tcsrvs/
<Location />
Require all granted
</Location>
</VirtualHost>
httpd -t
systemctl restart httpd
測試成功按照權(quán)重進(jìn)行調(diào)度
當(dāng)后端服務(wù)器出現(xiàn)故障不能提供服務(wù)時吕漂,調(diào)度器具備健康狀態(tài)檢查功能亲配;
當(dāng)將后端node2服務(wù)器的tomcat服務(wù)關(guān)閉時尘应,自動全部調(diào)度至node1
(四)啟用httpd的調(diào)度器管理接口
vim /etc/httpd/conf.d/ajp-tomcat.conf // 添加以下幾行內(nèi)容
<Location /balancer-manager>
SetHandler balancer-manager
ProxyPass !
Require all granted // 演示用惶凝,實際工作要具體設(shè)置權(quán)限,并設(shè)置賬號認(rèn)證
</Location>
systemctl restart httpd
三犬钢、Tomcat實現(xiàn)會話粘滯(session sticky)
httpd實現(xiàn)通過cookie會話粘滯
原理:客戶端的第一次請求調(diào)度至后方主機(jī)后苍鲜,響應(yīng)報文經(jīng)過調(diào)度器時會添加cookie說明具體被調(diào)度至后方哪一臺主機(jī)。此后客戶端的請求報文報文都會附帶此cookie信息玷犹,調(diào)度器通過cookie信息調(diào)度至第一次調(diào)度到的主機(jī)混滔,實現(xiàn)會話粘滯。
實現(xiàn)過程:主要是在httpd服務(wù)器上對balancer設(shè)定不同的cookie_ID
vim /etc/httpd/conf.d/ajp-tomcat.conf
// 添加自定義cookie屬性ROUTEID
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e;path=/" env=BALANCER_ROUTE_CHANGED
<proxy balancer://tcsrvs>
// 給cookie的ROUTEID賦值歹颓,下一條語句作用相似
BalancerMember ajp://192.168.136.130:8009 loadfactor=2 route=TomcatA
BalancerMember ajp://192.168.136.131:8009 loadfactor=1 route=TomcatB
ProxySet lbmethod=byrequests
// 設(shè)置以ROUTEID作為會話粘滯的依據(jù)
ProxySet stickysession=ROUTEID // 設(shè)置以ROUTEID作為會話粘滯的依據(jù)
</Proxy>
<VirtualHost *:80>
ServerName www.hellopeiyang.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://tcsrvs/
ProxyPassReverse / balancer://tcsrvs/
<Location />
Require all granted
</Location>
</VirtualHost>
<Location /balancer-manager>
SetHandler balancer-manager
ProxyPass !
Require all granted
</Location>
httpd -t
systemctl reload httpd
在瀏覽器上測試成功坯屿,從客戶端的第二次請求開始,請求報文都包含有cookie信息巍扛,內(nèi)容中存在設(shè)置的ROUTEID
- 通過http協(xié)議實現(xiàn)負(fù)載均衡领跛、會話粘滯與ajp協(xié)議下的實現(xiàn)非常相似,只需修改http協(xié)議與端口號即可撤奸,不再贅述
四吠昭、Tomcat實現(xiàn)會話集群(session cluster)
實現(xiàn)原理:與會話粘滯通過配置調(diào)度器實現(xiàn)不同,會話集群是通過設(shè)置后臺tomcat服務(wù)器胧瓜,在tomcat服務(wù)器集群的內(nèi)部主機(jī)中以多播通信同步會話信息矢棚,實現(xiàn)會話保持的
實現(xiàn)過程:在每臺tomcat服務(wù)器上執(zhí)行以下配置
// 配置啟用集群,將下列配置放置于<engine>或<host>中
vim /etc/tomcat/server.xml
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.58.5.8" // 多播地址必須相同
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.136.132" // 填入每臺服務(wù)器的ip地址
port="4000"
autoBind="100"
selectorTimeout="5000"
maxThreads="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.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
// 確保Engine的jvmRoute屬性配置正確
<Engine name="Catalina" defaultHost="localhost" jvmRoute="TomcatA"> //每個服務(wù)器的jvmRoute值不同
// 配置webapps
vim /usr/share/tomcat/webapps/myapp/WEB-INF/web.xml
<distributable/> // 在web-app標(biāo)簽下添加
// 重啟tomcat服務(wù)
systemctl restart tomcat
調(diào)度器可以使用nginx, httpd調(diào)度府喳,在瀏覽器測試蒲肋,成功進(jìn)行了session cluster
從測試結(jié)果看出:盡管調(diào)度器分別調(diào)度至后臺的兩臺tomcat服務(wù)器,但是兩臺服務(wù)器提供服務(wù)的session id相同劫拢,證明通過集群實現(xiàn)了會話保持
五肉津、Tomcat實現(xiàn)會話服務(wù)器(session server)
(一)memcached:高性能、分布式的內(nèi)存對象緩存系統(tǒng)
(1)特性:
- k/v cache:僅可存儲可序列化數(shù)據(jù)舱沧;存儲項:k/v
- 智能性一半依賴于客戶端(調(diào)用memcached的API開發(fā)程序)妹沙,一半依賴于服務(wù)端
- 分布式緩存:互不通信的分布式集群
- 分布式系統(tǒng)請求路由方法:取模法,一致性哈希算法熟吏,算法復(fù)雜度:O(1)
- 清理過期緩存項:
- 緩存耗盡:LRU距糖,最近最少使用算法
- 緩存項過期:惰性清理機(jī)制(標(biāo)記過期緩存而不刪除,新緩存直接覆蓋舊緩存牵寺,減少了系統(tǒng)開銷)
(2)安裝配置:
- 由CentOS 7 base倉庫直接提供:
yum install memcached - 監(jiān)聽的端口:
11211/tcp, 11211/udp - 文件結(jié)構(gòu):
主程序:/usr/bin/memcached
配置文件:/etc/sysconfig/memcached
Unit File:memcached.service - 協(xié)議格式:memcached協(xié)議
文本格式悍引,易理解,效率低
二進(jìn)制格式帽氓,效率高
(3)命令:
- 統(tǒng)計類:stats, stats items, stats slabs, stats sizes
- 存儲類:set, add, replace, append, prepend
- 命令格式:
<command name> <key> <flags> <exptime> <bytes> <cas unique> - 檢索類:get, delete, incr/decr
- 清空:flush_all
(4)memcached程序的常用選項:
- -m <num>:緩存的最大內(nèi)存空間趣斤,默認(rèn)64MB
- -c <num>:最大并發(fā)連接,默認(rèn)1024
- -u <username>:以指定的用戶身份來運行進(jìn)程
- -l <ip_addr>:監(jiān)聽的IP地址黎休,默認(rèn)為本機(jī)所有地址
- -p <num>:監(jiān)聽的TCP端口浓领, 默認(rèn)11211
- -U <num>:監(jiān)聽的UDP端口玉凯,默認(rèn)11211,當(dāng)為0時為關(guān)閉UDP監(jiān)聽
- -M:內(nèi)存耗盡時联贩,不執(zhí)行LRU清理緩存漫仆,而是拒絕存入新的緩存項,直到有多余的空間可用時為止
- -f <factor>:增長因子泪幌;默認(rèn)是1.25
- -t <threads>:啟動的用于響應(yīng)用戶請求的線程數(shù)
(二)實現(xiàn)memcached緩存下的session server
(1)實現(xiàn)環(huán)境:
使用memcached-session-manager作為會話管理器盲厌,需要下載相應(yīng)的jar包
項目地址:https://github.com/magro/memcached-session-manager
(2)實現(xiàn)過程:
- 項目地址下載相關(guān)的jar包,并復(fù)制jar包至tomcat的庫目錄中
cp memcached-session-manager-${version}.jar /usr/share/java/tomcat/
cp memcached-session-manager-tc${6,7,8}-${version}.jar /usr/share/java/tomcat/
cp spymemcached-${version}.jar /usr/share/java/tomcat/
cp msm-kryo-serializer-${version}.jar /usr/share/java/tomcat/
cp kryo-serializers-${0.34+}.jar /usr/share/java/tomcat/
cp kryo-${3.x}.jar /usr/share/java/tomcat/
cp minlog.${version}.jar /usr/share/java/tomcat/
cp reflectasm.${version}.jar /usr/share/java/tomcat/
cp asm-${5.x}.jar /usr/share/java/tomcat/
cp objenesis-${2.x}.jar /usr/share/java/tomcat/
- 分別在兩個tomcat上的某host上定義一個用于測試的context容器祸泪,并在其中創(chuàng)建一個會話管理器
vim /etc/tomcat/server.xml
<Context path="/myapp" docBase="/usr/share/tomcat/webapps/myapp" reloadable="true">
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.136.131:11211,n2:192.168.136.132:11211"
failoverNodes="n2"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
</Context>
- 測試用例仍舊使用之前的myapp應(yīng)用吗浩,啟動memcached和tomcat服務(wù)
systemctl start memcached
systemctl start tomcat
- 調(diào)度器服務(wù)器上使用nginx或httpd配置轉(zhuǎn)發(fā),方法如上文没隘,不再贅述
在瀏覽器中測試拓萌,可以確定session ID在負(fù)載均衡環(huán)境中保持不變