Tomcat单机多实例部署及管理

单台机器部署多个 Tomcat, 每个Tomcat部署独立服务,Tomcat之间启停互不影响

不要问我为什么有这个需求, 复制粘贴就是干

0x00 单机多实例概述

大概的目录结构:

  • CATALINA_HOME 为Tomcat应用程序运行程序及所需依赖
  • CATALINA_BASE 即我们即将部署的程序

手动更改如下工作目录:

这是我自己个儿整的初始目录结构 download

war_apps                #手动创建用来存放下载好的war包文件
tomcat                  #CATALINA_HOME
├── bin
├── INIT_APPS_FILE      #CATALINA_BASE
│   ├── conf
│   ├── logs
│   ├── temp
│   ├── webapps
│   └── work
└── lib

然后呢正常的思路就是配置每个APP的server.xml端口:

- Server Port:该端口用于监听关闭tomcat的shutdown命令,默认为8005
- Connector Port:该端口用于监听HTTP的请求,默认为8080
- AJP Port:该端口用于监听AJP( Apache JServ Protocol )协议上的请求,通常用于整合Apache Server等其他HTTP服务器,默认为8009
- Redirect Port:重定向端口,出现在Connector配置中,如果该Connector仅支持非SSL的普通http请求,那么该端口会把 https 的请求转发到这个Redirect Port指定的端口,默认为8443;

应用太多你难道要一个个手动改? no no no! 上脚本

0x01 自动部署管理配置

需要把应用war包传到可下载位置,来用于应用分发,我这里是直接传到了阿里云的oss桶里

1.添加tomcat更新启停控制脚本

需要安装unzip yum -y install unzip

manage.sh需要放在这里,也可以自定义改代码

war_apps                #手动创建用来存放下载好的war包文件
tomcat                  #CATALINA_HOME
├── bin
├── manage.sh
├── INIT_APPS_FILE      #CATALINA_BASE
│   ├── conf
│   ├── logs
│   ├── temp
│   ├── webapps
│   └── work
└── lib

蓝色块需要根据实际情况自定义, 应用名称, 和war包下载地址不需要写,后面的python总控制台会自动分配

manage.sh

