環境:OS=Windows10Pro
Webサーバ:ApacheHTTPServer2.4
APサーバ:Tomcat10(2台)
Apacheにロードバランサ設定を行い、2台のクラスタ化されたTomcatと連携する。
更に、Tomcat1台づつ停止してもSessionが引き継がれる事を確認する。
1.Tomcatインストール
・Tomcatを2つインストールする。(2つのインスタンスにしてインストール)
・Tomcat101のserver.xmlを修正
①
<Connector port=”8080″ protocol=”HTTP/1.1″ connectionTimeout=”20000″ redirectPort=”8443″ />
↓
<Connector port=”18080” protocol=”HTTP/1.1″ connectionTimeout=”20000″ redirectPort=”18443” />
②
※デフォルトではコメントになっているのでコメントを外す
<Connector protocol=”AJP/1.3″ address=”::1″ port=”8009″ redirectPort=”8443″ />
↓
<Connector protocol=”AJP/1.3″ address=”::1″ port=”18009” redirectPort=”18443” />
③
<!–
<Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster”/>
–>
このコメントの下に以下を追加
<Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster”
channelSendOptions=”6″>
<Manager className=”org.apache.catalina.ha.session.BackupManager”
expireSessionsOnShutdown=”false”
notifyListenersOnReplication=”true”
mapSendOptions=”6″/>
<!–
<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.0.0.4″
port=”45564″
frequency=”500″
dropTime=”3000″/>
<Receiver className=”org.apache.catalina.tribes.transport.nio.NioReceiver”
address=”auto”
port=”5000″
selectorTimeout=”100″
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.MessageDispatchInterceptor”/>
<Interceptor className=”org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor”/>
</Channel>
<Valve className=”org.apache.catalina.ha.tcp.ReplicationValve”
filter=”.*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt”/>
<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.ClusterSessionListener”/>
</Cluster>
・Tomcat102のserver.xmlを修正
①
<Connector port=”8080″ protocol=”HTTP/1.1″ connectionTimeout=”20000″ redirectPort=”8443″ />
↓
<Connector port=”28080” protocol=”HTTP/1.1″ connectionTimeout=”20000″ redirectPort=”28443” />
②
※デフォルトではコメントになっているのでコメントを外す
<Connector protocol=”AJP/1.3″ address=”::1″ port=”8009″ redirectPort=”8443″ />
↓
<Connector protocol=”AJP/1.3″ address=”::1″ port=”28009” redirectPort=”28443” />
③
<!–
<Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster”/>
–>
このコメントの下に以下を追加
<Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster”
channelSendOptions=”6″>
<Manager className=”org.apache.catalina.ha.session.BackupManager”
expireSessionsOnShutdown=”false”
notifyListenersOnReplication=”true”
mapSendOptions=”6″/>
<!–
<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.0.0.4″
port=”45564″
frequency=”500″
dropTime=”3000″/>
<Receiver className=”org.apache.catalina.tribes.transport.nio.NioReceiver”
address=”auto”
port=”5000″
selectorTimeout=”100″
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.MessageDispatchInterceptor”/>
<Interceptor className=”org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor”/>
</Channel>
<Valve className=”org.apache.catalina.ha.tcp.ReplicationValve”
filter=”.*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt”/>
<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.ClusterSessionListener”/>
</Cluster>
2.ApacheHTTPServerの設定
・httpd.confの末尾に以下を追加する
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_express_module modules/mod_proxy_express.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule status_module modules/mod_status.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
ProxyPass / balancer://mybalance/ nofailover=Off timeout=10 maxattempts=1 stickysession=JSESSIONID
ProxyPassReverse / balancer://mybalance/
<Proxy balancer://mybalance/>
BalancerMember http://localhost:18080 keepalive=On loadfactor=10 retry=2
BalancerMember http://localhost:28080 keepalive=On loadfactor=10 retry=2
</Proxy>
ProxyPass /balancer-manager !
<Location /balancer-manager>
SetHandler balancer-manager
Order Deny,Allow
Deny from all
Allow from 192.168 #環境によって変更
</Location>
・Apacheの動作確認
Apacheを起動する。起動方法はDos窓から起動する。(エラーの場合、Dos窓にエラーメッセージが出るから)

エラーが無かったらDos窓を終了して、サービスから起動

ブラウザからアクセスする

