襄阳市文章资讯

tomcat多实例部署的项目实践

2026-03-29 22:19:02 浏览次数:0
详细信息

Tomcat多实例部署项目实践指南

一、多实例部署的优势

资源隔离:每个实例独立运行,避免相互影响 版本隔离:不同项目可使用不同Tomcat版本 配置独立:每个实例有自己的配置和日志 高可用性:一个实例故障不影响其他实例 灵活扩展:可根据需求单独扩展某个实例

二、环境准备

系统要求

目录结构规划

/opt/tomcat/
├── tomcat-base/          # 基础安装目录
├── instances/           # 实例目录
│   ├── instance1/      # 实例1
│   ├── instance2/      # 实例2
│   └── instance3/      # 实例3
├── apps/               # 应用部署目录
└── scripts/           # 管理脚本

三、部署步骤

步骤1:安装基础Tomcat

# 下载Tomcat
cd /opt
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.85/bin/apache-tomcat-9.0.85.tar.gz
tar -xzf apache-tomcat-9.0.85.tar.gz
mv apache-tomcat-9.0.85 tomcat-base

# 创建必要的目录结构
mkdir -p /opt/tomcat/instances
mkdir -p /opt/tomcat/apps
mkdir -p /opt/tomcat/scripts
mkdir -p /opt/tomcat/logs

步骤2:创建多实例模板脚本

创建 /opt/tomcat/scripts/create-instance.sh

#!/bin/bash

# 创建Tomcat多实例脚本
INSTANCE_NAME=$1
PORT_OFFSET=$2

if [ -z "$INSTANCE_NAME" ] || [ -z "$PORT_OFFSET" ]; then
    echo "用法: $0 <实例名称> <端口偏移量>"
    echo "例如: $0 myapp 100"
    exit 1
fi

INSTANCE_DIR="/opt/tomcat/instances/$INSTANCE_NAME"
BASE_DIR="/opt/tomcat/tomcat-base"

# 创建实例目录
mkdir -p $INSTANCE_DIR
mkdir -p $INSTANCE_DIR/{bin,conf,logs,temp,webapps,work}

# 复制必要的配置文件
cp $BASE_DIR/conf/server.xml $INSTANCE_DIR/conf/
cp $BASE_DIR/conf/web.xml $INSTANCE_DIR/conf/
cp $BASE_DIR/conf/logging.properties $INSTANCE_DIR/conf/
cp $BASE_DIR/conf/tomcat-users.xml $INSTANCE_DIR/conf/

# 创建启动脚本
cat > $INSTANCE_DIR/bin/startup.sh << EOF
#!/bin/bash
export CATALINA_BASE="$INSTANCE_DIR"
export CATALINA_HOME="$BASE_DIR"
export CATALINA_PID="\$CATALINA_BASE/tomcat.pid"
export CATALINA_OPTS="-Xms512m -Xmx1024m -Djava.awt.headless=true"
export JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"

\$CATALINA_HOME/bin/catalina.sh start
EOF

cat > $INSTANCE_DIR/bin/shutdown.sh << EOF
#!/bin/bash
export CATALINA_BASE="$INSTANCE_DIR"
export CATALINA_HOME="$BASE_DIR"
export CATALINA_PID="\$CATALINA_BASE/tomcat.pid"

\$CATALINA_HOME/bin/catalina.sh stop
EOF