#!/bin/sh
# Author: Kionf
# description: 启动tomcat多实例.
# PATH=/opt/op/java/jdk1.8.0_172/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
# 应用名称
app=
# war包下载地址
war_url=
soft_dir="/opt/op"
download_war_file="${soft_dir}/war_apps/${app}.war"
export CATALINA_BASE="${soft_dir}/tomcat/$app"
export CATALINA_HOME="${soft_dir}/tomcat"
export JVM_OPTIONS="-Xms528m -Xmx812m -Xmn328m"
check(){
    PID=`ps aux|grep java|grep -w ${CATALINA_BASE}|awk '{print $2}'`
    if [ -n "$PID" ];then
        echo -e "\033[94m $app is running PID:$PID"
        running=`netstat -ntlp|grep $PID|grep 127.0.0.1`
        if [ -n "$running" ];then
            echo -e "\033[92m $app is provide services\033[0m "
        else
            echo -e "\033[93m $app is running but not provide services\033[0m"
        fi
        return 0
    else
        echo -e "\033[91m $app is dead\033[0m "
        return 1
    fi
}
start() {
    check
    if [ $? -eq 1 ];then
        echo -e "\033[94m Start $app \033[0m"
        $CATALINA_HOME/bin/startup.sh >/dev/null 2>&1
    fi
}
stop() {
    check
    if [ $? -eq 0 ];then
        echo -e "\033[94m Stop $app\033[0m"
        $CATALINA_HOME/bin/shutdown.sh >/dev/null 2>&1
        kill -9 $PID
    fi
}
update() {
    echo "下载文件"
    wget ${war_url} -O ${download_war_file} > /dev/null 2>&1
    if [ $? -eq 0 ];then
        cd ${CATALINA_BASE}/webapps/*/; unzip -q -o ${download_war_file} >/dev/null 2>&1
    fi
}
log() {
    tailf ${CATALINA_BASE}/logs/catalina.out
}
if [ $# != "0" ];then
    case "$1" in
        start)
            start
            ;;
        stop)
            stop
            ;;
        restart)
            stop
            start 
            ;;
        status)
            check
            ;;
        upgrade)
            stop
            update
            start
            ;;
        log)
            log
            ;;
        *)
            echo $"Usage: $0 {start|stop|restart|status|upgrade|log}"
            exit 1
            ;;
    esac
else
    start
    log
fi

2.添加总控制台脚本

我就放在了/usr/local/bin下, chmod +x /usr/local/bin/tomcat_manager 蓝色部分需要根据自己需求更改 (支持python2)

/usr/local/bin/tomcat_manager

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/5/23 15:18
# @Author  : Kionf
# @FileName: tomcat_manager.py
#
#   初始配置并管理单例tomcat多应用
#
import os
import subprocess
import sys
import shutil
# PATH = os.getcwd()
PATH = "/opt/op/tomcat"         #Tomcat目录
shell_script = os.path.join(PATH, "manage.sh")          #更新启停管理脚本
INIT_FILES = os.path.join(PATH, "INIT_APPS_FILE")
bucket = "https://oss.aliyuncs.com/tomcat_app/"         # webapp下载地址
config_data = {
    # 应用名: [ServerPort, ConnectPort, AJPPort, RedirectPort, ]
    'Application': ['8201', '8101', '8301', '8401', 'BaseApplication.war'],
    'BaseNotify_Service': ['8202', '8102', '8302', '8402', 'BaseNotify_Service.war'],
    'BaseUserCenter_Service': ['8203', '8103', '8303', '8403', 'BaseUserCenter_Service.war'],
}
def customize_print(msg, stat=0):
    if stat == 1:
        print("\033[91m [ERROR]:  %s \033[0m" % msg)
    elif stat == 0:
        print("\033[92m [INFO]:  %s \033[0m" % msg)
    elif stat == 2:
        print("\033[93m [DEBUG]:  %s \033[0m" % msg)
class TomcatAppsManage:
    def __init__(self, webapp):
        self.name = webapp
        self.app_config = config_data[self.name]
        self.manage_shell_file = os.path.join(PATH, self.name, self.name)
        self.server_port, self.conn_port, self.ajp_port, self.redirect_port, self.app_war_name = self.app_config
        self.app_download_url = bucket + self.app_war_name
        self.config_file = os.path.join(PATH, self.name, 'conf/server.xml')
        self.webapp_dir = os.path.join(PATH, self.name)
    def create_app(self):
        """
        创建app
        :return:
        """
        if not os.path.exists(self.webapp_dir):
            customize_print("创建APP: %s" % self.name)
            shutil.copytree(INIT_FILES, self.webapp_dir)
            os.mkdir(os.path.join(self.webapp_dir, "webapps", self.name.lower()))
    def config_app_port(self):
        customize_print("正在修改APP:%s 配置" % self.name)
        change_port = {
            'ServerPort': "sed -i s'#Server port=\"[0-9]*\"#Server port=\"" + self.server_port + "\"#'g " + self.config_file,
            'ConnPort': "sed -i s'#Connector port=\"[0-9]*\" protocol=\"HTTP/1.1\"#Connector port=\"" + self.conn_port + "\" protocol=\"HTTP/1.1\"#'g " + self.config_file,
            'RedirectPort': "sed -i s'#redirectPort=\"[0-9]*\"#redirectPort=\"" + self.redirect_port + "\"#'g " + self.config_file,
            'AjpPort': "sed -i s'#Connector port=\"[0-9]*\" protocol=\"AJP/1.3\"#Connector port=\"" + self.ajp_port + "\" protocol=\"AJP/1.3\"#'g " + self.config_file,
        }
        for port in change_port.keys():
            # customize_print("修改 %s 端口" % port)
            os.system(change_port[port])
    def config_app_manage_shell(self):
        customize_print("%s 添加管理脚本" % self.name)
        copy_shell_script = 'cp -f ' + shell_script + ' ' + self.manage_shell_file
        os.system(copy_shell_script)
        config_script_app_name = "sed -i 's/app=/app=\"" + self.name + "\"/' " + self.manage_shell_file
        os.system(config_script_app_name)
        config_script_war_url = "sed -i 's#war_url=#war_url=\"" + self.app_download_url + "\"#' " + self.manage_shell_file
        os.system(config_script_war_url)
    def status_app(self):
        """
        :return: 0提供服务,1停止,2未提供服务
        """
        try:
            result = subprocess.check_output(['sh', self.manage_shell_file, 'status'])
        except subprocess.CalledProcessError as e:
            result = e.output
        if 'run' in result:
            if 'is provide services' in result:
                customize_print("应用 %s 成功启动并提供服务" % self.name)
                return 0
            elif 'but' in result:
                customize_print("应用 %s 进程存在但未提供服务" % self.name, 2)
                return 2
        else:
            customize_print("应用 %s 以停止" % self.name, 1)
            return 1
    def manage(self, operate):
        os.system('sh %s %s' % (self.manage_shell_file, operate))

    def init(self):
        self.create_app()
        self.config_app_port()
        self.config_app_manage_shell()
        self.manage("upgrade")
        self.manage("stop")
    def restart(self):
        self.manage("stop")
        self.manage("start")
    def start(self):
        self.manage("start")
    def stop(self):
        self.manage("stop")
    def log(self):
        self.manage("log")
    def upgrade(self):
        self.lock_config_file()
        self.manage("upgrade")
    def lock_config_file(self):
        cmd = 'find ' + self.webapp_dir + ' -name db*properties -o -name config_base_*|xargs chattr +i >/dev/null 2>&1'
        customize_print("锁配置文件", 2)
        os.system(cmd)
    def unlock_config_file(self):
        cmd = 'find ' + self.webapp_dir + ' -name db*properties -o -name config_base_*|xargs chattr -i >/dev/null 2>&1'
        customize_print("解锁配置文件", 2)
        os.system(cmd)
def dash_board(apps, operate):
    """
    主管理程序,调用
    :param operate: 应用操作
    :param apps: apps 为list
    """
    for app in apps:
        app_obj = TomcatAppsManage(app)
        main_dict = {
            "init": app_obj.init,
            "shell": app_obj.config_app_manage_shell,
            "status": app_obj.status_app,
            "start": app_obj.start,
            "stop": app_obj.stop,
            "restart": app_obj.restart,
            "upgrade": app_obj.upgrade,
            "log": app_obj.log,
            "lock": app_obj.lock_config_file,
            "unlock": app_obj.unlock_config_file,
        }
        try:
            main_dict[operate]()
        except KeyError as e:
            customize_print(help_msg)
help_msg = """
使用方法:
    1 log
    all status
    管理应用编号 操作
操作:
    lock        锁配置文件
    unlock      解锁配置文件
    init        配置tomcat监听端口
    shell       配置webapp控制脚本
    status,start,restart, log,upgrade,stop 应用操作
"""
def main():
    app_list = []
    for index, app_name in enumerate(config_data, 1):
        print "\033[94m %s:  %s \033[0m" % (index, app_name)
        app_list.append(app_name)
    choice = raw_input("输入要管理的服务:  ")
    try:
        app_index = choice.split()[0]
        operate = choice.split()[1]
        if app_index.isdigit():
            app_index = int(app_index)
            if len(app_list) >= app_index > 0:
                app_name = app_list[app_index - 1]
                dash_board(app_name.split(), operate)
        elif app_index == "all":
            dash_board(app_list, operate)
    except ValueError and IndexError:
        customize_print("参数输入错误", 1)
        customize_print(help_msg)
if __name__ == '__main__':
    try:
        dash_board(sys.argv[1].split(), sys.argv[2])
    except IndexError:
        try:
            while True:
                main()
        except KeyboardInterrupt:
            customize_print("Bye!")

0x02 开始初始化部署

执行tomcat_manager

all init 自动初始化部署所有项目, 其他具体使用方法见帮助信息

标签:部署Tomcat 发布于:2019-10-22 23:53:01