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

基于Python http.server的自定义实现启用HTTPS后运行数小时无响应的问题排查求助

基于Python http.server的自定义实现启用HTTPS后运行数小时无响应的问题排查求助

各位好,我最近用Python的http.server模块搭了个自用的小服务,自定义了继承自BaseHTTPRequestHandler的请求处理器,原本一切正常,但升级到Python 3.12之后,启用HTTPS(TLS)的情况下,服务运行几个小时就会变得无响应,所有连接请求都会超时;但如果是debug模式(不启用HTTPS)的话,服务就能一直稳定运行。

先给大家贴一下核心代码(main.py里的关键部分):

# ...导入语句和其他辅助函数省略...

class RequestHandler(BaseHTTPRequestHandler):

    # ...其他自定义方法省略...

    def do_GET(self):
        resobj = self._manage_get_request()
        self.send_response(resobj.status_code)
        self._send_headers(resobj.headers)
        self._send_body(resobj.body)

def main():
    print('Running http server...')
    address = (_HTTP_SERV_ADDR, _HTTP_SERV_PORT)
    httpd = HTTPServer(address, RequestHandler)
    if not _DEBUG_ENABLED:
        print('Enabling TLS protocol...')
        context = _ssl.SSLContext(_ssl.PROTOCOL_TLS_SERVER)
        context.load_cert_chain(certfile=_CERTIFICATE_FILE_PATH,
                                keyfile=_KEY_FILE_PATH)
        httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
    print(f'Server is listening ({httpd.server_address[0]}:{httpd.server_port})...')
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    print('Shutting down http server...')
    httpd.server_close()

简单补充下我的实现细节:

  • _manage_get_request是我自己写的GET请求处理逻辑,会返回一个包含状态码、响应头和响应体的自定义Response对象
  • _send_headers是对父类send_header方法的封装,用来统一处理响应头发送
  • _send_body负责把响应体写入socket缓冲区

2025年1月6日 更新排查进展

我试了好几种代码调整都没解决问题,后来自己写了个简单的调用栈追踪装饰器,发现服务居然卡在了TCPServer.get_request方法里的socket.accept()调用上——而且看起来只有当几乎同时收到多个请求(间隔零点几秒)的时候才会触发这个情况。

目前我临时给这个方法加了个信号超时的机制,让服务能勉强继续运行,但这明显只是个临时 workaround,根本没解决根因:

class TimeoutException(BaseException):
    pass


def alarm_handler(signum, frame):
    print('Timeout reached!')
    raise TimeoutException


def get_request(self):
    # 重写TCPServer类的get_request方法,添加超时逻辑
    _signal.signal(_signal.SIGALRM, alarm_handler)
    _signal.alarm(30)
    try:
        result = self.socket.accept()
        _signal.alarm(0)
        return result
    except TimeoutException as e:
        _signal.alarm(0)
        raise OSError from e  # 调用方已经会处理OSError异常

我的服务是跑在基于ubuntu:latest的Docker镜像里的,现在实在搞不懂为什么启用HTTPS后会出现这个卡在accept的情况,想请各位大佬帮忙分析下可能的根因,以及正确的解决方法是什么?

备注:内容来源于stack exchange,提问作者rudicangiotti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 12:14:35