阿里云ECS nginx(阿里云LB) + tomcat 8.5 + Redis 3.2 构建tomcat集群


前提:阿里云ECS 服务器两台 + 阿里云LB (测试使用的nginx upstream模块模拟集群)

因为公司项目单点提供服务,程序经常会出现死机,响应慢的情况,所以需要我们做集群来分担之前单点服务器承受的压力。保证我们的程序测试成功。


要点:tomcat集群需要做session共享,而tomcat自带的 session replication组件是通过多播(组播)进行通信,而鉴于docker容器的特性,docker容器是对udp协议的支持奇差,简而言之docker不支持组播,之前公司的有个音视频业务需要用到组播流,我查了很久才发现docker的这个特性,不支持组播。没有办法,把容器中的业务部署在宿主机上得以解决。

而通过docker搭建的阿里云服务器平台也是具有这一特性,我通过提交工单询问得知。具体截图如下:


tomcat自带的session replication解释:

阿里云ECS nginx(阿里云LB)+ tomcat8 + Redis 构建tomcat容器集群_第1张图片


阿里云详细说明:

阿里云ECS nginx(阿里云LB)+ tomcat8 + Redis 构建tomcat容器集群_第2张图片


提交工单获得的解释:

阿里云ECS nginx(阿里云LB)+ tomcat8 + Redis 构建tomcat容器集群_第3张图片

阿里云ECS nginx(阿里云LB)+ tomcat8 + Redis 构建tomcat容器集群_第4张图片


通过以上,可以看到即便是阿里如此强大的公司也未能避免这个特性,这就宣告使用自带session replication组件已经没戏了。


只能开始走tomcat + redis集群部署线路,但是普通redis也是不能直接直接支持tomcat 8+版本的,所以需要我们使用 redisson 实现共享;


部署redis,yum 安装 redis即可,

需要修改redis.conf

* * *
bind 0.0.0.0  #使得两台tomcat都能连接这台redis
* * *
protected-mode no 
* * *
requirepass 123456  #密码

systemctl restart redis即可;


下载两个jar包,放到/tomcat/lib/目录下;

redisson-all-3.11.2.jar

redisson-tomcat-8-3.11.2.jar

修改/tomcat/conf/server.conf

  
    

    
  

修改/tomcat/conf/context.xml

  
    


添加/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+"/";  
%>  
  
  
  
    
    ">  
      
    My JSP 'index.jsp' starting page  
      
      
          
      
      
      
    
    
    
              ip: 172.17.0.2
        SessionID2:<%=session.getId()%>           
           SessionIP:<%=request.getServerName()%>           
           SessionPort:<%=request.getServerPort()%>           <%           out.println("This is Tomcat Server 11111");           %>       

 

本地搭建一个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程序的配置文件修改至同一个数据库。

示例:

阿里云ECS nginx(阿里云LB)+ tomcat8 + Redis 构建tomcat容器集群_第5张图片

阿里云ECS nginx(阿里云LB)+ tomcat8 + Redis 构建tomcat容器集群_第6张图片


参考地址:

地址1,地址2,地址3