【发布时间】:2021-04-26 00:03:44
【问题描述】:
问题
我已经为 Heroku 部署了一个 Node.js/Express.js/Mongoose API,但是当我点击端点时,我得到一个 503 状态代码并且 Heroku 提示告诉我有一个应用程序错误。
尝试解决方案
我在另一篇 Stackoverflow 帖子中读到,您需要在 Heroku 应用程序的设置中添加 MONGODB_URI 作为配置变量,因此我添加了连接字符串并将 MongoDB 连接更改为:
// Connect to DB
mongoose.connect(process.env.MONGODB_URI || uri, {useNewUrlParser: true, useUnifiedTopology: true}, () =>
console.log('Connected to DB!')
);
但这似乎没有帮助。我还尝试将 &ssl=true 附加到连接字符串,但没有成功。然后我尝试将 Mongoose 版本更改为 5.7.0 并将 MongoDB 连接字符串更改为 Node 版本 2.12.12 或更高版本(来自 Atlas Cloud)。一个都没用。
应用的文件结构
这是我的 API 的非常简单的结构
在 index.js 中,我设置了 express 应用程序、设置路由、连接到端口并使用 Mongoose 连接到数据库:
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
const uri = "mongodb+srv://username:password@devcluster.hesav.mongodb.net/quizappdb?retryWrites=true&w=majority";
const app = express();
// Middleware
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(cors());
// Import routes
const questionRoutes = require('./routes/questions.js');
app.use('/question', questionRoutes);
// Set to port 5000 and listen on port
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
// Connect to DB
mongoose.connect(process.env.MONGODB_URI || uri, {useNewUrlParser: true, useUnifiedTopology: true}, () =>
console.log('Connected to DB!')
);
(在 uri 中编辑的用户名和密码)
在 routes/questions.js 中,我使用 express 路由器定义 API 函数:
const express = require('express');
const router = express.Router();
const Question = require('../models/question');
// Get all questions
router.get('/', async (req, res) => {
try {
const questions = await Question.find();
res.json(questions);
} catch(err) {
res.json({message: err})
}
});
// Get questions by category
router.get('/:category', async (req, res) => {
const category = req.params.category;
console.log(category);
Question.find({category: category})
.exec()
.then(doc => {
console.log("From database", doc);
if (doc) {
res.status(200).json(doc);
} else {
res.status(404).json({message: 'No valid entry'})
}
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
})
})
// Add question
router.post('/', async (req, res) => {
const question = new Question({
category: req.body.category,
description: req.body.description,
option1: req.body.option1,
option2: req.body.option2,
option3: req.body.option3,
option4: req.body.option4,
answer: req.body.answer,
});
try {
const savedQuestion = await question.save()
res.json(savedQuestion);
} catch(err){
res.json({message: err})
}
});
// Delete question by id
router.delete('/:questionId', async (req, res) => {
try {
const removedQuestion = await Question.remove({_id: req.params.questionId})
res.json(removedQuestion);
} catch(err) {
res.json({message: err})
}
})
module.exports = router;
为了让 Heroku 知道我使用的是哪个版本的 Node,我在 package.json 的“引擎”部分定义了它:
"engines": {
"node": "14.x"
}
在我的 Procfile 中:
网络:节点 index.js
当我在 /question 访问应用程序时,它会挂起 30 秒,显示应用程序错误的 Heroku 提示,并且在我看到的日志中:
2021-01-21T16:56:32.313123+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/question" host=quiz-app-dk. herokuapp.com request_id=cda581cb-25c0-4980-a669-e65008a59ecd fwd="212.10.104.241" dyno=web.1 connect=1ms service=30001ms status=503 bytes=0 protocol=https
所以是 503 状态码。
当我指定一个类别并转到 /question/Sport 时,我得到相同的结果:
2021-01-21T16:57:10.687786+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/question/Sport" host=quiz-app- dk.herokuapp.com request_id=2620dc48-7581-406c-aa66-2085ee6decb3 fwd="212.10.104.241" dyno=web.1 connect=1ms service=30000ms status=503 bytes=0 protocol=https
与数据库的连接
还值得注意的是,与数据库的连接似乎发生了,正如我在 Heroku 日志中看到的那样:
2021-01-21T14:07:55.273864+00:00 app[web.1]:已连接到数据库!
但是,当我在本地执行其中任何一项操作时,一切正常。我怀疑路线有问题,但我不知道是什么。任何帮助是极大的赞赏。谢谢。
更新
我将数据库连接包装在 try catch 中并得到以下结果:
2021-01-21T17:07:08.861455+00:00 app[web.1]:无法连接到服务器。请启动服务器。错误:MongoNetworkError:第一次连接时无法连接到服务器 [devcluster-shard-00-00.hesav.mongodb.net:27017] [MongoNetworkError:连接 5 到 devcluster-shard-00-00.hesav.mongodb.net:27017关闭 2021-01-21T17:07:08.861463+00:00 app[web.1]:在 TLSSocket。
【问题讨论】:
-
试试:
app.enable('trust proxy')。更多信息here -
@CarloCorradini 没用,但感谢您抽出宝贵时间尝试和帮助。
-
不应该是
/question/sport而不是/sport吗? -
@L.Meyer 你是对的。不,我收到“MongooseError:操作
questions.find()缓冲在 10000 毫秒后超时” -
你能提供你的 Mongo 服务器和你使用的 mongoose 的版本吗?
标签: node.js express heroku mongoose