组件配置机制

本页介绍了 Fuchsia 提供的不同配置机制,讨论了它们的优缺点,并就在这种情况下应使用哪种机制提供了指导。

结构化配置

结构化配置是由组件框架提供的一种符合人体工程学的灵活现代配置系统。结构化配置与许多 Fuchsia 工具集成,包括 ffxinspect 和产品组装,在大多数情况下应是您的首选。

组件开发者通过在组件的清单中定义配置键(每个键的名称和数据类型)来使用结构化配置。系统保证在组件启动时,为所有这些配置键提供值。系统会自动生成库,以便在运行时轻松读取配置值。组件并不关心系统的哪个部分提供了结构化配置值,也不需要处理缺失的配置。

您可以通过一系列不同的路径提供结构化配置值,例如:

  • 软件包构建规则。通过构建规则设置的配置值将包含在该组件所在的软件包中。配置在构建时是固定的,因此可以在发布签名期间进行验证。
  • Realm 构建器。借助 Realm 构建器集成,测试可以轻松设置配置值。两个主要用例是验证可配置的行为,以及更改配置以帮助实现可测试性。
  • 产品组装。借助产品组件,平台可以定义配置键,其值由产品提供。产品集成商会在其产品配置中提供值,这些值会内置在组件包中,可在版本签名期间进行验证。

RFC-0127 介绍了几种指定结构化配置值的其他方法,但这些方法尚未针对近期用例构建而成。如果您的用例需要上述任何功能,请评论下方链接指向的功能跟踪 bug:

  • Development overrides (https://fxbug.dev/42178358). 这样一来,开发者便可以在运行时对工程 build 更改配置,例如,使用预发布功能。
  • Vbmeta (https://fxbug.dev/42178359)。这样一来,您无需构建新映像即可修改版本的签名配置。
  • 父级组件 (https://fxbug.dev/42178351)。这样,组件在创建这些子项时就可以为动态集合中的子项指定配置。这要求两个组件之间的配置定义保持一致,因此可能仅支持同一映像或软件包中的组件之间。
  • 舰队和企业管理 (https://fxbug.dev/42055769)。这样,您就可以将结构化配置用于逐步发布、运行 A/B 实验和执行企业政策,就像在其他大型平台上运行实验系统一样。

组件的结构化配置定义是该组件本地的。不存在全局“配置版本”,并且系统不会对不同组件版本的向前或向后兼容性提供保证 - 兼容性由组件开发者决定。因此,结构化配置目前不适合作为针对不同配置版本构建的组件之间的通信方式。

结构化配置非常灵活,并且在大多数情况下都适用,但存在配置问题,而结构化配置并不是最佳解决方案:

  • 配置值必须在大量不同组件之间保持一致。结构化配置键在组件的清单中本地定义。产品组装可用于在几个不同组件上设置一致的配置值,但这会带来可维护性挑战,并且不能很好地扩缩。如果配置值在许多不同组件之间必须保持一致,则基于软件包的配置基于服务的配置是更好的解决方案。
  • 大型配置。当配置非常大(例如超过几千字节)时,结构化配置提供的用于设置和查看配置值的工具会变得很不方便。实现结构化配置不会优先高效处理较大的值。基于软件包的配置是大型配置数据的更好解决方案。
  • 在运行时频繁更改的配置。组件会在启动时收到其结构化配置值,这意味着必须重启组件实例才能选择新配置。基于服务的配置是必须在运行时频繁更改的配置更好的解决方案。
  • 由最终用户设置的配置。与开发者不同,最终用户需要通过界面来控制配置。此界面意味着,界面组件、正在配置的组件以及本地化数据库都需要就配置的定义达成一致,因此必须在某个版本化工件中集中定义配置。基于服务的配置配置是更好的配置解决方案,由最终用户控制。

基于软件包的配置

同一软件包可以路由到多个不同的组件,并且配置文件可以任意大。

基于软件包的配置通常不如结构化配置的人体工学;文件必须手动打开并解析,组件可能需要处理配置缺失或格式错误的问题,并且未与用于测试、调试或自省配置的标准工具集成。

基于软件包的配置不适用于以下问题:

  • 需要在运行时更改配置。请评论上述跟踪 bug,以便在结构化配置中支持动态配置,并/或改用基于服务的配置

基于软件包的配置有三种不同的变体,具体取决于用于存储配置的软件包:

全局(也称为“config_data”)软件包配置

单个全局 config_data 软件包包含许多不同组件的配置数据。使用“config_data”构建规则添加每个组件的数据。此全局软件包是在 CFv1 中使用基于打包的配置的唯一方式,但它在 CFv2 中不够灵活且繁琐,因为 config-data 目录必须通过组件拓扑手动路由。

config_data 用户应迁移到结构化配置domain/in-package 配置,这两种配置都提供更好的工效学设计,并且灵活性更高。

网域软件包配置

网域中组件的开发者可以定义自己的配置软件包,并将其目录路由到其控制的组件。与全局软件包配置不同,此机制可以用于不同的构建系统和花瓣。

软件包内配置

配置文件也可以与其配置的组件放在同一软件包中。这样可以确保配置随组件一起分布,并且不需要复杂和脆弱的路由。不过,这也意味着如果不重新打包组件,就无法更改配置。如需了解详情,请参阅有关为组件提供数据文件的指南。

软件包内容存储在 blobfs 中,blobfs 是一个内容寻址文件系统,用于删除重复的 blob。这意味着,如果多个软件包包含相同的配置 blob,则系统只会存储一个副本。

基于服务的配置

写入 Fuchsia 组件即可通过 FIDL 收集、维护和分发网域的配置数据。一个很好的例子是 Fuchsia 平台的“设置”服务,它维护各种用户设置(如语言区域):设置服务会在设备重启后维护这些用户设置的状态,并公开 fuchsia.settings FIDL 协议,其他组件可能使用该协议读取当前配置数据或请求更改配置数据。

基于服务的配置非常灵活且强大,但引入服务器组件通常比其他选项更复杂,并且会产生更高的运行时费用。仅当这项额外费用能够带来价值时,才应使用基于服务的配置。

该组件可能会使用多种不同的输入来确定正确的配置。例如:用于验证和组合客户端请求、从某些服务器收集的设置或通过某种其他机制(如结构化配置)提供的默认配置值的业务逻辑。当必须在各种客户端之间共享配置时,基于服务的配置非常有效,因为该配置是由用于传递它的 FIDL 接口正式定义和版本控制的。如果配置可能会频繁更改,基于服务的配置也非常实用。

基于服务的配置不适用于以下问题:

  • 大型配置。配置由 FIDL 消息传送,这些消息受 zircon 通道写入大小的限制。虽然 FIDL 协议可以通过将配置拆分为块或发送 VMO 来解决此问题,但这会破坏客户端简单性和明确定义(这些都是基于服务的配置强度)。处理大型配置时,基于软件包的配置是更好的解决方案。