简单介绍
项目是属于Java项目,生产环境是在阿里云,前端有一个负载均衡,后端2台线上服务器。如果后端服务器较多,原理是一样的。首先,将编译后的包放到所有线上环境,然后移除负载均衡中其中一台服务器,对该服务器对应的服务进行停止,更新线上包,然后启动,测试,最后把服务器添加到负载均衡中。再执行剩余的机器,这样上线不会影响到所有的机器,业务可以不间断提供服务。注:该脚本有参考别人的思想
#coding:utf-8
#
from fabric.api import *
from fabric.utils import abort
from fabric.api import env, local, roles, hosts
from fabric.utils import abort
from fabric.operations import sudo, run, put
from fabric.context_managers import cd, settings
from fabric.tasks import execute
from fabric.contrib.files import exists
from fabric import context_managers
import time
import json
import urllib
env.host_one = ['a.a.a.a']
env.host_remaining = ['b.b.b.b']
env.host_tmp = ['']
env.host_all = env.host_one + env.host_remaining
env.user = 'admin'
env.password = ''
env.app_name = 'myproject'
env.app_port = '9006'
env.app_status_cmd = 'http://localhost:%s/v1/status' %env.app_port
env.java_home = '/usr/local/java/jdk1.8.0_181'
env.app_home = '/home/admin/deploy/%s' %env.app_name
env.local_app_home = '/home/admin/build/repo_gogs/%s' %env.app_name
env.app_sh = '%s/sh' %env.local_app_home
#env.pid_file = '%s/pid' %env.app_home
#env.app_log = '%s/logs' %env.app_home
#env.app_out = '%s/%s.out.log' %(env.app_log,env.app_name)
#env.java_opt = '-Xms2048m -Xmx2048m -XX:MaxDirectMemorySize=128m -Xmn1024m -XX:SurvivorRatio=10 -XX:+PrintGCDetails -XX:MetaspaceSize=72m -Xloggc:%s/gc.log -XX:+PrintGCDateStamps -XX:-OmitStackTraceInFastThrow' % env.app_log
env.Penv = 'ali'
#env.RELEASE_TARGET = 'biezz@192.168.174.138:/home/biezz/release'
env.build_dir = '/home/admin/build/repo_gogs/%s/build/distributions' %env.app_name
env.release_dir = '/home/admin/release'
env.release_branch = 'release'
env.slb_ids = ['lb-bp12wgm8lwhaaaaaaaaaa'] #阿里云实例ID
env.slb_host = 'http://192.168.3.55:8086' #实例操作接口,这个需要根据具体的实际情况来,这里是调用自己写的接口,亦可参考阿里云负载均衡api
#env.slb_host = 'http://slb.aliyuncs.com'
#env.access_key = 'TMP.AQGXgOn8WuetlM_SgLHmSbGOcGOlA4QkSjyeBDOBmHN2S13Ltn6bOvfco1n9ADAtAhUA7CjYA9nfadPGQAljN33YwG0AX2YCFBKPzcxoiT2WjOC9COgjw1laXhr0'
#env.backend_server = 'i-bp1aqu5t6zc4olokrxg5'
env.stop_wait_time = 15
env.status_check_interval = 5
env.status_check_times = 20
env.notify_api = 'http://10.171.232.204:8086/sendWeixinNotify?' #通知接口
def rnotify(msg=''):
print msg
param = {'auth':'evilognuf', 'agentid':10, 'message': (env.app_name + '===>' + msg)}
local('curl \'%s\'' % (env.notify_api + urllib.urlencode(param)))
#local('curl ' %(urllib.url))
#@hosts(env.host_tmp)
#def test():
# " just for test "
# rnotify('begin testDate')
# pass
def first():
rnotify('first begin ...')
execute(pull)
execute(build)
execute(release)
execute(deploy_one)
rnotify('first end ...')
def left():
"""deploy to remaining nodes"""
rnotify('left begin ...')
execute(deploy_remaining)
rnotify('left end ...')
def pull():
with lcd(env.local_app_home):
local("git fetch")
local('git reset --hard remotes/origin/%s' %env.release_branch)
def build():
with lcd(env.local_app_home):
local('gradle -Penv=%s clean distTar' %env.Penv)
@hosts(env.host_one)
def release():
with lcd(env.app_home):
#local('scp build/distributions/*.tar %s' %env.RELEASE_TARGET)
pass
run('mkdir -p ' + env.release_dir)
put(env.build_dir + '/*',env.release_dir)
def deploy_one(host=''):
if not host:
host = env.host_one[0]
env.hosts = [host]
execute(offline,innerIp=host)
execute(restart)
execute(check_status)
execute(online,innerIp=host)
def deploy_remaining():
"""run deploy_one on remaining nodes"""
for host in env.host_remaining:
execute(deploy_one, host)
def check_status():
"""check app status"""
ok = ''
times = 1
with settings(warn_only = True):
while times < env.status_check_times:
ok = run(env.app_status_cmd)
#ok = 'ok'
if ok == 'reloading':
return True
times = times + 1
print('status != ok. wait for %s seconds to check again ' % str(env.status_check_interval))
time.sleep(env.status_check_interval)
abort('check status failed after %s retires!' % str(times))
def offline(innerIp=''):
slb_remove(innerIp)
print('wait for %s seconds before stop' % str(env.stop_wait_time))
time.sleep(env.stop_wait_time)
def online(innerIp=''):
slb_add(innerIp)
def restart(zipfilename='', rollback=False):
#run('mkdir -p %s' %env.app_home)
#put(env.app_sh + '/*',env.app_home)
with cd('/home/admin/deploy/%s' %env.app_name):
#run('chmod +x deploy.sh env.sh restart.sh start.sh stop.sh')
if not zipfilename:
if rollback:
zipfilename = run('ls -t %s |head -2|tail -1' % env.release_dir)
else:
zipfilename = run('ls -t %s |head -1' % env.release_dir)
if not zipfilename:
abort('no tar found! can not restart! rollback: %s' % str(rollback))
run('cp %s/%s ./' %(env.release_dir,zipfilename))
run('./deploy.sh ' + zipfilename)
run('sh stop.sh',pty=False)
run('sh start.sh',pty=False)
def slb_add(innerIps=''):
slb_action('AddBackendServer', innerIps)
def slb_remove(innerIps=''):
slb_action('RemoveBackendServer', innerIps)
def slb_action(action='', innerIps=''):
for id in env.slb_ids:
response = run("curl '%s/slb/%s?auth=evilognuf&LoadBalancerId=%s&innerIps=%s'" % (env.slb_host, action, id, innerIps))
#response = 'ok'
if response != "ok":
abort("response not OK: %s" % response)
pass