简体   繁体   中英

How can I run a NodeJS Application as cronjob in Linux Ubuntu?

I have a node application that contain cron in it. Right now, it run perfectly on Ubuntu server.

在此处输入图片说明

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 **');
})

I want to make sure it run as cron the background.

I know that I can't do this

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

Because I already cron server in my node already.

How would one go about and debug this further?

I have faced the same problem and I resolved it using pm2.

install pm2 globally:

npm install -g pm2

if you run your script using npm start run this in your project folder

pm2 start index.js

pm2 will turn your script in to a daemon that will run in the background and it will restart the script if it fails. To check the logs run

pm2 monit

If you want to run your script when the system starts run

pm2 startup

and follow the instructions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM