weixin_44864723 2026-03-08 10:52 采纳率: 0%
浏览 3

emqx API Download a particular file 下载超大文件超时,服务器主动断开链接,有什么配置的地方么?

脚本报错:

requests.exceptions.ChunkedEncodingError: Response ended prematurely

emqx日志:

2026-03-07T14:35:41.874233+08:00 [error] Generic server <0.15174.0> terminating. Reason: {caller_down,<0.15173.0>}. Last message: {‘DOWN’,#Ref<0.3179383237.3557556227.51267>,process,<0.15173.0>,shutdown}. State: #{file => {file_descriptor,prim_file,#{handle => #Ref<0.3179383237.3557687312.27019>,owner => <0.15174.0>,r_buffer => #Ref<0.3179383237.3557687299.51268>,r_ahead_size => 0}},filename => <<“/home/aurora/data/transfers/exports/1F/0A/5409F16415E67614DCABACE3EA9B1F1BEA41/python-mqtt-file-transfer-1/123aa3/290.zip”>>,caller_pid => <0.15173.0>,mref => #Ref<0.3179383237.3557556227.51267>}.
2026-03-07T14:35:41.874549+08:00 [error] crasher: initial call: emqx_ft_storage_fs_reader:init/1, pid: <0.15174.0>, registered_name: , exit: {{caller_down,<0.15173.0>},[{gen_server,handle_common_reply,5,[{file,“gen_server.erl”},{line,2562}]},{proc_lib,init_p_do_apply,3,[{file,“proc_lib.erl”},{line,333}]}]}, ancestors: [emqx_ft_storage_fs_reader_sup,emqx_ft_sup,<0.5160.0>], message_queue_len: 0, messages: , links: [<0.5164.0>], dictionary: , trap_exit: false, status: running, heap_size: 4185, stack_size: 29, reductions: 93909; neighbours:
2026-03-07T14:35:41.874810+08:00 [error] Supervisor: {local,emqx_ft_storage_fs_reader_sup}. Context: child_terminated. Reason: {caller_down,<0.15173.0>}. Offender: id={<0.15173.0>,<<47,104,111,109,101,47,97,117,114,111,114,97,47,100,97,116,97,47,116,114,97,110,115,102,101,114,115,47,101,120,112,111,114,116,115,47,49,70,47,48,65,47,53,52,48,57,70,49,54,52,49,53,69,54,55,54,49,52,68,67,65,66,65,67,69,51,69,65,57,66,49,70,49,66,69,65,52,49,47,112,121,116,104,111,110,45,109,113,116,116,45,102,105,108,101,45,116,114,97,110,115,102,101,114,45,49,47,49,50,51,97,97,51,47,50,57,48,46,122,105,112>>},pid=<0.15174.0>.

  • 写回答

1条回答 默认 最新

  • 檀越@新空间 2026-03-08 10:57
    关注

    上午好☀️☀️☀️️
    本答案参考通义千问

    根据你提供的信息,EMQX 在下载超大文件时出现超时并主动断开连接,错误日志显示 ChunkedEncodingError: Response ended prematurely,这表明在客户端(如脚本)尝试接收响应时,服务器端提前关闭了连接。结合 EMQX 的日志内容,问题可能出在以下几点:


    一、问题分析

    1. EMQX 本身对大文件传输的限制

      • EMQX 默认配置中没有特别针对大文件下载的优化,尤其是在使用 HTTP API 下载文件时,可能会因为内存或超时设置导致连接中断。
    2. HTTP 协议和 Chunked Encoding 的问题

      • 当使用 requests 库下载大文件时,若未正确处理分块编码(Chunked Encoding),可能导致客户端提前结束响应。
    3. 网络或服务器资源不足

      • 如果服务器负载高,或者文件过大,EMQX 可能因资源不足而主动断开连接。
    4. 客户端脚本问题

      • 脚本中未正确处理大文件下载,例如未使用流式下载或未设置适当的超时参数。

    二、解决方案

    1. 优化 EMQX 配置

    • 增加超时时间:在 EMQX 的配置文件中调整相关超时参数,防止服务器过早断开连接。

      # 修改 emqx.conf 或 emqx.json
      # 增加如下配置项:
      http.listener.http.max_request_time = 600s  # 设置最大请求时间为 600 秒
      http.listener.http.keepalive_timeout = 600s  # 保持连接的超时时间
      
    • 调整文件读取方式:确保 EMQX 使用高效的文件读取机制,避免内存溢出。

    2. 客户端脚本优化

    • 使用流式下载:避免一次性加载整个文件到内存中,改用流式下载。

      import requests
      
      url = "http://your-emqx-server/api/v4/files/download/your-file-path"
      response = requests.get(url, stream=True)
      
      try:
          with open("downloaded_file.zip", "wb") as f:
              for chunk in response.iter_content(chunk_size=1024):
                  if chunk:
                      f.write(chunk)
      except requests.exceptions.ChunkedEncodingError as e:
          print(f"Error downloading file: {e}")
          # 重试逻辑或记录日志
      
    • 设置超时时间:为 requests.get() 添加超时参数,防止长时间等待。

      response = requests.get(url, stream=True, timeout=600)  # 设置超时为 600 秒
      
    • 使用 requests.adapters.HTTPAdapter 增加重试次数

      from requests.adapters import HTTPAdapter
      from requests.packages.urllib3.util.retry import Retry
      
      session = requests.Session()
      retries = Retry(total=5, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504])
      session.mount('http://', HTTPAdapter(max_retries=retries))
      session.mount('https://', HTTPAdapter(max_retries=retries))
      
      response = session.get(url, stream=True, timeout=600)
      

    3. 检查 EMQX 文件存储路径

    • 确保文件路径合法且可访问,避免因文件路径问题导致读取失败。

    • 建议将大文件存储在独立的存储系统中(如 S3、NFS、对象存储等),而不是直接通过 EMQX 内部文件系统处理。

    4. 增加日志级别以获取更多信息

    • 在 EMQX 中启用更详细的日志,帮助定位具体哪个模块出了问题。

      # 修改 emqx.conf
      log.level = debug
      

    三、重点配置修改示例

    | 配置项 | 说明 | 修改建议 | |--------|------|----------| | http.listener.http.max_request_time | 控制 HTTP 请求的最大时间 | 增加至 600s | | http.listener.http.keepalive_timeout | 控制 Keep-Alive 连接的超时时间 | 增加至 600s | | log.level | 日志级别 | 设置为 debug 以便调试 | | stream | 客户端下载方式 | 使用流式下载,避免内存溢出 |


    四、总结

    关键点:

    • EMQX 对大文件下载的默认配置不够友好,需要手动调优。
    • 客户端应使用流式下载,并设置合理的超时和重试机制。
    • 建议将大文件存储在外部存储系统中,减少 EMQX 的负担。

    如果以上方法仍无法解决问题,可以考虑使用其他协议(如 FTP、SFTP)进行大文件传输,或者使用 EMQX 的 MQTT 文件传输插件(如 emqx-mqtt-file-transfer)来优化传输过程。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月8日