node.js - 如何在 Linux Ubuntu 中将 NodeJS 应用程序作为 crontab 运行?

标签 node.js linux ubuntu cron

我有一个包含 cron 的 Node 应用程序。现在,它在 Ubuntu 服务器上完美运行。

enter image description here

索引.js

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const router = express.Router();
const cron = require('node-cron');

const nodemailer = require('nodemailer');

const request = require('request');
const cheerio = require('cheerio');
const FCM = require('fcm-node');


app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

var admin = require('firebase-admin');
var serviceAccount = require('./serviceAccountKey.json');
var fcm = new FCM(serviceAccount);
var firebase = admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: 'https://ios-base-88.firebaseio.com'
});

const FETCH_DOMAIN = 'https://finance.yahoo.com/lookup/all?s=';

router.get('/', (req, res) => {
    res.json({
        msg: 'Something happening'
    })
});

const checkPrice = () => {
    var db = admin.database();
    var ref = db.ref('alerts');
    ref.on('value', (snapshot) => {
        console.log(snapshot.val());
        if (snapshot.val()) {
            snapshot.forEach((child) => {
                trackPrice(child);
            })
        }
    }, (error) => {
        console.log('The read failed: ' + error.code);
    })
}

const sendEmailNotification = async (email, text, snapshot) => {
    let transporter = nodemailer.createTransport({
        service: 'gmail',
        auth: {
            user: 'email@gmail.com',
            pass: '***'
        }
    });

    let mailOptions = {
        from: 'email@gmail.com',
        to: email,
        subject: text,
        html: text
    };

    let info = await transporter.sendMail(mailOptions);
    // update notify params 
    var db = admin.database();
    var ref = db.ref('alert').child(snapshot.key);
    const company = snapshot.val();
    ref.update({
        companyName: company.companyName,
        price:  company.price,
        ticker: company.ticker,
        notified: true
    })
    console.log('Message sent: %s', info.messageId);
    console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
}

const trackPrice = (child) => {
    var snapshot = child.val();
    const company = snapshot.companyName;
    const price = snapshot.price;
    const url = `${FETCH_DOMAIN}${snapshot.ticker}`;
    request(url, (error, response, html) => {
        if (!error && response.statusCode === 200) {
            var $ = cheerio.load(html);
            var stock_price = null;
            $('table').find('tbody').find('tr').each(function(i, e) {
                var column = $(this).prev();
                if (column.children('td.data-col1').text() === snapshot.companyName) {
                    stock_price = column.children('td.data-col2').text();
                }
            });
            stock_price = parseFloat(stock_price.replace(/,/g, ''));
            if (stock_price && snapshot.price == Math.floor(stock_price)) {
                // send email notification
                admin.auth().listUsers()
                    .then((list) => {
                        list.users.forEach((user) => {
                            var customer = user.toJSON();
                            sendEmailNotification(customer.email, `The company ${snapshot.companyName}' stock price is reached to ${snapshot.price}`, child);
                        });
                    }).catch((error) => {
                        console.log('Error listing users:', error);
                    })
                
                // Send push notification
                var ref = firebase.database().ref('users');
                ref.once('value')
                    .then(function(snapshot) {
                        var data = snapshot.val();


                        var fcmToken = '***';
                            var message = {
                                to: fcmToken,
                                data: {},
                                notification: {
                                    title: 'Stock Price',
                                    body: `The company ${company}' stock price is reached to ${price}`,
                                    tag: collapseKey,
                                    icon: 'ic_notification',
                                    color: '#18d821',
                                    sound: 'default'
                                }
                            };
                            fcm.send(message, function(err, response) {
                                if (err) {
                                    console.log(err);
                                } else {
                                    console.log("Successfully sent with response: ", JSON.stringify(response));
                                }
                            })

                            
                        
                    })
            }
        }
    })
}

const run_job = () => {
    cron.schedule('0 * * * * *', () => {
        checkPrice();
    });
}

//run_job();
checkPrice();
app.use('/api', router);

app.listen(3000, () => {
    console.log('\x1b[33m%s\x1b[0m', '** Express Development is listening on localhost:3000, open your browser on http://localhost:3000 **');
})

我想确保它作为 cron 后台运行。

我知道我做不到

* * * * * node /home/forge/bheng/public/ios-base-api/index.js >> /tmp/tmpfile.log 2>&1 &

因为我已经在我的 Node 中设置了 cron 服务器。

如何进一步调试它?

最佳答案

我遇到了同样的问题,我使用 pm2 解决了它。

全局安装 pm2:

npm install -g pm2

如果您使用 npm start 运行您的脚本,请在您的项目文件夹中运行它

pm2 start index.js

pm2 会将您的脚本转换为后台运行的守护进程,如果失败,它将重新启动脚本。检查日志运行

pm2 monit

如果你想在系统启动时运行你的脚本

pm2 startup

并按照说明进行操作。

关于node.js - 如何在 Linux Ubuntu 中将 NodeJS 应用程序作为 crontab 运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54184268/

相关文章:

linux - 如何在树莓派3b+中同时使用静态以太网ip和Wi-Fi

java - MongoDB 连接问题

java - 没有组件的 WindowBuilder 调色板

node.js - 重试提示自定义

linux - shell命令 "cat -"的效果

java - 错误 : JAVA_HOME is set to an invalid directory:/usr/lib/jvm/java-8-oracle/jre/bin/java when i run gradle command in terminal

linux - 如何限制单个 Linux 进程的内存使用而不终止进程

javascript - 错误: Could not locate the bindings file.尝试:(Webpack)

node.js - 如何从多个文件创建可读文件流

node.js - 为什么 proto buffer 没有日期数据类型?