Docker容器内Nginx路由设置,请求超时出现502错误的解决方案

72次阅读
没有评论

问题描述

在一个Docker容器内,我有一个React应用程序,用户可以输入一些数字,然后会有一个算法执行一些计算并输出结果。在此过程中,Nginx会检查请求并决定是将其路由到React服务器还是Express服务器。然而,当提交数字时,存在一个xhr请求保持挂起状态,直到最终以502错误的坏网关错误超时。

我在一个Docker容器内运行了 docker logs <container-id> 命令,并一直看到以下内容:

upstream server temporarily disabled while connecting to upstream

我怀疑问题可能出在我构建的 default.conf 文件中,但我在Express服务器、工作进程或React应用程序中都没有找到问题。以下是我的 default.conf 文件内容:

upstream client {
    server client:3000;
}
upstream api {
    server server:5000;
}
server {
    listen 80;
    location / {
        proxy_pass http://client;
    }
    location /sockjs-node {
        proxy_pass http://client;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
    location /api {
        rewrite /api/(.*) /$1 break;
        proxy_pass http://api;
    }
}

然后整个应用程序在运行一段时间后崩溃了。为了让这个配置覆盖Nginx中的默认 default.conf 文件,我在 nginx/ 文件夹中设置了一个 Dockerfile.dev 文件:

FROM nginxCOPY ./default.conf /etc/nginx/conf.d/default.conf

应用程序总体上使用了这个 docker-compose.yml 文件:

version: "3"
services:
  postgres:
    image: "postgres:latest"
  redis:
    image: "redis:latest"
  nginx:
    restart: always
    build:
      dockerfile: Dockerfile.dev
      context: ./nginx
    ports:
      - "3050:80"
  api:
    build:
      dockerfile: Dockerfile.dev
      context: ./server
    volumes:
      - /app/node_modules
      - ./server:/app
    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - PGUSER=postgres
      - PGHOST=postgres
      - PGDATABASE=postgres
      - PGPASSWORD=postgres_password
      - PGPORT=5432
  client:
    build:
      dockerfile: Dockerfile.dev
      context: ./client
    volumes:
      - /app/node_modules
      - ./client:/app
  worker:
    build:
      dockerfile: Dockerfile.dev
      context: ./worker
    volumes:
      - /app/node_modules
      - ./worker:/app

此外,我还在 docker-compose.yml 文件的底部添加了一些Redis环境变量,这些变量位于 worker 服务的下面:

worker:
    build:
      dockerfile: Dockerfile.dev
      context: ./worker
    volumes:
      - /app/node_modules
      - ./worker:/app
    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379

我已经使用 docker-compose up --build 命令重新构建了镜像并重启了应用程序,但我仍然可以看到之前的xhr请求仍处于挂起状态,并且在一段时间后仍然会出现502和504错误。

解决方案

解决方案1

在你的 default.conf 文件中,你定义了一个名为 api 的上游服务器,但在 server 块内却仍然使用了 server server:5000;。这可能导致问题,因为你将上游服务器的名称从 server 改为 api,但在块内未做相应修改。

正确的配置应该是:

upstream client {
    server client:3000;
}
upstream api {
    server api:5000;  # 将这里的 server 改为 api
}
server {
    # ...
    location /api {
        rewrite /api/(.*) /$1 break;
        proxy_pass http://api;
    }
}

解决方案2

如果问题仍然存在,你可以考虑以下步骤:
1. 确保 Express API 能够及时响应请求。检查是否有任何潜在的性能问题或延迟。
2. 观察日志以查看是否有其他错误信息或警告,特别是在容器启动和运行过程中。
3. 尝试使用调试工具分析请求的流程,以确定是否有任何阻塞点。

解决方案3

考虑添加更多的监控和日志记录,以便更好地追踪请求的路径和响应时间。这将有助于识别潜在的问题并进行进一步的故障排除。

请注意,对于生产环境中的问题,建议进行逐步修改和测试,以避免对现有服务造成不必要的干扰。

总结

通过检查Nginx配置文件和Express API的性能,以及添加更多的监控和日志记录,你应该能够解决在Docker容器内出现502错误的问题。在做出任何更改之前,请确保你理解它们的影响并进行适当的测试。

正文完