上一节已经分析了tomcat多实例的原理,这节只需按着那思路实现自动化脚本即可。
一、思路规划
最终安装完成的目录:
- app:根目录;
- servers:放置所有安装的容器,包含tomcat、nginx等等,以实例名区分;
- tomcat:放置官方tomcat的安装原文件(如果是nginx,就放置在nginx目录);
- deploytool:放置容器管理脚本(启停),后面会分析它的具体结构。
二、自动化部署脚本实现
部署工具目录结构:
- deploytool:放置实例管理器脚本,直接整个复制过去
- install:放置要安装的软件
其中tomcat:放置tomcat相关
nginx:放置nginx相关
config:放置通用配置文件 - deploy.py:自动部署脚本
1、 tomcat-server.xml
三个重要的占位符,安装时会用具体内容替换:
shutdownport:关闭端口
port:监听端口
appBase:应用部署目录
这些内容最后会输出到实例的 server.xml 文件中
<Server port="$shutdownport" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener" />
<!--Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" /-->
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
<GlobalNamingResources>
<!-- Used by Manager webapp -->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="$port" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" minSpareThreads="25"
enableLookups="false" redirectPort="8443" acceptCount="200"
connectionTimeout="40000"
disableUploadTimeout="false"/>
<!-- This is here for compatibility only, not required -->
<!-- <Connector port="59009" protocol="AJP/1.3" /> -->
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase" />
<Host name="localhost" appBase="$appBase" unpackWARs="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" rotatable="true"
directory="logs" prefix="access.log"
pattern="%h %{X-FORWARDED-FOR}i %l %u %t %r %s %b %q %{User-Agent}i %T %D" resolveHosts="false"/>
</Host>
</Engine>
</Service>
</Server>
2、tomcat-install.conf
实例基本属性,每个安装好的实例,都会生成以实例名命名的conf文件,存放在 deploytool -> conf 目录,例如 tm_adidas 实例,就会自动生成一个 tm_adidas.conf 文件,到时实例管理器就是根据这个文件的内容进行启动/停止实例。
这些以 $ 开头的占位符,在安装完成后会被具体内容替换
[tomcat]
app_name = $appname
app_root_dir = $approotdir
app_port = $port
app_shutdown_port = $shutdownport
JAVA_HOME = $jdk_home
CATALINA_HOME = $catalina_home
CATALINA_BASE = $catalina_base
CATALINA_TMPDIR = $catalina_temp
CATALINA_PID = $catalina_base/$appname.pid
JAVA_OPTS = "-Xms2048m -Xmx2048m -XX:MaxNewSize=128m -XX:MaxPermSize=128m -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -verbose:gc -Xloggc:$catalina_base/logs/gc.log -Dtomcat.name=$appname"
以下就是 tm_adidas 实例安装完成后生成的 tm_adidas.conf 内容:
[tomcat]
app_name = tm_adidas
app_root_dir = /home/admin/app/servers/tm_adidas
app_port = 30086
app_shutdown_port = 40086
JAVA_HOME = /home/admin/app/tomcat/jdk1.8.0_162
CATALINA_HOME = /home/admin/app/tomcat/apache-tomcat-8.0.50
CATALINA_BASE = /home/admin/app/servers/tm_adidas
CATALINA_TMPDIR = /home/admin/app/servers/tm_adidas/temp
CATALINA_PID = /home/admin/app/servers/tm_adidas/tm_adidas.pid
JAVA_OPTS = "-Xms2048m -Xmx2048m -XX:MaxNewSize=128m -XX:MaxPermSize=128m -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -verbose:gc -Xloggc:/home/admin/app/servers/tm_adidas/logs/gc.log -Dtomcat.name=tm_adidas"
3、deploy.py
自动化部署脚本,就是根据前面的思路,把该复制的文件复制,把该替换内容替换。
#coding=utf-8
import os
import sys
import shutil
##install dir
BASE_DIR = "/home/admin" ##the base dir of installed software
APP_DIR = BASE_DIR + os.sep + "app"
SERVER_DIR = APP_DIR + os.sep + "servers"
TOMCAT_DIR = APP_DIR + os.sep + "tomcat"
NGINX_DIR = APP_DIR + os.sep + "nginx"
DEPLOYTOOL_DIR = APP_DIR + os.sep + "deploytool"
##software dir
now_dir = os.getcwd() ##the dir now
deploytool_dir = now_dir + os.sep + "deploytool"
software_dir = now_dir + os.sep + "install"
tomcat_dir = software_dir + os.sep + "tomcat"
nginx_dir = software_dir + os.sep + "nginx"
##install the tomcat
def deployTomcat(appname="tomcat",port=8080,shutdown_port=8005):
##copy the software
if not os.path.exists(TOMCAT_DIR) :
shutil.copytree(tomcat_dir,TOMCAT_DIR)
##unzip the *.tar.gz files
tar_cmd = "cd %s;ls *.tar.gz | xargs -n1 tar -zxvf" % TOMCAT_DIR
os.system(tar_cmd)
if not os.path.exists(DEPLOYTOOL_DIR):
shutil.copytree(deploytool_dir,DEPLOYTOOL_DIR)
##get tomcat/jdk dir
tomcat_version_dir = ""
jdk_version_dir = ""
for dir in os.listdir(TOMCAT_DIR):
if os.path.isdir(os.path.join(TOMCAT_DIR, dir)):
if "jdk" in dir :
jdk_version_dir = TOMCAT_DIR + os.sep + dir
if "tomcat" in dir :
tomcat_version_dir = TOMCAT_DIR + os.sep + dir
if tomcat_version_dir == "" or jdk_version_dir == "" :
print "can not find software tomcat or jdk"
##create instance dir
instance_dir = SERVER_DIR + os.sep + appname
if not os.path.exists(instance_dir+os.sep+"conf"):
shutil.copytree(tomcat_version_dir+os.sep+"conf",instance_dir+os.sep+"conf")
if not os.path.exists(instance_dir+os.sep+"logs"):
os.makedirs(instance_dir+os.sep+"logs")
app_temp = instance_dir+os.sep+"temp"
if not os.path.exists(app_temp):
os.makedirs(app_temp)
if not os.path.exists(instance_dir+os.sep+"work"):
os.makedirs(instance_dir+os.sep+"work")
app_webapps = instance_dir+os.sep+"webapps"
if not os.path.exists(app_webapps):
os.makedirs(app_webapps)
##create server.xml
config_file = software_dir + os.sep + "config" + os.sep + "tomcat-server.xml"
tomcat_server_conf = instance_dir+os.sep+"conf" + os.sep + "server.xml"
with open(config_file) as source:
contens = source.read()
contens = contens.replace("$shutdownport",str(shutdown_port)).replace("$port",str(port)).replace("$appBase",app_webapps)
with open(tomcat_server_conf,"w") as des:
des.write(contens)
##create deploy conf file
deploy_file = software_dir + os.sep + "config" + os.sep + "tomcat-install.conf"
instance_deploy_file = DEPLOYTOOL_DIR + os.sep + "conf" + os.sep + appname + ".conf"
with open(deploy_file) as source:
contens = source.read()
contens = contens.replace("$appname",appname).replace("$approotdir",instance_dir).replace("$port",str(port)).replace("$shutdownport",str(shutdown_port))
contens = contens.replace("$jdk_home",jdk_version_dir).replace("$catalina_home",tomcat_version_dir).replace("$catalina_base",instance_dir).replace("$catalina_temp",app_temp)
with open(instance_deploy_file,"w") as des:
des.write(contens)
print "tomcat installed........"
##install the nginx
def deployNginx(appname="nginx",port=8000):
print appname,port
print "nginx installed........."
## main function
if __name__=='__main__':
print "Please intput your choice(1 or 2): 1.tomcat 2.nginx"
choice = input()
if choice == 1 :
print "installing tomcat ......."
appname = raw_input("input the appname:")
port = input("input the port:")
shutdown_port = input("input the shutdonw port:")
deployTomcat(appname,port,shutdown_port)
elif choice == 2 :
print "installing nginx ........"
appname = raw_input("input the appname:")
port = input("input the port:")
deployNginx(appname,port)
else :
print "your choice is error......"
sys.exit()
三、实例管理器脚本实现
1、目录结构
- bin:放置实例管理器脚本,serverctl.py
- lib:放置各种实例操作类的脚本
- conf:放置已安装实例的属性文件
2、TomcatOps.py (tomcat 操作类)
#coding=utf-8
import os
import sys
import ConfigParser
class TomcatOps(object):
## need the instance conf-file,like tm_adidas.conf
def __init__(self,conf_file):
self.conf_file = conf_file
##set tomcat instance env
def __setEnv(self):
## read the conf-file
config = ConfigParser.ConfigParser()
config.read(self.conf_file)
##get the properities
self.JAVA_HOME = config.get("tomcat", "JAVA_HOME")
self.CATALINA_HOME = config.get("tomcat", "CATALINA_HOME")
self.CATALINA_BASE = config.get("tomcat", "CATALINA_BASE")
self.CATALINA_TMPDIR = config.get("tomcat", "CATALINA_TMPDIR")
self.CATALINA_PID = config.get("tomcat", "CATALINA_PID")
self.JAVA_OPTS = config.get("tomcat", "JAVA_OPTS")
##build the shell command
self.env_cmd = '''export JAVA_HOME=%s;export CATALINA_HOME=%s;export CATALINA_BASE=%s;export CATALINA_TMPDIR=%s;export CATALINA_PID=%s;export JAVA_OPTS=%s;
''' % (self.JAVA_HOME, self.CATALINA_HOME, self.CATALINA_BASE, self.CATALINA_TMPDIR, self.CATALINA_PID, self.JAVA_OPTS)
## start the server
def start(self):
self.__setEnv()
start_sh = self.CATALINA_HOME + os.sep + "bin" + os.sep + "startup.sh"
cmd = self.env_cmd + start_sh
##call the shell command
os.system(cmd)
##stop the server
def stop(self):
self.__setEnv()
stop_sh = self.CATALINA_HOME + os.sep + "bin" + os.sep + "shutdown.sh"
cmd = self.env_cmd + stop_sh
##call the shell command
os.system(cmd)
2、serverctl.py
接收两个参数:
- 实例名:appname,需要根据实例名确定conf-file
- 动作:action,start or stop
#coding=utf-8
import sys
import os
import ConfigParser
sys.path.append("..")
from lib.TomcatOps import *
##main function
if __name__=='__main__':
if len(sys.argv) != 3 :
print "the args should like (appname action): tm_adidas start"
else :
appname = sys.argv[1]
action = sys.argv[2]
##the server conf file
conf_file = os.path.abspath('..') + os.sep + "conf" + os.sep + appname + ".conf"
if not os.path.exists(conf_file):
print "can not find install conf file,please check:"
print "conf_file:",conf_file
else :
config = ConfigParser.ConfigParser()
config.read(conf_file)
server_type = config.sections()[0]
##get the instance type,can be tomcat nginx and so on
if server_type == "tomcat" :
ops = TomcatOps(conf_file)
if action == "start" :
print action
ops.start()
elif action == "stop" :
print action
ops.stop()
else:
print "can not find this action, please check...."
if server_type == "nginx" :
print "nginx"
启停例子:
cd /home/admin/app/deploytool/bin/ ##需要先到bin目录,要不无法找到conf-file,后期看如何优化
python serverctl.py tm_adidas start ##启动实例
python serverctl.py tm_adidas stop ##停止实例
四、结论
目前只实现了tomcat,后续会实现nginx,思路一样。
哪位大神如果有高见,请指教,非常感谢!!!!