Skip to content

文件传输服务端配置

EMQX 默认情况下不启用 MQTT 文件传输功能。若您希望使用该功能,您需要在配置文件或 Dashboard 中进行设置。

本页主要介绍了如何启用 EMQX 中的文件传输功能并在 EMQX 服务端配置文件传输的各项功能,包括分片存储,在本地磁盘和 S3 存储桶中导出合并后的文件。同时还介绍了如何进行 MQTT 传输的配置以优化服务端对文件传输的操作。以下章节具体介绍了如何通过配置文件来进行配置操作:

您也可以通过 Dashboard 来启用和配置文件传输功能,详细内容参阅:通过 Dashboard 启用和配置文件传输

本页还介绍了如何通过 REST API 管理导出的文件。具体内容参阅:管理导出的文件

启用文件传输

在 EMQX 中,文件传输功能默认是关闭的,您需要在配置文件中启用该功能。

bash
file_transfer {
  enable = true
}

添加此配置后,EMQX 会默认将分片文件存储在 data/file_transfer/segments 目录下,并启用本地磁盘导出功能,将合并后的文件导出到 data/transfers/exports 目录下。

如果您需要进一步配置文件传输功能,可以参考后续的配置说明。

配置分片存储

EMQX 支持客户端上传文件分片,并在接收到所有分片后将其合并为完整的文件。为了支持这一点,EMQX 需要暂存传输过程中的分片文件,并对其进行管理。

目前 EMQX 仅支持将分片文件存储到磁盘,您可以配置分片的存储位置。

文件完成上传后,分片将会被自动清理。对于超时未完成上传的文件,您也可以配置分片的有效期和定时清理时间,避免磁盘空间被占满。

bash
file_transfer {
  # 启用文件传输功能
  enable = true

  # 分片存储配置
  storage.local.segments = {
    # 分片存储目录,建议优先设置到高 I/O 性能的磁盘上。
    root = "./data/file_transfer/segments"
    
    # 定时清理已过期的分片文件
    gc {
      # 清理间隔
      interval = "1h"

      # 分片存储最大有效期,达到有效期之后,即使分片未被合并也将被清除。
      # 客户端指定的有效期不得超过此值。
      maximum_segments_ttl = "24h"
    }
  }
}

您需要根据预期的文件大小、并发传输数量和可用磁盘空间设置合理的配置。

配置文件导出

在所有分片传输完成后,EMQX 支持合并分片为完整文件,并将完整文件文件导出到本地磁盘或 S3 存储桶,以便应用集成使用。

TIP

不配置文件导出的情况下,默认导出到本地磁盘。EMQX 不支持同时配置两种导出方式,只能选择其中一种使用。

文件导出到本地磁盘

使用以下配置示例会将合并后的完整文件保存在本地磁盘上,您可以配置导出文件的存储位置和有效期。

bash
file_transfer {
  # 启用文件传输功能
  enable = true


  # 分片存储配置
  # ...

  # 启用本地磁盘文件导出
  storage.local.exporter.local {
    enable = true
    # 导出文件存储目录,建议优先设置到高 I/O 性能的磁盘上。
    root = "./data/transfers/exports"
  }
}

文件导出到 S3 存储桶

使用以下配置示例会将合并后的完整文件保存到 S3 存储桶中。

bash
file_transfer {
  # 启用文件传输功能
  enable = true

  # 分片存储配置
  # ...

  # 启用 s3 存储桶文件导出
  storage.local.exporter.s3 {
    enable = true

    host = "s3.us-east-1.amazonaws.com"
    port = 443

    # 用于访问 S3 的凭证
    access_key_id = "AKIA27EZDDM9XLINWXFE"
    secret_access_key = "******"

    # 导出文件存储桶
    bucket = "my-bucket"

    # 共享 URL 过期时间
    # EMQX 会生成一个临时的共享 URL,用于客户端直接从 S3 中下载文件。此参数用于指定 EMQX 通过 API 返回的文件下载 URL 的过期时间,过期后 URL 将不可用,实际 S3 中文件仍然存在。
    #url_expire_time = "1h"

    # 用于与 S3 的底层 HTTP(S) 连接的设置,允许安全文件上传和连接池管理。
    transport_options {
      ssl.enable = true
      connect_timeout = 15s
    }
  }
}

配置 MQTT 传输

为了优化文件传输操作并防止客户端等待时间过长,我们可以为文件传输操作设置特定的超时时间,可以配置以下 MQTT 传输设置:

bash
file_transfer {
  enable = true

  init_timeout = "10s"
  store_segment_timeout = "10s"
  assemble_timeout = "60s"
}
  • init_timeout:初始化操作的超时时间。
  • store_segment_timeout:文件分片存储超时时间。
  • assemble_timeout:文件分片拼接超时时间。

如果这些操作中的任何一个超过了指定的超时时间,MQTT 客户端将收到带有 RC_UNSPECIFIED_ERROR 代码的 PUBACK 数据包。

通过 Dashboard 启用和配置文件传输

本节演示如何在 Dashboard 上启用文件传输并配置其功能。

转到 EMQX Dashboard 并点击 管理 -> 文件传输。在文件传输页面,您可以点击 启用 开关以启用文件传输功能。您可以参考常规设置高级设置来配置功能。配置完成后,点击 保存修改

file-transfer-enable

常规设置

您可以配置以下常规设置:

  • 初始化超时时间init 命令执行超时的最大时间。例如,如果系统过载且无法在此时间内处理 init 命令,则操作将超时。在这种情况下,将发送带有错误代码(0x80)的 PUBACK 消息以指示失败。默认值为 10s
  • 分片存储目录:上传文件的临时分片存储的目录路径。选择绝对路径至关重要,最好位于具有高 I/O 性能的磁盘上。这样可以在高负载下有效处理文件分片。
  • 文件存储:选择文件的导出方法,选项包括 本地存储S3 存储。选择 S3 存储时,需要进行额外配置:
    • 地址:S3 服务的端点。例如 s3.us-east-1.amazonaws.com
    • 端口:用于连接 S3 服务的端口,例如 443,表示安全的 HTTPS 连接。
    • 访问密钥 ID访问密钥:用于访问 S3 存储桶的凭据。应安全地保存。
    • 存储桶:存储文件的 S3 存储桶的名称,例如 my-bucket
    • 启用 TLS:确定是否使用 TLS(传输层安全性)进行安全文件传输。有关更多信息,请参阅启用 TLS 加密访问外部资源
  • 文件存储目录:指定文件存储的目录,需要为绝对路径。当选择 本地存储 作为文件存储方法时,此目录用于存储已合并的文件。

高级设置

根据您在常规设置中配置的文件存储方法,可以配置不同的高级设置。

本地存储

如果选择将文件导出到本地存储,您可以配置以下高级设置。

字段名称描述推荐值
分片存储超时时间指定使用 segment 命令存储文件段的最大时间。如果超出此时间(例如,由于系统过载),将发送带有错误代码(0x80)的 PUBACK 消息,表示超时。5 分钟
文件拼接超时时间定义允许 fin 命令完成文件拼接过程的最大持续时间。如果超时,则将发送带有错误代码(0x80)的 PUBACK 消息。此设置在系统资源受限导致文件拼接延迟的情况下至关重要。5 分钟
存储垃圾回收间隔设置文件存储系统中运行存储垃圾收集过程的间隔。这个过程有助于通过删除不必要的数据来管理存储空间。1 小时
分片存储最大有效期设置分片存储的最大生存时间(TTL)。超过此 TTL 的分片将自动清理,无论它们是否已合并成完整文件或在文件传输期间指定了更长的 TTL。24 小时
分片存储最小有效期设置分片存储的最小生存时间(TTL)。即使它们已经合并成完整文件或在文件传输期间指定了更短的 TTL,分片也不会在此 TTL 过期之前被删除。这确保了分片在任何后处理或冗余要求下至少可用最小持续时间。5 分钟

S3 存储

如果选择将文件导出到 S3 存储,除了与本地存储相同的设置外,还可以配置以下高级设置。

