单台机器部署多个 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 "33[94m $app is running PID:$PID"
running=`netstat -ntlp|grep $PID|grep 127.0.0.1`
if [ -n "$running" ];then
echo -e "33[92m $app is provide services33[0m "
else
echo -e "33[93m $app is running but not provide services33[0m"
fi
return 0
else
echo -e "33[91m $app is dead33[0m "
return 1
fi
}
start() {
check
if [ $? -eq 1 ];then
echo -e "33[94m Start $app 33[0m"
$CATALINA_HOME/bin/startup.sh >/dev/null 2>&1
fi
}
stop() {
check
if [ $? -eq 0 ];then
echo -e "33[94m Stop $app33[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("33[91m [ERROR]: %s 33[0m" % msg)
elif stat == 0:
print("33[92m [INFO]: %s 33[0m" % msg)
elif stat == 2:
print("33[93m [DEBUG]: %s 33[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 "33[94m %s: %s 33[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 自动初始化部署所有项目, 其他具体使用方法见帮助信息