作为一个Python菜鸟,在了解到这门语言的一些基础和优点之后,就想着怎么用这门语言来使自己的工作一步步向自动化推进,我首先想到的就是一个java后端经常干的事儿——打包,部署,重启服务。我的开发环境是windows,服务器是linux。以下是我的实现思路:
1、切换到项目目录,clean,打包,切换到jar包目录
2、上传jar包到服务器(Linux)的指定路径
3、停止应用进程,启动应用进程
参照上述实现思路我分成四个步骤完成我的想法:
1、我的项目用的是maven管理依赖和打包,所以第一步我先实现了进入项目目录并用maven进行clean和打包,然后切换到打好的jar包,此处用到了Python的os库
import os
os.chdir('D:\\user\\proj\\backend_server')
print('当前:',os.getcwd())
os.system('mvn clean')
print('clean完成'.center(100,'='))
os.system('mvn package')
print('package完成'.center(100,'='))
local_dir = 'D:\\user\\proj\\backend_server\\target'
os.chdir(local_dir)
print('切换至target',os.getcwd())
2、打包的时长需要看代码量和项目复杂程度。切换到打好包的路径之后,就是把打好的jar包上传到linux服务器指定路径上,此处需要用到paramiko和os,local_dir是本地jar包路径,remote_dir是服务器目标路径,hostname和jars分别是服务器ip和需要上传到jar包,可以支持多个服务器上传
import datetime
import os
import paramiko
hostname = ['102.12.43.11', '102.12.43.12']
port = 22
username = 'root'
password = '123456'
jars = ['jar1.jar', 'jar2.jar']
def upload(local_dir, remote_dir):
try:
for host in hostname:
t = paramiko.Transport((host, port))
t.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(t)
print('开始上传文件:%s' % datetime.datetime.now())
for root, dirs, files in os.walk(local_dir):
for file in files:
filename = os.path.join(root, file)
a = filename.replace(local_dir, '').replace('\\', '/').lstrip('/')
if a in jars:
remote_file = os.path.join(remote_dir, a)
try:
sftp.put(filename, remote_file)
except Exception as e:
sftp.mkdir(os.path.split(remote_dir)[0])
sftp.put(filename, remote_file)
print('上传成功!')
sftp.close()
t.close()
except Exception as e:
print(e)
3、上传完成之后就是重启应用,这里我用的方法可能有点儿笨,我先依据关键字查到几个进程,再依据启动用户和详细的关键字定位到了具体的进程,然后kill -9,再启动应用。启动脚本是事先写好的sh文件
import datetime
import os
import time
import paramiko
hostname = ['102.12.43.11', '102.12.43.12']
port = 22
username = 'root'
password = '123456'
jars = ['jar1.jar', 'jar2.jar']
def do_connect(host):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=host, port=port, username=username, password=password)
return client
def do_command1(host, command):
client = do_connect(host)
stdin, stdout, stderr = client.exec_command(command)
res, err = stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
result = res if res else err
print('执行成功'.center(100, '='))
print(result)
client.close()
return result
# 本来使用上面的方法用来启动应用的,结果不好使,不知道为啥
# 所以加了下面这个方法,并且启动之后需要暂停1到2秒才可以
def do_command2(host, command):
client = do_connect(host)
shell = client.invoke_shell()
shell.send(command)
while not shell.recv_ready():
pass
ouput = shell.recv(4096).decode('utf-8')
if 'error' in ouput:
print(ouput)
else:
print('运行成功!')
time.sleep(2)# 暂停,为了启动成功
client.close()
def restart_app(host):
pid = do_command1(host, 'ps -ef | grep app_name')
pid = pid.split('\r\n')
for v in pid:
if '/usr/local/app_name/jar1.jar' in v:
print(v)
v = v.split(' ')
for st in v:
if st != 'root' and st != '':
do_command1(host, 'kill -9 %s' % st)
print('app_name停止'.center(100, '='))
break
break
do_command2(host, 'bash /usr/local/app_name/start.sh\n')
for host in hostname:
restart_app(host)
4、应用重启成功之后就可以把本地的jar包clean掉了
上述内容是我目前正在用的,还有优化空间,后期打算把maven换成gradle试试,如果能增量打包上传重启的话那就太好了!
当然,上述步骤只是针对后端,如果要做vue前端的话也是可以的,需要把第一步的打包脚本换成vue的打包脚本,另外再加上上传前压缩步骤和上传后备份和解压缩步骤就可以了