ubuntu上的pm2和systemd无法正确守护程序节点应用程序

时间:2018-07-21 10:02:37

标签: node.js systemd pm2

人。我正在Ubuntu服务器上实现节点应用程序。该应用使用CAS 服务器获取票证。如下代码:

module.exports = function (req, res, next) {
    if (!req.session) {         // failed to create session
        return res.status(500).end();
    }
    if (req.session.uid) {      // user has logged
        return next();
    }
    if (!req.query || !req.query.ticket) {  
        // if a none-logged request has no query, it should be thought as 
        // the first request of the user, so it would be redirect to CAS 
        // server for authentication
        return redirectToCas(req, res);
    }
    var { ticket } = req.query;
    if (!ticket.startsWith('ST-')) {
        // This system self don't use query string. If a none-logged request
        // carries a none-CAS-standard query, it will be treated as illegal
        // and redirect to unauthorized page.
        return redirectTo401(res);  // unknown ticket
    }
    let originalUrl = LOCAL_SERVICE + url.parse(req.originalUrl).pathname;
    let path = `${CAS_SERVER}/serviceValidate?service=${originalUrl}&ticket=${ticket}`;
    (async () => {
        try {
            console.log(`${times++} original url:${originalUrl}`);

            let echo = await getResponseText(path);     // get xml response from CAS server
            let result = await parseXmlEcho(echo);      // set successful flag and fetch uid 
            if (result.success) {       // successfully pass the verification of CAS
                var hasPerm = await testPermission(result.uid);
                if (hasPerm) {          // test if user has permission in this system
                    req.session.uid = result.uid;
                    res.redirect(originalUrl);
                } else {
                    redirectTo401(res);
                }
            } else {
                //res.status(401).end('authorized');
                redirectTo401(res);
            }
        }
        catch (err) {
            console.error(err);
            //res.status(401).end('没有授权!');      // unauthorized
            redirectTo401(res);
        }
    })();
}

以上代码属于auth.js。 app.js的主要入口是这样的:

// provide public resources
app.use(favicon(path.join(__dirname, 'public', 'some.ico')))
    .use('/public', express.static('public'));

// check session
app.use(session({
    name: 'certain-name',
    secret,
    store: new MssqlStore(storeConfig),
    resave: false,
    saveUninitialized: false,
    cookie: {
        path: '/',
        httpOnly: false
    }
}));

// authenticate
app.use('*', auth)              // authenticate
    .post('/end', api.end);     // logout
    .... serve index.html and other resource here 

现在,我已经在Ubuntu服务器上实现了代码。当我使用“ node app.js”在Putty终端中启动该应用程序时,一切正常。但是当我同时使用PM2或systemd启动它时(我在Chris Lea的blog的指导下进行了配置 ),应用程序崩溃,浏览器回显“ Cannot GET /index.html”。查看日志(systemctl状态为myappname)后,系统已提供但报告了index.html。 通过直接敲入终端中的“ Node app”并使用systemd或PM2来启动它的生成过程之间有什么区别?散播Nodejs + CAS是否需要一些其他配置?

1 个答案:

答案 0 :(得分:0)

在插入一捆日志语句后,我已经弄清楚了该应用程序的详细流程步骤。该问题是由指定静态资源的错误路径引起的。我的应用程序中有两行引用表示静态中间件。一个在认证之前,另一个在认证之后。

use('/public', express.static('public')) // serve two tiny images and noperm.html
...authenticate
use('/',express.static('client/build')) // serve homepage

这两个语句都将资源路径与当前目录捆绑在一起。当我用腻子连接到Ubuntu时,我不自觉地总是进入包含应用程序的路径,然后使用node启动该应用程序。因为当前路径是应用程序的根目录,所以current-path +'public'和current-path +'client / build'都可以计算出正确的资源路径,并且该应用程序可以愉快地运行。但是,当我使用PM2或systemd启动应用程序时,基本目录更改为PM2或systemd的根路径(我尚未验证,只是猜测),因此所有静态资源都无法正确发现,并且应用程序将运行失败了 在我修改了代码以使用path.join方法计算静态资源路径后,问题就消失了。 因此,从PM2和Node启动应用程序之间确实存在一些不同,至少默认路径是。