node.js - ubuntu 上的 pm2 和 systemd 无法正确守护节点应用程序
问题描述
伙计们。我正在 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 的博客的指导下配置它 ),应用程序崩溃并且浏览器回显“Cannot GET /index.html”。查看日志(systemctl status myappname)后,系统但报告 index.html 已被提供。通过直接在终端中敲入“节点应用程序”和使用 systemd 或 PM2 启动它来生成过程有什么区别?生成 Nodejs+CAS 是否需要一些进一步的配置?
解决方案
在插入一束日志语句后,我已经弄清楚了应用程序的详细流程步骤。该问题是由于指定了错误的静态资源路径引起的。我的应用程序中有两行引用了 express 静态中间件。一个是在认证之前,另一个是在认证之后。
use('/public', express.static('public')) // serve two tiny images and noperm.html
...authenticate
use('/',express.static('client/build')) // serve homepage
这两个语句都将资源路径与当前目录捆绑在一起。当我使用 putty 连接到 Ubuntu 时,我不知不觉总是进入包含应用程序的路径,然后使用 node.js 启动应用程序。因为当前路径是应用程序的根目录,所以 current-path+'public' 和 current-path+'client/build' 都可以计算出正确的资源路径,并且应用程序运行愉快。但是当我使用 PM2 或 systemd 启动应用程序时,基本目录更改(我尚未验证但只是猜测)到 PM2 或 systemd 的根路径,因此所有静态资源都无法再正确发现并且应用程序运行失败的。在我修改了代码以计算静态资源路径后,path.join 方法问题消失了。所以从 PM2 和 Node 启动应用程序之间确实有一些不同,至少默认路径是。
推荐阅读
- git - Git:如何从另一个存储库导入提交并取消压缩它们?
- redis - Redis 的 lua 脚本中的时间(以纳秒为单位)
- python - AttributeError:“WSGIRequest”对象在发出获取请求时没有属性“get”
- html - Symfony 表单和 Ajax
- c++ - 为什么我们不能更改 std::vector 的数据指针?
- d3.js - 如何将现有文本元素转换为 d3plus-text 文本框?
- angular - 如何将组件中的对象传递和接收到 NbDialog 组件 nebular ngx-admin?
- mysql - Docker 与 MySQL v5.7 连接问题
- python - AttributeError: 'NoneType' object has no attribute 'strip' 如何解决?
- python - 如何用列表初始化一个numpy数组