如何在Linux Ubuntu中将NodeJS应用程序作为cronjob运行?

时间:2019-01-14 15:20:06

标签: node.js linux ubuntu cron

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

enter image description here

index.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 &

因为我已经在自己的节点中建立了服务器。

人们将如何进行进一步的调试?

1 个答案:

答案 0 :(得分:1)

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

全局安装pm2:

npm install -g pm2

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

pm2 start index.js

pm2将把您的脚本转到后台运行的守护程序,如果失败,它将重新启动脚本。要查看日志,请运行

pm2 monit

如果要在系统启动时运行脚本,请运行

pm2 startup

并按照说明进行操作。