これでOK
3.Sessionが引き継がれる確認用のJavaアプリを作成する
index.jsp
TopPage.java
CreateSessionPage.java
GetSessionPage.java
PersonSeri.java
web.xml
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=windows-31j”/>
</head>
<body>
<br>
<form action=’./TopPage’ method=’Post’>
<input type = ‘submit’ value = ‘TopPage’>
</form>
<br>
</body>
</html>
</html>
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet(name = “TopPage”, urlPatterns = { “/TopPage” })
public class TopPage extends HttpServlet {
private static final String CONTENT_TYPE = “text/html; charset=windows-31j”;
private static final long serialVersionUID = 1L;
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
out.println(“<html>”);
out.println(“<head><title>TopPage</title></head>”);
out.println(“<body>”);
out.println(“<br>”);
out.println(“TopPage”);
out.println(“<br>”);
out.println(“<br>”);
out.println(“<form action=’./CreateSessionPage’ method=’Post’>”);
out.println(“<input type = ‘submit’ value = ‘CreateSessionPage’>”);
out.println(“</form>”);
out.println(“<br>”);
out.println(“<br>”);
out.println(“<form action=’./GetSessionPage’ method=’Post’>”);
out.println(“<input type = ‘submit’ value = ‘GetSessionPage’>”);
out.println(“</form>”);
out.println(“<br>”);
out.println(“<form action=’./index.jsp’ method=’Post’>”);
out.println(“<input type = ‘submit’ value = ‘index.jsp’>”);
out.println(“</form>”);
out.println(“<br>”);
out.println(“</body>”);
out.println(“</html>”);
}
}
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet(name = “CreateSessionPage”, urlPatterns = { “/CreateSessionPage” })
public class CreateSessionPage extends HttpServlet {
private static final String CONTENT_TYPE = “text/html; charset=windows-31j”;
private static final long serialVersionUID = 1L;
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
//Sessionはシリアライズ化する
session.setAttribute(“personSeri”, new PersonSeri(“TESTTEST”));
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
out.println(“<!DOCTYPE html>”);
out.println(“<html>”);
out.println(“<head>”);
out.println(“<title></title>”);
out.println(“</head>”);
out.println(“<body>”);
out.println(“<br>”);
out.println(“CreateSessionPage”);
out.println(“<br>”);
out.println(“Session=name1<br>”);
out.println(“<form action=’./GetSessionPage’ method=’Post’>”);
out.println(“<input type = ‘submit’ value = ‘GetSessionPage’>”);
out.println(“</form>”);
out.println(“<br>”);
out.println(“<br>”);
out.println(“<form action=’./TopPage’ method=’Post’>”);
out.println(“<input type = ‘submit’ value = ‘TopPage’>”);
out.println(“</form>”);
out.println(“<br>”);
out.println(“<form action=’./index.jsp’ method=’Post’>”);
out.println(“<input type = ‘submit’ value = ‘index.jsp’>”);
out.println(“</form>”);
out.println(“<br>”);
out.println(“</body>”);
out.println(“</html>”);
}
}
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet(name = “GetSessionPage”, urlPatterns = { “/GetSessionPage” })
public class GetSessionPage extends HttpServlet {
private static final String CONTENT_TYPE = “text/html; charset=windows-31j”;
private static final long serialVersionUID = 1L;
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
out.println(“<html>”);
out.println(“<head><title>GetSessionPage</title></head>”);
out.println(“<body>”);
out.println(“<br>”);
out.println(“GetSessionPage”);
out.println(“<br>”);
out.println(“PersonSeri ” + ((PersonSeri)request.getSession().getAttribute(“personSeri”)).getName());
out.println(“<br>”);
out.println(“<br>”);
out.println(“<form action=’./TopPage’ method=’Post’>”);
out.println(“<input type = ‘submit’ value = ‘TopPage’>”);
out.println(“</form>”);
out.println(“<br>”);
out.println(“<form action=’./index.jsp’ method=’Post’>”);
out.println(“<input type = ‘submit’ value = ‘index.jsp’>”);
out.println(“</form>”);
out.println(“<br>”);
out.println(“</body>”);
out.println(“</html>”);
}
}
public class PersonSeri implements Serializable {
@SuppressWarnings(“compatibility:-6848355860387642004”)
private static final long serialVersionUID = 1L;
private String name;
public PersonSeri(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<distributable/> ※最後尾に追加する
</web-app>
・作成したアプリをTomcat1,2にデプロイする
4.動作確認
2台のTomcatを停止→起動→停止を繰り返してSessionが消えない事を確認する
・Tomcat1,2起動
ブラウザからアクセス
・GetSessionPageボタン押下
これはTomcat1,2が起動しているのでSession取れて当たり前
・Tomcat1停止
・TopPageボタン押下→GetSessionPageボタン押下
Sessionが取得できること確認
・Tomcat1起動→Tomcat2停止
・TopPageボタン押下→GetSessionPageボタン押下
Sessionが取得できること確認
これでApacheのロードバランサが効いて、Tomcatのクラスタが効いて、Sessionレプリカが効いていることを確認できた




