python 不让系统杀掉_发布系统有那么难么?

07dd84e4c7ee01bb7c967d49ef3c5c8e.png

必要性

如果一个上点规模的公司,技术团队有什么值得一做的系统,那么发布系统算一个。

jenkins用的好好的,为什么要自己搞呢?总结下来,有下面几点原因:

1、 每个公司的流程和技术栈都是不一样的,生搬硬套,就像便秘一样不顺畅。

2、 发布系统技术开发成本不高,很容易搞。你要是觉得难搞,那一定是卡在复杂的公司人员环境和流程上。

3、 jenkins这样的工具要想做个增强功能,不比自己开发简单。比如加个审批环节,做个表单嵌入什么的。

一句话,自己搞个套餐不比改造现成的难。

概要

开发一个发布系统是很简单的,虽然需要全栈的知识(前端、后台、脚本)。有多简单呢?我们提供了两个人力,只花了10个工作日就全部完成了。看完本文,你要是觉得不简单,那就是我们太牛掰了(囧),毕竟也是见识过七八个高开去做同样事情的豪华阵容。

流程上是帮不了你什么忙了,但在技术上,我将奉上个人觉得很不错的一套实现。如果你的架构是基于SpringCloud的,你会发现很贴心。发布系统主要有以下功能:构建模块、部署模块、权限管理模块、审计模块

构建模块

a32b738c557892c12b7cd59e8d0f882d.png

用户登录系统后,会看到所有拥有权限的项目列表。点点击前往,则进入构建页面。

68dfc6b1bf22679c98a20b834cf8ce0c.png

构建模块其实是非常简单的。不论你是用maven,还是gradle,再或者cnpmg++等,都是通过传入一堆参数到脚本中执行。在这里推荐使用python脚本进行更多控制。

构建者可以选择任何一次提交进行构建。构建成功后,会自动给提交打tag(也可以自定义tag)。同一个项目不允许同时打包。构建失败,可以重新进行构建,构建者会看到实时滚动的日志。这里有两个技术点:

1) 如何获取git的提交记录并进行切换?

2) 如何显示滚动日志?

获取gitlab的提交记录

拿gitlab来说(因为用的最多)。加入gitlab的maven即可使用。

<dependency>

    <groupId>org.gitlab</groupId>

    <artifactId>java-gitlab-api</artifactId>

    <version>4.1.0</version>

</dependency>

获取最近提交记录。

api.getAllCommits(projectId,page, branch)

打tag

api.addTag(projectId, tagName, hash, tagTitle, tagContent);

滚动日志实现

见本公众号文章《滚动日志的实现》

部署模块

很多发布系统让人很不爽的一点,就是不支持单台或者多台发布,不方便而且风险大。

部署页面只显示已经打包成功的记录,按照提交时间倒序显示。支持重新部署,不管是上次部署成功还是失败。部署界面如下:

2bbc37968d0db3873f8e7ce36509934d.png

点击部署按钮,即可显示部署机器列表,可以选择一个或者多个进行部署。

995ad1b242c3f20232820437fb9539a1.png

部署记录都会按照打包记录进行分组,显示在日志列中。同一次部署,如果有一台部署失败,则默认部署整体部署失败,可以从部署日志判断当前的部署状态。

可以看到系统其实是没有回滚的概念的,只有部署哪个版本的概念。一个服务可能有上百台机器,如何更优雅的显示多版本共存的关系,有条件的团队是不会放过这个改进的。

SpringCloud的部署过程

af28c58d3c1b39a8a3fa069c3a81558b.png

权限管理

github上有很多开源的实现,随便搬弄一套集成即可。我们主要谈一下权限理念。

权限设计有两个要点。第一不能阻碍研发的开发效率,第二要严控线上的安全。所以线上和非线上环境是分开设计的。

1) 一个系统的用户,要么是超级管理员(就是神马都能干的那总);要么是带有线上权限标识的用户;再就是普通用户了。

2) 一个用户,要么是某个项目的成员,要么不是

权限图如下:

7fffbc15a1bfa8e0271db61b8e98d9bb.png

