Node.js 节点JS正在运行但没有响应。工作,但随后定期停止响应
我已经创建了我的第一个nodejsapi(也是第一次使用JS),因此我遇到了一些问题,并且非常希望得到一些帮助/指导 我目前的问题是,API可以工作,但有时(每天不止一次)它会停止响应。(使用邮递员进行测试)。它不会以“无响应”来响应,它只是不断尝试,好像在等待响应 当我登录到我使用的节点时:Node.js 节点JS正在运行但没有响应。工作,但随后定期停止响应,node.js,express,api-design,Node.js,Express,Api Design,我已经创建了我的第一个nodejsapi(也是第一次使用JS),因此我遇到了一些问题,并且非常希望得到一些帮助/指导 我目前的问题是,API可以工作,但有时(每天不止一次)它会停止响应。(使用邮递员进行测试)。它不会以“无响应”来响应,它只是不断尝试,好像在等待响应 当我登录到我使用的节点时: lsof -i tcp:3000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME node 22361 [myserver]
lsof -i tcp:3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 22361 [myserver] 18u IPv6 190588033 0t0 TCP *:hbci (LISTEN)
kill -9 22361
当我杀死它时,我会等待10秒,然后它会再次启动,因为我已经安装了永久
问题是节点似乎就在那里。。。不起作用。如果它崩溃了,它不会重新启动并重新工作,但它只是“在那里”
我如何诊断这个
我也安装了Nodemon,但由于出现了EAINUSE错误,无法使其正常工作
- 我已经在我的VPS上创建了该文件
- 在我的Win10 PC上使用Visual Stdio代码进行SSH
- 看了几段youtube视频让我跑步
- 我的主js文件非常基本:
const app = require('./app');
const port = process.env.port || 3000;
app.listen(port);
目前,我似乎无法找到“为什么”节点从工作和响应变为停滞、运行,但实际上不工作
很乐意分享代码,只有大约12个js文件,不想在这里添加太多内容
Package.json:
{
"name": "qudaapi",
"version": "1.0.0",
"description": "NodeJSAPI",
"main": "qudaserver.js",
"scripts": {
"start": "node qudaserver.js"
},
"author": "GAngel",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"morgan": "^1.10.0",
"mysql": "^2.18.1"
}
}
App.js
const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const app = express();
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use((req,res,next)=>{
res.header("Access-Control-Allow-Origin","*");
res.header("Access-Control-Allow-Headers","Origin,X-Requested-With,Content-Type,Accept,Authorization");
if (req.method === 'OPTIONS'){
res.header('Access-Control-Allow-Methods','PUT,POST,PATCH,DELETE,GET');
return res.status(200).json({});
}
next();
});
//Import Routes
const chemistRoutes = require('./api/routes/chemists');
const smsHxRoutes = require('./api/routes/smsHx');
const authRoute = require('./api/routes/auth');
const webhookRoutes = require('./api/routes/stripehook');
const orderRoutes = require('./api/routes/orders');
const comboDataRoutes = require('./api/routes/comboData');
const staffRoutes = require('./api/routes/staff');
const orderListsRoutes = require('./api/routes/orderLists');
const contactLogRoutes = require('./api/routes/contactLog');
const licenseRoutes = require('./api/routes/license');
//Route Middleware
app.use('/smsHx',smsHxRoutes);
app.use('/chemists',chemistRoutes);
app.use('/register',authRoute);
app.use('/stripehook',webhookRoutes);
app.use('/orders',orderRoutes);
app.use('/comboData',comboDataRoutes);
app.use('/staff',staffRoutes);
app.use('/orderLists',orderListsRoutes);
app.use('/contactLog',contactLogRoutes);
app.use('/license',licenseRoutes);
app.use((req,res,next) => {
const error = new Error('Endpoint not Found');
error.status = 404;
next(error);
})
app.use((error,req,res,next) => {
res.status(error.status || 500);
res.json({
error: {
message: error.message
}
});
});
module.exports = app;
导致某种失败循环的部分:
//Login_Get APIkey
router.post('/login',verifyQUDA,async (req,res) => {
let loginChemist = req.body;
const realPass = loginChemist.chemistPassword;
// CHECK Password
var sqlString = "SELECT * From tblChemists WHERE userName = ?;";
connection.query(sqlString,[loginChemist.userName], async (err,rows,fields)=>{
if (rows && Array.isArray(rows) && rows.length) {
const savedHash = rows[0].chemistpass;
const chemistID = rows[0].chemistID;
const validPass = await bcrypt.compare(realPass,savedHash);
if(!validPass){
return res.status(200).json({
Result: false
})
}else{
const token = jwt.sign({_id: chemistID},process.env.TOKEN_SECRET);
res.header('auth-token',token);
return res.status(200).json({
Result: true,
API_Token: token
})
}
}
})
})
因此,我的代码运行,我可以使用API,我似乎能够很好地使用它(所有路由),并获得预期的响应,然而,如果我随机登录并只是做一个测试,有时它会关闭,邮递员只是一直在等待响应,但当我检查。。。它仍在“运行”
真的很想知道我应该做什么来诊断
编辑:
上面的代码是有时循环或导致问题的部分。
我发现api实际上是在其他api调用工作时运行的,如果我不添加头,这个api调用“工作”。
因此,如果没有标头,或者标头API键不正确,我可以得到500个响应
问题似乎是如果标题是正确的,用户和通行证是正确的,有时我只是得到一个循环响应。。。
然而,代码确实可以工作,并在这里和那里提供我需要的API_标记,但有时只是像疯子一样循环 您的
/login
处理程序有许多代码路径,这些路径不发送任何响应,并且缺少一些错误处理,因此最终可能会出现“静默”错误和挂起的请求。就个人而言,我会在您的数据库上切换到promise API,但在不进行结构更改的情况下,这里有一种方法至少可以确保您始终发送响应并捕获错误:
//Login_Get APIkey
router.post('/login', verifyQUDA, (req, res) => {
const loginChemist = req.body;
// CHECK Password
var sqlString = "SELECT * From tblChemists WHERE userName = ?;";
connection.query(sqlString, [loginChemist.userName], async (err, rows, fields) => {
try {
if (err) {
// catch database errors
console.log(err);
res.sendStatus(500);
} else if (rows && rows.length) {
const savedHash = rows[0].chemistpass;
const chemistID = rows[0].chemistID;
const realPass = loginChemist.chemistPassword;
const validPass = await bcrypt.compare(realPass, savedHash);
if (!validPass) {
res.status(200).json({ Result: false });
} else {
const token = jwt.sign({ _id: chemistID }, process.env.TOKEN_SECRET);
res.header('auth-token', token);
res.status(200).json({ Result: true, API_Token: token });
}
} else {
// send some status here when the username does not exist
// or your rows condition is not met
res.sendStatus(404);
}
} catch (e) {
// this catches any exception in this scope or await rejection
console.log(e);
res.sendStatus(500);
}
});
});
您只需在服务器上记录内容,直到您能够缩小内容被卡住的范围。例如,当传入请求被卡住时,是否会到达第一个中间件?或者它甚至没有走那么远?我要寻找的是:1)泄漏的数据库连接或数据库资源,2)泄漏的文件句柄,3)没有完整的错误处理的路由,并且有一些路径在出现错误时无法发送任何响应,4)一些中间件有一个它永远不会调用
next()的条件
或发送响应(从而挂起请求)。在您显示的一个路由处理程序中,似乎在发送响应后没有退出的循环中调用res.status(200).json()。如果您可以在循环中多次使用此If
语句,则这是错误的。每个请求得到一个响应,而不是N个响应。这本身可能不会引起您的症状,但这是错误的,需要修复。谢谢各位,我将立即研究这些问题,看看我能做些什么。您是否在生产环境中运行此功能?您添加的代码有许多代码路径,不会返回任何响应。而且,它缺少一系列错误处理,这也会导致没有响应被发送。非常感谢@jfriend00,我已经使用了这些代码,并且运行良好。我发现不需要(&&Array.isArray)部分,我认为这也会导致问题,所以我将其删除。我将对我的其他API片段使用这种设计/处理来清理它们。再次感谢您花时间帮助我确定,这有助于缩小问题的范围,但它仍然“破坏”API正在处理除此之外的所有调用,该调用已重新运行内部服务器错误500响应。考虑到其余的API都在工作,我怎么能找出这里的错误呢?@GlennAngel-好吧,我建议的代码无论在哪里都会发送错误500响应,它也会记录错误的详细信息,所以我建议查看日志,看看你是否能找出它出现的原因。您还可以添加更多日志记录来检查所有内容,并尝试找出错误所在。@GlennAngel-此代码有三种主要方式生成500错误。首先,数据库给了您一个错误。其次,在处理行数据时引发了异常。第三,wait bcrypt.compare()
被拒绝。好的,谢谢,所以我的最后一个问题(noob)是,如果我转到我的cmd屏幕并启动节点,我可以在打印时看到控制台,但是如果我关闭cmd并且节点正在运行。。如何访问该日志?