前言
之前在 使用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,确保如果高峰期某个节点发生卡顿可以在一分钟内自动恢复,这样就免去了人肉运维,并且又在生产环境增加了两个实例,好长一段时间都没有反馈卡顿的问题了