操作都会被记录进操作历史,并且发送邮件(或者其他hook):

1) 修改项目,发送给项目成员所有人

2) 构建项目,发送给构建者构建结果

3) 部署项目,发送给项目成员所有人

所有的操作记录,在项目中都可查。

6c700d4dc3898bbb766baf9fcec5abde.png

脚本

发布系统的web端,不过是套层皮囊。真正去执行的,还是我们的脚本。

使用python脚本进行构建和发布,是非常方便的。有些java开发人员对脚本不是很熟,我这里挑比较重要的点说明一下。

执行过程显示

建议使用logging模块控制。效果见下图。

import logging

def setup_logging():

    root = logging.getLogger()

    root.setLevel(logging.DEBUG)

    ch = logging.StreamHandler(sys.stdout)

    ch.setLevel(logging.DEBUG)

    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    ch.setFormatter(formatter)

    root.addHandler(ch)

aab1f9cbf87d386ad70b69dee571712c.png

脚本异常记录

默认python执行异常是不输出到stdout的,我们需要强行转换一下。

import sys

import traceback

try:

    setup_logging()

    #...

except Exception as e:

    exc_type, exc_value, exc_traceback_obj = sys.exc_info()

    traceback.print_exception(exc_type, exc_value, exc_traceback_obj, limit=2, file=sys.stdout)

远程执行

发布系统的机器应该都做了免密登录。通过

ssh -t "su - sth"

可以切换到任何一个用户在远端执行程序。

但实践证明,通过python的subprocess模块执行存在诸多问题。所以我们才用了paramiko库进行了远程调用。

s = paramiko.SSHClient()

s.load_system_host_keys()

s.connect(srv, 22 )

(stdin, stdout, stderr) = s.exec_command(cmd)

last_line = ""

for line in stdout.readlines():

    last_line = line

    print( line)

    s.close()

安全的杀死进程

大家都应该知道kill -15kill -9的区别。以下脚本让程序等待10秒,然后使用kill -9杀掉她。

注意:以下脚本有巨坑~,一定要传参
n=0

while [[ $n  -lt  10 ]]

do

    let "n++"

    ex=`ps aux|grep /${flag}|grep -v grep | grep -v sc. | awk '{print $2}' `

    echo $ex

    if [[ $ex == "" ]]

    then

        echo "program not exist"

        break

    else

        echo "send kill -15 to below:"

        echo $ex

        ps aux|grep /${flag}|grep -v grep | grep -v sc. | awk '{print $2}' |  xargs kill -15

        sleep 1

    fi

    if [[ $n  -eq 10 ]]

    then

        # after 10s , try to send kill -9

        ps aux|grep /${flag}|grep -v grep | grep -v sc. | awk '{print $2}' |  xargs kill -9

    fi

done

##start jar

echo "start jar"

nohup  -jar $jar  >/dev/null 2>&1 &

echo "restart ${flag} !!!"

sleep 2

ex=`ps aux|grep /${flag}|grep -v grep | grep -v sc. | awk '{print $2}' `

if [[ $ex == "" ]]

then

    echo "Fail"

else

    echo "new PID is "

    echo $ex

    echo "OK"

fi

exit

前端

vue干这个大材小用了。我们选择了后台都熟悉的bootstrap,配上一个比较古老好看的AdminLTE框架。

但这么多页面写起来也是非常浪费时间的,所以我们也集成了ejs模版引擎。

对技术团队的建议

1) 要信得过自己团队,信得过自己。如果公司环境复杂。少开会去讨论,少扯皮。先闭关锁国再改革开放。先闭门造车,做出个东东来,再让各位大爷们品头论足,进行修改。毕竟也花不了多长时间,原型驱动再好不过了,你又不是一次性做个百分项目。

2) 设计时一定要考虑项目类型的多样性和分布式。别等着需求来了,量来了,把你连根拔起。

3) 自动化虽然好,也要准备好应急的手动化方式。如果CTO亲自给你来电了,这并不见得是一件好事。

ce86ed36ef38ec601f8ef68fa0ac2459.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值