问题描述
在一个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错误的问题。在做出任何更改之前,请确保你理解它们的影响并进行适当的测试。