chmod +x $INSTANCE_DIR/bin/*.sh

# 修改server.xml中的端口配置
SHUTDOWN_PORT=$((8005 + PORT_OFFSET))
HTTP_PORT=$((8080 + PORT_OFFSET))
AJP_PORT=$((8009 + PORT_OFFSET))

sed -i "s/8005/$SHUTDOWN_PORT/" $INSTANCE_DIR/conf/server.xml
sed -i "s/8080/$HTTP_PORT/" $INSTANCE_DIR/conf/server.xml
sed -i "s/8009/$AJP_PORT/" $INSTANCE_DIR/conf/server.xml

# 修改日志配置
sed -i "s#\${catalina.base}/logs#/opt/tomcat/logs/${INSTANCE_NAME}#" $INSTANCE_DIR/conf/logging.properties

# 创建日志目录
mkdir -p "/opt/tomcat/logs/${INSTANCE_NAME}"

echo "实例 $INSTANCE_NAME 创建成功!"
echo "HTTP端口: $HTTP_PORT"
echo "Shutdown端口: $SHUTDOWN_PORT"
echo "AJP端口: $AJP_PORT"

步骤3:创建三个实例

# 赋予执行权限
chmod +x /opt/tomcat/scripts/create-instance.sh

# 创建实例
/opt/tomcat/scripts/create-instance.sh webapp1 0     # 端口: 8080, 8005, 8009
/opt/tomcat/scripts/create-instance.sh webapp2 100   # 端口: 8180, 8105, 8109
/opt/tomcat/scripts/create-instance.sh webapp3 200   # 端口: 8280, 8205, 8209

步骤4:配置用户和权限

修改每个实例的 tomcat-users.xml

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">

    <role rolename="manager-gui"/>
    <role rolename="manager-script"/>
    <role rolename="manager-jmx"/>
    <role rolename="manager-status"/>
    <role rolename="admin-gui"/>

    <user username="admin" password="admin123" 
          roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui"/>
</tomcat-users>

步骤5:配置应用部署

创建应用部署目录结构:

# 为每个应用创建目录
mkdir -p /opt/tomcat/apps/{app1,app2,app3}

# 示例:部署一个简单的WAR文件
# 将应用部署到对应的webapps目录
cp /path/to/app1.war /opt/tomcat/instances/webapp1/webapps/
cp /path/to/app2.war /opt/tomcat/instances/webapp2/webapps/ROOT.war  # 作为根应用

四、管理系统服务

创建Systemd服务文件

为每个实例创建systemd服务:

/etc/systemd/system/tomcat-webapp1.service

[Unit]
Description=Tomcat 9 Instance - webapp1
After=network.target

[Service]
Type=forking
User=tomcat
Group=tomcat
Environment="CATALINA_BASE=/opt/tomcat/instances/webapp1"
Environment="CATALINA_HOME=/opt/tomcat/tomcat-base"
Environment="CATALINA_PID=/opt/tomcat/instances/webapp1/tomcat.pid"
Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk"
Environment="JAVA_OPTS=-Xms512m -Xmx1024m -server -XX:+UseParallelGC"

ExecStart=/opt/tomcat/tomcat-base/bin/startup.sh
ExecStop=/opt/tomcat/tomcat-base/bin/shutdown.sh

RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target

创建管理脚本

/opt/tomcat/scripts/manage-tomcat.sh

#!/bin/bash

ACTION=$1
INSTANCE=$2

case "$ACTION" in
    start)
        systemctl start tomcat-$INSTANCE
        ;;
    stop)
        systemctl stop tomcat-$INSTANCE
        ;;
    restart)
        systemctl restart tomcat-$INSTANCE
        ;;
    status)
        systemctl status tomcat-$INSTANCE
        ;;
    list)
        echo "可用的Tomcat实例:"
        echo "1. webapp1 (端口: 8080)"
        echo "2. webapp2 (端口: 8180)"
        echo "3. webapp3 (端口: 8280)"
        ;;
    *)
        echo "用法: $0 {start|stop|restart|status|list} [实例名]"
        exit 1
esac

五、Nginx反向代理配置

配置Nginx实现负载均衡和反向代理:

upstream tomcat_cluster {
    least_conn;
    server 127.0.0.1:8080 weight=3;
    server 127.0.0.1:8180 weight=2;
    server 127.0.0.1:8280 weight=1;

    keepalive 32;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://tomcat_cluster;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 连接超时设置
        proxy_connect_timeout 30s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # 启用keepalive
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }

    # 静态文件缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # 健康检查
    location /health {
        access_log off;
        return 200 "healthy\n";
    }
}

六、监控和管理

1. 日志管理配置

配置logrotate管理日志:

/etc/logrotate.d/tomcat-instances

/opt/tomcat/logs/*/*.log {
    daily
    rotate 30
    missingok
    compress
    delaycompress
    notifempty
    create 644 tomcat tomcat
    sharedscripts
    postrotate
        /usr/bin/systemctl reload tomcat-*
    endscript
}

