在我的 NextJS 项目中,我正在开发一个新闻通讯应用程序。我的数据库名为 Datastax Astra。我已经开发了保存数据库文件的逻辑。但是,我仍然收到 1000 毫秒缓冲问题。我查看并尝试过,但没有产生任何结果。
db.ts
import mongoose from "mongoose";
import { driver, createAstraUri } from "stargate-mongoose";
export const connectDb = async () => {
try {
const uri = createAstraUri(
process.env.ASTRA_DB_API_ENDPOINT!,
process.env.ASTRA_DB_APPLICATION_TOKEN!
);
if (mongoose.connection.readyState !== 0) {
await mongoose.disconnect();
}
mongoose.set("autoCreate", true);
mongoose.setDriver(driver);
await mongoose
.connect(uri, { isAstra: true })
.then((res) => {
console.log("Connected");
})
.catch((r) => {
console.log(r);
});
} catch (error) {
console.log(error);
}
};
我在上面的代码中创建了一个到数据库的连接函数,这样我就可以在连接过程中被调用,并在发生错误时引发错误。
这是我的保存电子邮件代码,它创建一个连接并使用 db.ts 文件中的数据库连接函数将数据放入数据库中。
保存_Email.ts
"use server";
import Email from "@/models/email.model";
import { connectDb } from "@/shared/libs/db";
export const saveEmail = async ({
title,
content,
newsLetterOwnerId,
}: {
title: string;
content: string;
newsLetterOwnerId: string;
}) => {
try {
await connectDb();
const email = await Email.findOne({
title,
newsLetterOwnerId,
});
if (email) {
await Email.findByIdAndUpdate(email._id, {
content,
});
return { message: "Email updated successfully!" };
} else {
await Email.create({
title,
content,
newsLetterOwnerId,
});
return { message: "Email saved successfully!" };
}
} catch (error) {
console.log(error);
}
};
对于电子邮件,我还开发了一个电子邮件架构。下面提供了其代码。
架构
import mongoose from "mongoose";
const { Schema } = mongoose;
const emailSchema = new Schema(
{
title: {
type: String,
},
content: {
type: String,
},
newsLetterOwnerId: {
type: String,
},
},
{ timestamps: true }
);
const Email = mongoose.models.Email || mongoose.model("Email", emailSchema);
export default Email;
我尝试在我的在线 Astra 数据库中创建电子邮件集合,但完全不成功。我必须将电子邮件信息在线保存在我的 Astra 数据库中。但事实并非如此,接下来的错误表明了这一点。
Connected
MongooseError: Operation `emails.findOne()` buffering timed out after 10000ms
at Timeout.<anonymous> (D:\Projects\Portfolio\Newsletter\node_modules\mongoose\lib\drivers\node-mongodb-native\collection.js:185:23)
at listOnTimeout (node:internal/timers:569:17)
at process.processTimers (node:internal/timers:512:7)
针对此案例,有两个设置需要讨论。
1。 bufferCommands 和 bufferTimeoutMS
bufferCommands 是 mongoose 特定的设置,用于处理与 MongoDB 服务器可能出现的间歇性断开连接。当服务器连接恢复时,它将让应用程序等待并重试模型方法。但是,如果在 bufferTimeoutMS(默认为 10 秒)内连接未恢复,则会超时并抛出错误。
这就是本例中现在发生的情况。应用程序已缓存 - 更具体地说是方法 findOne - 10 秒,然后通过抛出错误而中止。
2。服务器选择超时MS
这是 mongoose 传递给 Mongo 驱动程序的设置。它设置驱动程序尝试寻找服务器来发送任何给定操作的秒数。默认值为 30 秒。
问题:
默认情况下,serverSelectionTimeoutMS 是 bufferTimeoutMS 的 3 倍。因此bufferTimeoutMS将首先到期。这将抑制失败的真正原因,即 serverSelectionTimeoutMS 超时。
现在至少有3个选择,可以让这个案子继续下去
应用选项 1:禁用 bufferCommands - 示例
以下临时设置会让系统等待30秒,然后抛出实际的错误原因。
const schema = new Schema({ /* ... */ }, { bufferCommands: false });
应用选项 2:将 serverSelectionTimeoutMS 降低到 bufferTimeoutMS - 示例
如果您发现选项 1 中的 30 秒等待时间略高于调试所需的时间,请应用此选项。以下临时设置会让系统等待 5 秒,然后抛出与选项 1 类似的错误。
mongoose.connect(uri, { serverSelectionTimeoutMS: 5000 }); // Timeout after 5s instead of 30s
示例代码:选项 1 - 30 秒后抛出连接错误
// Please note there is no MongoDB server at the given URL
import mongoose, { Schema } from 'mongoose';
await main().catch((err) => {
console.log(`Error thrown: ${new Date()}`);
console.log(err);
});
mongoose.connection.on('error', (err) => { console.log(err);});
async function main() {
const uri = 'mongodb://127.1.0.1:27017/test';
console.log(`Connecting: ${new Date()}`);
await mongoose.connect(uri);
const someSchema = new Schema({ somekey: String }, { bufferCommands: false });
const SomeModel = mongoose.model('SomeModel', someSchema);
await SomeModel.find();
}
OUTPUT: Connection error thrown after 30 seconds
Connecting. : ... 13:37:15 hh:mm:ss ...
Error thrown: ... 13:37:45 hh:mm:ss ...
Error: MongooseServerSelectionError: connection timed out
…
示例代码:选项 2 - 5 秒后抛出连接错误
// Please note there is no MongoDB server at the given URL
import mongoose, { Schema } from 'mongoose';
await main().catch((err) => {
console.log(`Erron thrown: ${new Date()}`);
console.log(err);
});
mongoose.connection.on('error', (err) => {
console.log(err);
});
async function main() {
const uri = 'mongodb://127.1.0.1:27017/test';
console.log(`Connecting: ${new Date()}`);
await mongoose.connect(uri, {
serverSelectionTimeoutMS: 5000,
});
const someSchema = new Schema({ somekey: String });
const SomeModel = mongoose.model('SomeModel', someSchema);
await SomeModel.find();
}
OUTPUT: Connection error thrown after 5 seconds
Connecting. : ... 13:33:35 hh:mm:ss ...
Error thrown: ... 13:33:40 hh:mm:ss ...
Error: MongooseServerSelectionError: Server selection timed out after 5000 ms
...
注意事项和要求:
请注意,此处讨论的选项仅用于调试目的。一旦找到连接问题,这方面的更改将被恢复。
要根据应用程序的需要进行永久性更改,请在此处查看原始文档:
谢谢
我们做最好的4你