You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js应用已正常运行但请求连接被拒绝,求故障排查

问题排查:Node.js应用反向代理请求被拒绝

问题概述

服务器上部署的Node.js应用(app.js)监听3000端口,通过PM2管理进程,Nginx配置反向代理将80端口请求转发至3000端口。但外部通过Postman向服务器IP(81.31.168.76)的80端口发送POST请求至/api/inputfile时,返回Error: connect ECONNREFUSED 81.31.168.76:80。

已确认的环境与状态

1. Node.js应用代码(app.js)

const express = require("express");
const fs = require("fs");
const { v4: uuidv4 } = require("uuid");
const InputManager = require("./inputHandler/inputManagment");
const InputAnalyser = require("./inputHandler/inputAnalyser");
const CdfCreator=require("./inputHandler/outputCreator");
const app = express();
app.use(express.json());
app.post("/api/inputfile", (req, res) => {
  const informations = req.body;
  const age = informations.yearOfConstruction;
  const latitude = informations.latitude;
  const longitude = informations.longitude;
  const systemType = informations.systemType;
  const floor = informations.floor;
  const saveData = /*informations.saveData*/true;
  let inputManager = new InputManager({
    age: age,
    latitude: latitude,
    longitude: longitude,
    systemType: systemType,
    floor: floor,
  });
  inputManager.CreateInputBody();
  if (inputManager.error.length == 0) {
    const uuidInputFileName = uuidv4();
    fs.writeFile(
      "./RTX_InputFiles/RTX_LVL1_" + uuidInputFileName + ".txt",
      inputManager.inputFile,
      function (err) {
        if (err) {
          throw err;
        } else {
          console.log(
            "File created successfully. \nName: " +
              "RTX_LVL1_" +
              uuidInputFileName +
              ".txt\n" +
              "-".repeat(30) +
              "\n"
          );

          const inputAnalyser = new InputAnalyser(uuidInputFileName);
          inputAnalyser.RunAnalysis();
          var checker = setInterval(() => {
            if (inputAnalyser.status == 1) {
              const cdfCreator=new CdfCreator('RTX_InputFiles/'+inputManager.cdfCostRatio,'RTX_InputFiles/'+inputManager.outputFile);
              cdfCreator.createCdfandCov();
              // res.sendFile(inputManager.outputFile, {
              //   root: "./RTX_InputFiles/",
              // });
              res.send(cdfCreator.result);
              console.log(
                "Analysis done successfully.\n" + "-".repeat(30) + "\n"
              );
              if (!saveData) {
                setTimeout(() => {
                  inputAnalyser.Clear({
                    DEL_input: "RTX_LVL1_" + uuidInputFileName + ".txt",
                    DEL_output: inputManager.outputFile,
                    DEL_cdf: inputManager.cdfCostRatio,
                  });
                }, 3000);
              }

              clearInterval(checker);
            } else if (inputAnalyser.error.length != 0) {
              res.send(
                "An error occured during computation! you can find more detail in terminal, code 4004!\n"
                //+JSON.stringify(inputAnalyser.error)
              );
              clearInterval(checker);
            }
          }, 5000);

          // setTimeout(() => {

          // }, 50000);

          //res.send("ok");
        }
      }
    );
  } else {
    res.json(inputManager.error);
  }
});
const PORT = 3000;
app.listen(PORT, () => {
  console.log(
    "RTX is listening at PORT:\n" + PORT + "\n" + "-".repeat(30) + "\n"
  );
});
// async function getOutput(uuidInputFileName) {

//   return result;
// }

2. PM2进程状态

┌─────┬────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id  │ name   │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├─────┼────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0   │ app    │ default     │ 1.0.0   │ fork    │ 14908    │ 9m     │ 2    │ online    │ 0%       │ 262.2mb  │ civ… │ disabled │
└─────┴────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

3. Nginx服务状态

civilrepo@civilRepo:/$ systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2023-02-23 18:08:48 +0330; 5s ago
     Docs: man:nginx(8)
  Process: 21258 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, s
  Process: 21265 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
  Process: 21262 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
 Main PID: 21271 (nginx)
    Tasks: 9
   Memory: 5.0M
      CPU: 63ms
   CGroup: /system.slice/nginx.service
           ├─21271 nginx: master process /usr/sbin/nginx -g daemon on; master_process on
           ├─21272 nginx: worker process
           ├─21273 nginx: worker process
           ├─21274 nginx: worker process
           ├─21275 nginx: worker process
           ├─21276 nginx: worker process
           ├─21277 nginx: worker process
           ├─21278 nginx: worker process
           └─21279 nginx: worker process

Feb 23 18:08:48 civilRepo systemd[1]: Starting A high performance web server and a reverse proxy server...
Feb 23 18:08:48 civilRepo systemd[1]: Started A high performance web server and a reverse proxy server.
lines 1-24/24 (END)

4. Nginx反向代理配置(/etc/nginx/sites-available/default)

server {

listen 80 default_server;
listen [::]:80 default_server;

root /var/www/html;

# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;

location / {
proxy_pass "http://127.0.0.1:3000";
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
}

}

5. 其他确认信息

  • PM2日志显示应用已监听3000端口:
RTX is listening at PORT:
0|app      | 3000
0|app      | ------------------------------
  • lsof命令确认3000端口被Node进程占用:
COMMAND     PID      USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME
node\x20/ 14908 civilrepo   20u  IPv6 1042798917      0t0  TCP *:3000 (LISTEN)

排查步骤建议

  • 检查服务器防火墙规则:执行ufw status查看防火墙状态,若80端口未允许,执行ufw allow 80/tcp并重启防火墙。
  • 验证Nginx监听状态:执行ss -tulnp | grep nginx,确认输出包含*:80或0.0.0.0:80。若仅监听IPv6的:::80,需调整Nginx配置或开启IPv4支持。
  • 测试本地连通性:在服务器内部执行curl -X POST http://127.0.0.1:80/api/inputfile -H "Content-Type: application/json" -d '{"age":1400,"latitude":35.68,"longitude":51.41,"systemType":1,"floor":12}',判断本地请求是否正常。若本地正常,问题出在外部网络链路;若本地失败,执行nginx -t验证配置语法,再执行systemctl reload nginx重新加载配置。
  • 调整Nginx绑定IP:修改Nginx配置中的listen指令为listen 0.0.0.0:80 default_server;,确保监听所有可用IP。
  • 检查云服务商安全组:若为云主机,登录云控制台确认安全组已允许80端口的入站请求。

内容的提问来源于stack exchange,提问作者kodas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:12:15