2. 监控脚本

/opt/tomcat/scripts/monitor-tomcat.sh

#!/bin/bash

INSTANCES=("webapp1" "webapp2" "webapp3")
PORTS=(8080 8180 8280)

for i in "${!INSTANCES[@]}"; do
    INSTANCE=${INSTANCES[$i]}
    PORT=${PORTS[$i]}

    # 检查进程
    PID_FILE="/opt/tomcat/instances/$INSTANCE/tomcat.pid"
    if [ -f "$PID_FILE" ]; then
        PID=$(cat $PID_FILE)
        if ps -p $PID > /dev/null; then
            echo "$INSTANCE 运行正常 (PID: $PID)"

            # 检查端口监听
            if netstat -tlnp 2>/dev/null | grep ":$PORT" | grep -q "$PID"; then
                echo "  - 端口 $PORT 监听正常"
            else
                echo "  - 警告: 端口 $PORT 未监听"
            fi
        else
            echo "$INSTANCE 进程不存在,尝试重启..."
            systemctl restart tomcat-$INSTANCE
        fi
    else
        echo "$INSTANCE 未运行"
    fi

    # 检查应用状态
    RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:$PORT/health 2>/dev/null || echo "000")
    if [ "$RESPONSE" = "200" ]; then
        echo "  - 应用健康检查通过"
    else
        echo "  - 警告: 应用健康检查失败 (HTTP: $RESPONSE)"
    fi
done

七、安全配置建议

1. 修改默认配置

<!-- 修改server.xml中的Connector配置 -->
<Connector port="8080" protocol="HTTP/1.1"
           maxThreads="200"
           minSpareThreads="10"
           enableLookups="false"
           acceptCount="100"
           maxConnections="10000"
           connectionTimeout="20000"
           disableUploadTimeout="true"
           compression="on"
           compressionMinSize="2048"
           compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/json"
           server="Unknown Server"  <!-- 隐藏服务器信息 -->
           />

2. 防火墙配置

# 只开放必要的端口
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=8180/tcp
sudo firewall-cmd --permanent --add-port=8280/tcp
sudo firewall-cmd --reload

八、部署验证

测试脚本

/opt/tomcat/scripts/test-deployment.sh

#!/bin/bash

echo "=== Tomcat多实例部署测试 ==="
echo

# 测试每个实例
echo "1. 测试实例连接:"
curl -s http://localhost:8080 | grep -o "<title>.*</title>"
curl -s http://localhost:8180 | grep -o "<title>.*</title>"
curl -s http://localhost:8280 | grep -o "<title>.*</title>"

echo
echo "2. 测试应用健康状态:"
for port in 8080 8180 8280; do
    status=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:$port/ 2>/dev/null)
    echo "端口 $port: HTTP $status"
done

echo
echo "3. 检查进程状态:"
ps aux | grep "[j]ava.*catalina.base" | grep -v grep

echo
echo "4. 检查端口监听:"
netstat -tlnp | grep -E ":8080|:8180|:8280"

九、常见问题解决

1. 端口冲突

# 检查端口占用
netstat -tlnp | grep -E "8080|8180|8280"

# 修改端口
# 编辑对应实例的server.xml修改端口号

2. 内存设置

根据应用需求调整JVM参数:

# 编辑systemd服务文件
JAVA_OPTS="-Xms1g -Xmx2g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"

3. 权限问题

# 设置正确的文件权限
chown -R tomcat:tomcat /opt/tomcat
chmod -R 755 /opt/tomcat/instances

十、优化建议

使用连接池:配置DBCP或HikariCP 启用HTTPS:为生产环境配置SSL 会话共享:使用Redis实现分布式会话 监控集成:集成Prometheus和Grafana 自动部署:使用CI/CD流水线自动化部署

这个部署方案提供了完整的Tomcat多实例管理框架,可根据实际需求进行调整和扩展。

相关推荐