使用uWSGI部署Flask API的Docker容器无法相互通信
容器间通信故障排查与解决
环境配置
Docker Compose 配置
nginx: build: ... container_name: ... restart: always hostname: my-host ports: - "80:80" expose: - 80 networks: - my-net micro1: build: ... container_name: ... restart: always hostname: my-host expose: - 8080 networks: - my-net micro2: build: ... container_name: ... restart: always hostname: my-host expose: - 8081 networks: - my-net
uWSGI 配置(以micro1为例)
[uwsgi] wsgi-file = micro1.py callable = micro1_api socket = :8080 ...
故障现象
- 容器间用
requests发起请求时,日志报错:invalid request block size: (max 4096)...skip uwsgi - 增大uWSGI的
buffer-size后,日志出现uwsgi_proto_uwsgi_parser(): Success [proto/uwsgi.c line 40],但请求超时 - 若将uWSGI协议改为HTTP,容器内部调用正常,但Nginx的
uwsgi_pass配置无法处理请求
解决方案
方案1:让uWSGI同时监听uwsgi协议和HTTP协议
修改uWSGI配置,同时开启uwsgi套接字和HTTP服务,兼顾Nginx反向代理需求和容器间HTTP通信:
[uwsgi] wsgi-file = micro1.py callable = micro1_api # 给Nginx用的uwsgi协议套接字 socket = :8080 # 给容器间通信用的HTTP服务 http = :8082 ...
容器间通信时,直接请求目标服务的8082端口(比如micro2调用micro1时用http://micro1:8082/xxx),Nginx依然通过8080端口用uwsgi协议转发请求。
方案2:使用uwsgi协议客户端发起容器间请求
放弃requests的HTTP请求方式,改用uWSGI官方Python客户端库uwsgi直接发送uwsgi协议请求:
import uwsgi # 连接到micro1的uwsgi套接字 uwsgi.connect("micro1:8080") # 发送请求 uwsgi.send("GET /path HTTP/1.1\r\nHost: micro1\r\n\r\n") # 接收响应 response = uwsgi.recv(4096) uwsgi.close()
这种方式直接与Nginx转发协议保持一致,无需修改uWSGI监听配置。
方案3:统一协议为HTTP,调整Nginx配置
如果允许调整Nginx配置,可将uWSGI改为纯HTTP模式:
- 修改uWSGI配置:
[uwsgi] wsgi-file = micro1.py callable = micro1_api http = :8080 ...
- 修改Nginx配置,将
uwsgi_pass替换为proxy_pass:
location /micro1/ { proxy_pass http://micro1_upstream; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
调整后容器间HTTP请求正常,Nginx也可通过反向代理处理请求。
内容的提问来源于stack exchange,提问作者Cătălin Florescu
相关产品推荐
相关产品推荐

