连接到上游时 NGINX 和 nodejs 上游连接超时,但请求将在 60 秒后得到响应

NGINX and nodejs upstream connection timed out while connecting to upstream but request will get responded after exactly 60s

后续 HTTP 请求 GET 和 POST 有时会在 60 秒内得到响应,而其他时候请求在 100 毫秒内得到响应。我应该如何解决这个问题?我认为这与我的 nodejs 后端和 mysql 连接有关,不一定与 nginx 反向代理和 docker 这些都存在的容器有关。

这是我经常遇到的 nginx 错误:

2022/01/10 16:43:15 [error] 33#33: *985 upstream timed out (110: Connection timed out) while connecting to upstream, client: xxx.xxx.xxx.xxx, server: sub.domain.tld, request: "GET /getTemp?api_key=xxxxxxx HTTP/1.1", upstream: "http://127.0.0.1:8080/getTemp?api_key=xxxxxxx", host: "sub.domain.tld"

我曾尝试按照其他帖子的建议将 nginx proxy_read_timeout 增加到 120s,但这不是这里的解决方法。我也从 mysql.createConnection() 切换到 mysql.createPool() 但这并没有解决它。

这是我到 mysql 数据库的 nodejs 连接:

let pool = mysql.createPool({
    connectionLimit: 10,
    host: process.env.DB_HOST,
    user: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_DATABASE,
    timezone: 'Europe/Helsinki'
});

这是 getTemp 端点的片段:

app.get('/getTemp', (req, res) =>{
    console.log(req.path);
    let ip = req.header('x-forwarded-for') || req.socket.remoteAddress;

    let ua = req.get('user-agent');
    console.log(ua);

    let {api_key} = req.query;
    console.log(req.query);

    if(api_key == process.env.API_KEY){
        console.log(`Authorized access from IP: '${ip}'`);
        // if one of the variables are undefined then send 400 status code to the client
        if(api_key == undefined){
            return res.sendStatus(400).send({message:"One or more variables are undefined"});
        }
        
        sql_query = "SELECT * FROM tempData ORDER BY id DESC";

        sql_query = mysql.format(sql_query);
        
        // attempt to query mysql server with the sql_query 
        pool.query(sql_query, (error, result) =>{
            if (error){
                // on error log the error to console and send 500 status code to client
                console.log(error);
                return res.sendStatus(500);
            };
            
            // if temp is found we send 200 status code to client
        
            if(result.length > 0){
                let currentTemp = result[0].currentTemp;
                console.log(`Temp: ${currentTemp}`);
                return res.status(200).send({temperature:currentTemp});
            }else{
                // incase temp is not found then we send 500 status code to client
                console.log('Temperature not found');
                return res.status(500).send({error:"Temperature not found"});
            }
        });

    }else{
      // if client sends invalid api key then send 403 status code to the client
  
      console.log(`Unauthorized access using API key '${api_key}' from IP: '${ip}'`);
      return res.sendStatus(403);
    }
})

这是我的 nginx 配置:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 4096;
}

http {
         server {
            listen 80;
            listen [::]:80;

            listen 443 default_server ssl;
            listen [::]:443 ssl;

            ssl_certificate /cert.pem;
            ssl_certificate_key /cert.key;

            server_name sub.domain.tld;

            location / {
                proxy_read_timeout 120;

                proxy_pass http://localhost:8080;
                proxy_set_header X-Real-IP $http_cf_connecting_ip;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header X-NginX-Proxy true;
            }

        }
}

我为端点分配了静态值,因此它不会从数据库中查询任何内容,而且它还需要一分钟的时间来响应,所以不是数据库连接或端点导致了问题。我在应用程序中禁用了速率限制,并且不再超时。所以我超时的原因是配置错误的速率限制。