ecFlow学习笔记:服务检查系统

目录

前两年我编写的一些监控程序,往往部署在高性能计算机外的主机上,使用SSH协议或者TCP端口获取监控数据。 但这样的程序存在不少问题。

高性能计算的SSH连接并不是百分之百可靠的。为此,我在应用中设置了重新连接的机制。

ecFlow的API没有对数据进行压缩,对于挂载任务数比较多的服务(例如集合预报和产品后处理系统等),获取状态数据很慢。 为此,我将ecFlow的采集程序放到了高性能计算机的登陆节点上,类似ecflow服务程序。 但我写的程序缺乏像ecflow服务的稳定性,可能会因为不明原因退出。 再加上最近几天,科研分区的登陆节点经常出问题,我需要类似Supervisor一样监视程序运行情况的机制。

虽然我们单位核心的业务系统都运行在高性能计算机上,但我们只是高性能计算机的一个用户,只有普通用户的权限。 所以我们无法使用操作系统级的Service监控。

本文介绍如何使用ecFlow实现定时检查后台程序的功能,实现对登录节点上的后台程序进行监控。

后台运行程序

首先需要将程序在后台运行,使用 nohup 实现。

下面的代码在后台运行 nwpc_message_client 程序,并将标准输出和标准错误输出打印到同一个日志文件中。

nohup ${message_client_base}/bin/nwpc_message_client \
    broker \
    --address=${message_address} \
    >${message_broker_data}/log/log.${current_log_name} 2>&1 &

检查进程

监控程序首先要检查进程是否存在,

pgrep 会返回所有符合筛选条件的进程号,如果没有匹配的,退出码为1。 如果后台程序同时只可能有一个程序在运行时,就可以使用 pgrep 实现进程检查的功能。

下面代码检查是否有包含nwpc_message_client broker的进程,如果不存在则重启,如果存在则忽略。

if ! pgrep -f "nwpc_message_client broker" &> /dev/null 2>&1; then
    echo "checking nwpc_message_client...failed"
    # restart program
else
    echo "checking nwpc_message_client...successful"
fi

定时检查

最后我们需要定时检查进程,ecFlow 提供的 Cron 可以实现。

我们业务的 ecFlow 系统都是每天滚动循环的。整个系统的所有任务都完成后,日期才会增加1天。

但设置 Cron 的任务永远不会完成,所以不能使用上述的日期滚动机制。 不过好在检查程序不依赖于具体时间,可以直接使用系统时间。

下面代码创建一个定时检查的任务,从 00:01 到 23:58 逐5分钟运行一次。

with suite.add_family("message") as fm_message:
    with fm_message.add_task("check_broker") as tk_broker:
        cron = Cron("00:01 23:58 00:05")
        tk_broker.add_cron(cron)
        tk_broker.add_variable(common.sjob())
        tk_broker.add_variable("ECF_SCRIPT_CMD", "cat {ecf_files}/check_message_broker.ecf".format(
            ecf_files=self.suite_attrs['ECF_FILES']
        ))

ecflow 系统截图如下:

service_checker 的 ecflow_ui 截图