字段名称描述推荐值
URL 过期时间确定生成的用于访问 S3 上上传文件的 URL 的有效期。一旦过期,URL 将无法再用于访问文件。-
最小分片大小指定将文件分成多个分片上传到 S3 时每个分片的最小大小。较小的分片大小可以增加上传频率,但可能有助于在不稳定连接环境中处理大文件。5 MB
最大分片大小定义多个分片上传到 S3 时每个分片的最大大小限制。更大的分片意味着更少的上传操作,这对于高带宽环境可能有效,但可能消耗更多内存。5 MB
ACL访问控制列表(ACL)指定上传到 S3 存储桶的对象的权限。不同的 ACL 选项提供不同级别的访问控制:
private:仅所有者具有完全访问权限。
public_read:所有人都有读取权限。
public_read_write:所有人都有读写权限。
authenticated_read:仅经过身份验证的用户具有读取权限。
bucket_owner_read:存储桶所有者具有读取权限。
bucket_owner_full_control:存储桶所有者具有完全控制权。
-
IPV6 探针确定是否检查 IPv6 连接。如果您的网络支持 IPv6,则启用此选项可能有利,确保兼容性并可能提高性能。启用
连接超时允许建立到 S3 服务器的连接的最大时间。如果连接时间超过此持续时间,则超时。此设置确保来自服务器的及时响应。-
连接池类型指定用于管理 S3 连接的连接池的类型:
random:随机选择连接。
hash:使用哈希函数选择连接。这个选择可能会影响连接到 S3 的性能和可靠性。
random
连接池大小定义 S3 连接的连接池的大小。更大的池可以处理更多的并发连接,但消耗更多资源。8
HTTP 管道指定在不等待每个响应的情况下可以发送的 HTTP 请求数量。这可以提高吞吐量,但可能增加复杂性。100
请求头允许为 S3 请求添加自定义请求头。这可以用于向 S3 服务传递额外信息或控制参数。点击 添加 来指定键值对。-
最大重试次数指定在发送请求错误时 S3 请求的最大重试次数。增加此值可以提高可靠性,但可能导致潜在的延迟。-
HTTP 请求超时允许 S3 请求完成的最大时间。如果请求耗时更长,则会超时。

管理导出的文件

您可以对导出的文件进行管理,比如列出文件以浏览文件的详细信息、移动文件、删除文件或下载文件。您通过 REST API 进行这些管理操作,也可以进行手动管理。未来版本将添加 Dashboard 界面用于管理导出文件。

通过 REST API 管理导出文件

EMQX 提供了 REST API 用于管理导出的文件,您可以使用 MQTT 文件传输管理 API 进行管理,实现文件的浏览与下载。

手动管理磁盘导出文件

如果您需要直接在磁盘上管理导出的文件,例如进行移动、使用自建的 FTP 或 HTTP 服务下载,可以参考以下说明获取文件存储位置。

为了解决文件名冲突和单个目录下文件数量过多的问题,EMQX 在保存导出文件时,使用了分桶存储方案。该方案工作原理如下:

  • 先计算出文件 ID 和客户端 ID 的 sha256 哈希值,比如:ABCDEFG012345...
  • 将文件存储在 6 级目录层次结构中,每一级定义如下:
    1. 哈希的前两个字节作为第一级目录名称;
    2. 接下来的两个字节作为第二级目录名称;
    3. 剩余的哈希作为第三级目录名称;
    4. 转义的客户端 ID;
    5. 转义的文件 ID;
    6. 元数据中的文件名作为最后一层。

例如,导出的文件会存储在这样的位置中:AB/CD/EFGH.../{clientid}/{file_id}/{filename}

手动管理 S3 存储桶导出文件

对于 S3 存储桶,您可以使用 S3 客户端工具或 S3 提供的 REST API 进行管理,实现文件删除、下载等操作。您可以可以参考以下说明获取文件存储位置。

与本地导出使用的分桶存储方案不同,使用 S3 存储桶导出的文件使用更简单的 3 级层次结构存储:

  1. 转义的客户端 ID;
  2. 转义文件 ID;
  3. 文件名。

例如,导出的文件会存储在这样的位置中:{clientid}/{file_id}/{filename}

TIP

更多关于使用 S3 客户端工具或 REST API 的操作,可以参考以下资源: