初めて立て見みましたが、やってみると、ほぼ、tomcatのdocumentのまんま。という感じ
全体構成
┌PC─────┐
│┌────┐│
││browser ││
│└──┬─┘│
└───│──┘
│
┌ HostA│──┐ ┌ HostB───┐
│┌──┴─┐│ │ │
││nginx ││ Load Balance │ │
│└──┬─┘│ (Round Robin)│ │
│ ├─────────────┐ │
│┌──┴─┐│ │┌─┴──┐│
││tomcat8 ├─────────┤tomcat8 ││
│└──┬─┘│ Session │└─┬──┘│
│┌──┴─┐│ Replication │┌─┴──┐│
││java ││(DeltaManager ││java ││
││servlet ││ MultiCast) ││servlet ││
│└────┘│ │└────┘│
└──────┘ └──────┘
install & setup nginx
ロードバランサとして使用しますが、まずはinstall
[HOST A]$ sudo rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm [HOST A]$ sudo yum install nginx
次に設定。 centos7ha1.a5.jp:80 で受けたrequestを centos7ha1.a5.jp:8080 , centos7ha2.a5.jp:8080 に対し、 round robinでload balanceします。 また、access.log に対し、load balance先のipを出力しています。($upstream_addr)
[HOST A]$ sudo vi /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$upstream_addr"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
upstream centos7ha1.a5.jp {
server centos7ha1.a5.jp:8080;
server centos7ha2.a5.jp:8080;
}
server {
listen 80;
location / {
proxy_pass http://centos7ha1.a5.jp;
}
}
}
nginxを起動し、ブラウザでアクセスすると、 centos7ha1.a5.jp:8080 , centos7ha2.a5.jp:8080 に対し、 round robinでload balanceされていることが分かります。
[HOST A]$ sudo systemctl start nginx [HOST A]$ sudo tail -f /var/log/nginx/access.log [19/Sep/2019:10:04:49 +0900] "GET / HTTP/1.1" <略> "192.168.63.16:8080" [19/Sep/2019:10:04:50 +0900] "GET / HTTP/1.1" <略> "192.168.63.17:8080" :
その他、今回は各ホストで名前解決する為、/etc/hostsを以下のようにしています。
[ALL HOST]$ cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.63.16 centos7ha1.a5.jp 192.168.63.17 centos7ha2.a5.jp
install java & tomcat
[ALL HOST]$ sudo yum install java [ALL HOST]$ java -version openjdk version "1.8.0_222" OpenJDK Runtime Environment (build 1.8.0_222-b10) OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
[ALL HOST]$ sudo useradd tomcat [ALL HOST]$ sudo passwd tomcat [ALL HOST]$ sudo su - tomcat [ALL HOST]$ mkdir local [ALL HOST]$ cd local [ALL HOST]$ wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.0.53/bin/apache-tomcat-8.0.53.tar.gz [ALL HOST]$ tar -xvf apache-tomcat-8.5.45.tar.gz [ALL HOST]$ ln -s apache-tomcat-8.5.45 tomcat
config tomcat
https://tomcat.apache.org/tomcat-8.0-doc/cluster-howto.html
上記urlを参考に、DeltaManager + MultiCastな Session Replication環境を構築します。 (MultiCast以外にUniCastなSession Replicationもできるようです)
まずは、マルチキャストIPを各hostが受信するようにroutingを設定。
[ALL HOST]$ sudo vi /etc/sysconfig/network-scripts/route-enp0s8 ADDRESS0=224.0.0.0 NETMASK0=240.0.0.0 [ALL HOST]$ sudo service network restart [ALL HOST]$ netstat -rn
[ALL HOST]$ sudo su - tomcat
[ALL HOST]$ vi /home/tomcat/local/tomcat/conf/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.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
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.ClusterSessionListener"/>
</Cluster>
動作確認用 java servletの作成
/SetSession で日時をセッションに登録し、 /GetSession でセッションにある情報を画面表示させます。(以下)
package jp.end0tknr; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @WebServlet("/SetSession") public class SetSession extends HttpServlet { private static final long serialVersionUID = 1L; public SetSession() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); Date date = new Date(); // 今日の日付 String strDate = date.toString(); session.setAttribute("sessionKey", strDate); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Hello World!</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Hello !! Create Session !!</h1>"); out.println("</body>"); out.println("</html>"); out.close(); } }
package jp.end0tknr; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @WebServlet("/GetSession") public class GetSession extends HttpServlet { private static final long serialVersionUID = 1L; public GetSession() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); out.println("<html><body>"); out.println("sessionValue = " + request.getSession().getAttribute("sessionKey")); out.println("<br>"); out.println(request.getSession().getId()); out.println("</body></html>"); out.close(); } }
以下は、servlet用のweb.xmlの抜粋。
web.xmlに「
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee"> <display-name>SessionTest</display-name> <distributable /> </web-app>
後は、tomcatを起動し、動作確認して下さい。
[ALL HOST]$ sudo su - tomcat [ALL HOST]$ cd local/tomcat [ALL HOST]$ ./bin/startup.sh