简体   繁体   English

如何使用无服务器在 Node js express 服务器中建立与 mongo db 的连接?

[英]How to establish connection to mongo db in a Node js express server using serverless?

I don't know how to establish connection to the mongo db for my node JS server in AWS Lambda using serverless on AWS.我不知道如何使用 AWS 上的无服务器在 AWS Lambda 中为我的节点 JS 服务器建立与 mongo db 的连接。 I've mentioned my question in the handler function below.我在下面的处理程序 function 中提到了我的问题。

The code looks something like this:代码看起来像这样:

import express from "express";
import mongoose from "mongoose";
import dotenv from "dotenv";   
import cookieParser from "cookie-parser";
import serverless from "serverless-http";

const PORT = 1234;

dotenv.config();

mongoose.connect(
    process.env.MONGO_URL,
    () => {
        console.log("connected to db");
    },
    (err) => {
        console.log({
            error: `Error connecting to db : ${err}`,
        });
    }
);

const app = express();

app.use(cookieParser());
app.use(express.json());

// this part has various routes
app.use("/api/auth", authRoutes);


app.use((err, req, res, next) => {
    const status = err.status || 500;
    const message = err.message || "Something went wrong";
    return res.status(status).json({
        success: false,
        status,
        message,
    });
});

app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

export const handler = () => { 
    // how to connect to mongodb here?
    return serverless(app);
};

Here handler is the AWS lambda's handler function.这里的handler是 AWS lambda 的处理程序 function。 For each http request I'm reading/writing data from/to my DB in some way.对于每个 http 请求,我正在以某种方式从/向我的数据库读取/写入数据。 After checking the cloudwatch logs, it was clear that the requests sent to the server result in timeout because the connection to mongodb hasn't been established.查看cloudwatch日志后,很明显发送到服务器的请求导致超时,因为与mongodb的连接尚未建立。 So how exactly do I use mongoose.connect here?那么我究竟如何在这里使用mongoose.connect呢?

I tried doing this:我试过这样做:

export const handler = () => { 
    mongoose.connect(
        process.env.MONGO_URL,
        () => {
            console.log("connected to db");
        }
    );
    return serverless(app);
};

But it didn't work possibly because it's asynchronous.但它可能不起作用,因为它是异步的。 So I'm not sure how to make this connection here.所以我不确定如何在这里建立这种联系。

EDIT :编辑

One thing that I realised was that the database server's network access list had only my IP because that's how I set it up initially.我意识到的一件事是数据库服务器的网络访问列表只有我的 IP,因为这就是我最初设置它的方式。

So I changed it to anywhere for now and made the following minor changes:所以我现在把它改成了任何地方,并做了以下小改动:

const connect_to_db = () => {
    mongoose
        .connect(process.env.MONGO_URL)
        .then(() => {
            console.log("Connected to DB");
        })
        .catch((err) => {
            throw err;
        });
};

app.listen(PORT, () => {
    connect_to_db();
    console.log(`Server listening on port ${PORT}`);
});

Now I can see "Connected to DB" in the logs but the requests sent still times out after 15 seconds (the timeout limit set currently).现在我可以在日志中看到“已连接到数据库”,但发送的请求在 15 秒后仍然超时(当前设置的超时限制)。

My logs:我的日志:

在此处输入图像描述

What am I doing wrong?我究竟做错了什么?

So I did some more digging and asked this around the community .所以我做了一些更多的挖掘,并在社区周围询问了这个问题。 Few things that made me understand what I was doing wrong:几件事让我明白我做错了什么:

  • It appeared I wasn't connecting the db and my app response together.看来我没有数据库和我的应用程序响应连接在一起。 My app was handling the request fine, my db was connecting fine.我的应用程序处理请求很好,我的数据库连接正常。 But there was nothing tying them together.但是没有什么能把他们绑在一起。 It's supposed to be simple:它应该很简单:

    Requests comes in > App waits until db connection has been established > App handles request > App returns response.请求进入 > 应用程序等待数据库连接建立 > 应用程序处理请求 > 应用程序返回响应。

  • Second, calling app.listen was another problem in my code.其次,调用 app.listen 是我代码中的另一个问题。 Calling listen keeps the process open for incoming requests and it ultimately is killed by Lambda on timeout.调用 listen 保持进程对传入请求保持打开状态,最终在超时时被 Lambda 杀死。

    In a serverless environment, you don't start a process that listens for requests but, instead, the listening part is done by AWS API Gateway (which I have used to have my Lambda handle http requests) and it knows to send request information to Lambda handler for processing and returning a response.在无服务器环境中,您不会启动侦听请求的进程,而是由 AWS API 网关(我曾经让我的 Lambda 处理 Z80791B3AE7002CB88C246876D9FAA8F 请求信息)完成侦听部分并知道它向请求发送信息Lambda 处理程序,用于处理和返回响应。 The handler function is designed to be run on each request and return a response.处理程序 function 设计为在每个请求上运行并返回响应。

So I tried adding await mongoose.connect(process.env.MONGO_URL);所以我尝试添加await mongoose.connect(process.env.MONGO_URL); to all my methods before doing any operation on the database and it started sending responses as expected.在对数据库进行任何操作之前,我的所有方法都开始按预期发送响应。 This was getting repetitive so I created a simple middleware and this helped me avoid lot of repetitive code.这变得重复了,所以我创建了一个简单的中间件,这帮助我避免了很多重复的代码。

app.use(async (req, res, next) => {
    try {
        await mongoose.connect(process.env.MONGO_URL);
        console.log("CONNECTED TO DB SUCCESSFULLY");
        next();
    } catch (err) {
        next(err);
    }
});

Another important, but small change.另一个重要但很小的变化。 I was assigning lambda's handler incorrectly.我错误地分配了 lambda 的handler

Instead of this:而不是这个:

export const handler = () => { 
    return serverless(app);
};

I did this:我这样做了:

export const handler = serverless(app);

That's it I suppose, these changes fixed my express server on Lambda.我想就是这样,这些更改将我的快递服务器固定在 Lambda 上。 If anything I've said is wrong in any way just let me know.如果我所说的任何内容有任何错误,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM