Python中uwsgi出现writing to a closed pipe/socket/fd错误如何解决

nginx+uwsgi+flask

uwsgi 错误日志:
Tue Jul 10 13:26:34 2018 - SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request /api/samples/87af0c678e4799392bb8fbfada5d69c5192dc6b6ca74de1ac8913e657121d103 (ip 10.72.30.186) !!!
Tue Jul 10 13:26:34 2018 - uwsgi_response_writev_headers_and_body_do(): Broken pipe [core/writer.c line 306] during GET /api/samples/87af0c678e4799392bb8fbfada5d69c5192dc6b6ca74de1ac8913e657121d103 (10.72.30.186)
OSError: write error

查不到解决方法,,求解答。
Python中uwsgi出现writing to a closed pipe/socket/fd错误如何解决


1 回复

这个错误通常发生在uWSGI worker进程尝试向已经关闭的连接(比如客户端提前断开)写入响应时。核心问题是你的应用代码没有正确处理连接中断的情况。

根本原因: 当客户端(浏览器、curl等)在请求完成前断开连接,uWSGI的worker进程仍会继续执行并尝试写入响应,这时就会触发这个IOError。

解决方案:

  1. 最直接的修复 - 捕获并忽略连接错误:
def application(env, start_response):
    try:
        # 你的应用逻辑
        response_body = b"Hello World"
        status = '200 OK'
        headers = [('Content-Type', 'text/plain')]
        start_response(status, headers)
        return [response_body]
    except (IOError, OSError) as e:
        # 连接已关闭,安静地忽略
        if 'write' in str(e) or 'pipe' in str(e) or 'socket' in str(e):
            # 返回空响应或记录日志
            return []
        raise
  1. 对于WSGI框架(如Flask/Django),使用中间件:
class IgnoreClosedConnectionMiddleware:
    def __init__(self, app):
        self.app = app
    
    def __call__(self, environ, start_response):
        try:
            return self.app(environ, start_response)
        except (IOError, OSError) as e:
            if any(x in str(e) for x in ['write', 'pipe', 'socket', 'closed']):
                return []
            raise

# Flask中使用
from flask import Flask
app = Flask(__name__)
app.wsgi_app = IgnoreClosedConnectionMiddleware(app.wsgi_app)
  1. uWSGI配置调整(治标不治本):
[uwsgi]
# 增加请求缓冲区大小
buffer-size = 65535
# 设置更长的请求超时
http-timeout = 300
socket-timeout = 300
# 启用harakiri模式,超时自动杀死worker
harakiri = 30

最佳实践:

  • 优先在应用层捕获并处理连接中断异常
  • 确保你的响应生成逻辑是幂等的,避免在连接中断后还修改共享状态
  • 对于长时间运行的任务,考虑实现进度检查或分块传输

一句话总结: 在应用代码中捕获IOError并安静处理客户端断开连接的情况。

回到顶部