阿里雲ECS nginx(阿里雲LB) + tomcat 8.5 + Redis 3.2 構建tomcat集羣php
前提:阿里雲ECS 服務器兩臺 + 阿里雲LB (測試使用的nginx upstream模塊模擬集羣)css
由於公司項目單點提供服務,程序常常會出現死機,響應慢的狀況,因此須要咱們作集羣來分擔以前單點服務器承受的壓力。保證咱們的程序測試成功。html
要點:tomcat集羣須要作session共享,而tomcat自帶的 session replication組件是經過多播(組播)進行通訊,而鑑於docker容器的特性,docker容器是對udp協議的支持奇差,簡而言之docker不支持組播,以前公司的有個音視頻業務須要用到組播流,我查了好久才發現docker的這個特性,不支持組播。沒有辦法,把容器中的業務部署在宿主機上得以解決。java
而經過docker搭建的阿里雲服務器平臺也是具備這一特性,我經過提交工單詢問得知。具體截圖以下:nginx
tomcat自帶的session replication解釋:git
阿里雲詳細說明:github
提交工單得到的解釋:web
經過以上,能夠看到即使是阿里如此強大的公司也未能避免這個特性,這就宣告使用自帶session replication組件已經沒戲了。redis
只能開始走tomcat + redis集羣部署線路,可是普通redis也是不能直接直接支持tomcat 8+版本的,因此須要咱們使用 redisson 實現共享;docker
部署redis,yum 安裝 redis便可,
須要修改redis.conf
* * * bind 0.0.0.0 #使得兩臺tomcat都能鏈接這臺redis * * * protected-mode no * * * requirepass 123456 #密碼
systemctl restart redis便可;
下載兩個jar包,放到/tomcat/lib/目錄下;
修改/tomcat/conf/server.conf
<GlobalNamingResources> <!-- Editable user database that can also be used by UserDatabaseRealm to authenticate users --> <Resource name="bean/redisson" auth="Container" factory="org.redisson.JndiRedissonFactory" configPath="${catalina.base}/conf/redisson.conf" closeMethod="shutdown"/> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources>
修改/tomcat/conf/context.xml
<ResourceLink name="bean/redisson" global="bean/redisson" type="org.redisson.api.RedissonClient" /> <Manager className="org.redisson.tomcat.JndiRedissonSessionManager" readMode="REDIS" jndiName="bean/redisson" />
添加/tomcat/conf/redisson.conf (根據實際狀況修改 redis 的 ip,host,password)
{ "singleServerConfig":{ "idleConnectionTimeout":10000, "connectTimeout":10000, "timeout":3000, "retryAttempts":3, "retryInterval":1500, "password":"123456", "subscriptionsPerConnection":5, "clientName":null, "address": "redis://127.0.0.1:6379", "subscriptionConnectionMinimumIdleSize":1, "subscriptionConnectionPoolSize":50, "connectionMinimumIdleSize":24, "connectionPoolSize":64, "database":0, "dnsMonitoringInterval":5000 }, "threads":16, "nettyThreads":32, "codec":{ "class":"org.redisson.codec.FstCodec" }, "transportMode":"NIO" }
而後寫一個測試session.jsp ,目錄爲/tomcat/webapps/test/session.jsp , 兩個後臺的tomcat都須要寫這個jsp,並保持ip爲實際狀況的ip。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> ip: 172.17.0.2<br> SessionID2:<%=session.getId()%> <BR> SessionIP:<%=request.getServerName()%> <BR> SessionPort:<%=request.getServerPort()%> <% out.println("This is Tomcat Server 11111"); %> </body> </html>
本地搭建一個nginx 進行測試;
~]# cat /etc/nginx/conf.d/upstream.conf upstream api{ server 127.0.0.1:8080; server 192.168.1.100:8080; } server { listen 80; server_name abc.test.com; access_log /var/log/nginx/upstream.access.log combined; error_log /var/log/nginx/upstream.tv.error.log info; location / { index index.php index.shtml index.html; proxy_redirect off; proxy_pass http://api2; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
訪問 http://abc.test.com/test.session 而後能夠查看ip在邊,session不變,從而達到咱們的目的,注意若是鏈接數據庫的話,咱們須要把兩個tomcat程序的配置文件修改至同一個數據庫。
示例:
參考地址: