前言

之前在 使用Python定时清理运行超时的pdflatex僵尸进程 博文中我采用python脚本开启定时任务清理pdflatex僵尸进程,线上4u2G的k8s pod部署了3个,pdflatex执行过程是是比较耗cpu的,内存占用微乎其微,但是pod在实际在运行中偶尔还是会出现一些问题

问题

问题一:K8s POD存储超过100M,POD down了,但是资源没有被回收,导致k8s命名空间资源被空耗
问题二:每隔一段时间偶发性单个pod进程积压,定时清理脚本会down掉,清理任务无法正常运行
问题三:主要是你还不知道那个pod有问题,所有的请求都是通过k8s负载均衡到各个pod中去,一旦路由到有问题的pod,请求就挂起了,你得本地配置kubectl进入到生产的pod中去查看进程,找到问题pod,手动清理进程然后重启清理任务,但是清理完你会发现过几天又会出现同样的问题,人肉运维负担很重

解决

问题一
第一个问题的产生是由于我们在执行pdflatex时候会生成tex和pdf文件,当我们正常执行完成之后,会清理这些文件,但是如果是僵尸进程的话,我们在清理进程的时候也需要把进程对应的文件清理掉,清理脚本如下:

def clean_files():
    nowtime = datetime.datetime.now()
    # 获取时间差5分钟(因为文件创建超过5分钟的要删除掉)
    deltime = datetime.timedelta(seconds=120)
    # 获取当前时间减去5分钟时间差
    nd = nowtime - deltime
    path = "/home/"
    files = os.listdir(path)
    for file in files:
        filectime = get_filectime(path + file)
        if filectime < nd and len(file) > 32:
            os.remove(path + file)
            logging.info("清理文件:"+file)

问题二
第二个问题比较严重,产生的原因有如下几个:

1、clean_files 偶发性异常,导致定时任务挂掉,这里已经判断了文件创建时间5分钟在执行删除偶发性出现文件找不到的异常,导致清理定时任务挂掉,判断是由于pdflatex进程积压导致clean_files一直没有拿到cpu的执行权,当执行os.remove的时候那些“不正常”的文件被“正常”的进程清理掉了,导致报错
2、p.terminate()方法没有生效,这一块应当是texlive的bug导致,之前的清理进程我在部署生产的时候放到10分钟执行一次,但是由于pdflatex的cpu消耗较多,如果有较多的错误语法的转换或者稍高一点的并发,都是导致短暂是cpu压力陡增,这时部分pdflatex进程已经假死,直接给进程发送terminate指令,进程也无法响应

解决:第一个问题比较简单,try catch包裹一下,一次执行失败下次执行即可,无伤大雅;第二问题,问题没有定位出来,偶发性的,有的节点运行了几个月也都没有问题,但是就是偶尔有个新节点老是喜欢出问题,没辙了只能暴力点,上代码

def process_checker():
    try:
        logging.info("pdflatex进程清理")
        os.system("kill -9 `ps -ef | grep pdflatex | grep pdftex | awk '{print $1}'`")
    except Exception as e:
        logging.error("清理进程出错")

    try:
        clean_files()
        logging.info("文件清理成功")
    except Exception as e:
        logging.error("清理文件出错")

其实一开始我用的是kill想平滑一点,但是运行一段时间发现根本kill不掉,所以加了个 -9 来终结那些令人糟心的进程

定时任务也去掉了,一切从简,while循环,每次睡60秒,循环里的代码try catch,确保如果高峰期某个节点发生卡顿可以在一分钟内自动恢复,这样就免去了人肉运维,并且又在生产环境增加了两个实例,好长一段时间都没有反馈卡顿的问题了