如何防止PM2继续启动新的NodeJS应用程序?

时间:2019-01-19 20:22:16

标签: node.js cron pm2 crontrigger

我有一个NodeJS文件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-a2107.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) => {
        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: 'johndoe@gmail.com',
            pass: '#######'
        }
    });

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

    let info = await transporter.sendMail(mailOptions);
    // update notify params
    var db = admin.database();
    var ref = db.ref('emails').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();
                }
            });
            if (stock_price != null) {
                stock_price = parseFloat(stock_price.replace(/,/g, ''));
                if (stock_price && Math.round(snapshot.price) == Math.round(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();
                        for (var i=0;i<data.length;i++) {
                            var fcmToken = data[i].fcmToken;
                            var collapseKey = 'new_message';
                            var message = {
                                to: fcmToken,
                                data: {
                                    cpeMac: '000000000000',
                                    type: 'malware',
                                },
                                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 **');
})

现在,我使用PM2启动它。

我不断得到

0|index  |     at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
0|index  |     at Function.Module._load (internal/modules/cjs/loader.js:552:3)
PM2      | App [index:0] exited with code [1] via signal [SIGINT]
PM2      | App [index:0] starting in -fork mode-
PM2      | App [index:0] online
0|index  | Error: listen EADDRINUSE: address already in use :::3000
0|index  |     at Server.setupListenHandle [as _listen2] (net.js:1255:14)
0|index  |     at listenInCluster (net.js:1303:12)
0|index  |     at Server.listen (net.js:1391:7)
0|index  |     at Function.listen (/home/forge/john/public/ios-base-api/node_modules/express/lib/application.js:618:24)
0|index  |     at Object.<anonymous> (/home/forge/john/public/ios-base-api/index.js:153:5)
0|index  |     at Module._compile (internal/modules/cjs/loader.js:721:30)
0|index  |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)
0|index  |     at Module.load (internal/modules/cjs/loader.js:620:32)
0|index  |     at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
0|index  |     at Function.Module._load (internal/modules/cjs/loader.js:552:3)
PM2      | App [index:0] exited with code [1] via signal [SIGINT]
PM2      | App [index:0] starting in -fork mode-
PM2      | App [index:0] online
0|index  | Error: listen EADDRINUSE: address already in use :::3000
0|index  |     at Server.setupListenHandle [as _listen2] (net.js:1255:14)
0|index  |     at listenInCluster (net.js:1303:12)
0|index  |     at Server.listen (net.js:1391:7)
0|index  |     at Function.listen (/home/forge/john/public/ios-base-api/node_modules/express/lib/application.js:618:24)
0|index  |     at Object.<anonymous> (/home/forge/john/public/ios-base-api/index.js:153:5)
0|index  |     at Module._compile (internal/modules/cjs/loader.js:721:30)
0|index  |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)
0|index  |     at Module.load (internal/modules/cjs/loader.js:620:32)
0|index  |     at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
0|index  |     at Function.Module._load (internal/modules/cjs/loader.js:552:3)
PM2      | App [index:0] exited with code [1] via signal [SIGINT]
PM2      | App [index:0] starting in -fork mode-
PM2      | App [index:0] online
0|index  | Error: listen EADDRINUSE: address already in use :::3000
0|index  |     at Server.setupListenHandle [as _listen2] (net.js:1255:14)
0|index  |     at listenInCluster (net.js:1303:12)
0|index  |     at Server.listen (net.js:1391:7)
0|index  |     at Function.listen (/home/forge/john/public/ios-base-api/node_modules/express/lib/application.js:618:24)
0|index  |     at Object.<anonymous> (/home/forge/john/public/ios-base-api/index.js:153:5)
0|index  |     at Module._compile (internal/modules/cjs/loader.js:721:30)
0|index  |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)
0|index  |     at Module.load (internal/modules/cjs/loader.js:620:32)
0|index  |     at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
0|index  |     at Function.Module._load (internal/modules/cjs/loader.js:552:3)
PM2      | App [index:0] exited with code [1] via signal [SIGINT]
PM2      | App [index:0] starting in -fork mode-
PM2      | App [index:0] online
  

EADDRINUSE:地址已在使用::: 3000

我的目标是在后台运行我的NodeJS应用,而不是每分钟启动一个新的。


问题

有人可以告诉我我做错了什么吗?


目前我愿意接受任何建议。

0 个答案:

没有答案