你如何 运行 一个 pm2 cron 作业而不关心它启动的进程是否已经启动?

How do you run a pm2 cron job without caring if a process it kicks off has started or not?

说明一下我的情况。我有一个 pm2 cron 脚本,我 运行 使用:

pm2 start clear-redis-state-cron.js -n clearState --cron '0 0/1 * 1/1 * *'

这个运行的js脚本叫clear-redis-state-cron.js就好了。

这个脚本的作用是停止进程p1和进程p2。然后它 运行 是一个 lua redis 脚本,从数据库中清除一些键。这一切都很好,但为了简洁起见,我把它放在这里。

var crs = require('./clear-redis-state'),
    pm2 = require('pm2');

pm2.connect(function(err) {
    pm2.stop('component1');
    pm2.stop('component2');

    crs.clear();

    pm2.restart(__dirname + '/../../node_modules/component1/index.js', { name: 'c1' }, function (err, proc) {
        if (err) throw new Error('err');
    });

    pm2.restart(__dirname + '/../../node_modules/component2/index.js', { name: 'c2' }, function (err, proc) {
        if (err) throw new Error('err');
    });
});

它运行是一个clear() js函数,定义在这里:

var config = require('common/lib/config'),
    log = require('common/lib/logger'),
    redis = require('common/lib/redis'),
    ScriptTo = require('redis-scripto');

exports.clear = function() {
    log.init();

    if (!config.isSet()) {
        // Use local config
        var configPath = require('path').join(__dirname, '../../app/config');
        config.load(configPath);
    }

    redis.init(config.get('redis'));

    var scriptManager = new ScriptTo(redis.getClient());
    scriptManager.loadFromDir(__dirname + '/scripts');

    scriptManager.run('clear-state', [], [], function(err, results) {
        logError(err);
        console.log('results:', results);
    });

    function logError(err) {
        if (err !== null) {
            console.log('Error loading lua script merge-keys: ', err);
        }
    };
}

我对此没有问题。但是,它似乎在开始时崩溃。假设我已经有 pm2 运行ning 两个进程 component1 和 component2 分别称为 p1 和 p2。当我 运行 使用 --no-daemon 启动 cron 时,为什么会出现以下错误?

... clear-redis-state-cron.js had too many unstable restarts (15). Stopped. "errored"

我的直觉是进程启动错误关闭并因此处于错误状态所以当它试图关闭它时它已经关闭,但是因为 pm2 假设出现问题 cron 进程停止.

知道我做错了什么吗?

编辑:我尝试像这样承诺关闭 pm2 逻辑:

pm2.connect(function(err) {

    Promise.resolve(ops.stop('component1'))
       .then(ops.stop('component2'))
       .then(ops.clear)
       .then(ops.restart(__dirname + '/../../node_modules/component1/index.js', { name: 'component1' }))
       .then(ops.restart(__dirname + '/../../node_modules/component2/index.js', { name: 'component2' }))
       .catch(logFailureToStop);
});

var logFailureToStop = function (err) {
    console.log('Failed to stop ', err);
};

停止 运行ning 进程后结果如下:

$ pm2 list
┌───────────┬────┬──────┬───────┬─────────┬───────────┬────────┬─────────────┬──────────┐
│ App name  │ id │ mode │ PID   │ status  │ restarted │ uptime │      memory │ watching │
├───────────┼────┼──────┼───────┼─────────┼───────────┼────────┼─────────────┼──────────┤
│ component2│ 0  │ fork │ 0     │ stopped │        17 │ 0      │      0 B    │ disabled │
│ component1│ 1  │ fork │ 18769 │ online  │        31 │ 19s    │ 30.539 MB   │ disabled │

最终成功解决了这个问题。

这个问题是因为我有一个监听 SIGTERM 的 on handler 事件。显然这些会干扰 PM2,因此您需要改用 gracefulStop/gracefulRestart 命令。

参见:https://github.com/Unitech/PM2/issues/304