初めて立て見みましたが、やってみると、ほぼ、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