组件配置页面介绍了如何在 Fuchsia 上配置组件,并介绍了需要进行组件配置的不同情况。
本页介绍了 Fuchsia 提供的各种配置机制,介绍了它们的优点和缺点,并提供了有关在哪种情况下使用哪种机制的指导。
结构化配置
结构化配置是由组件框架提供的现代、符合人体工程学且灵活的配置系统。结构化配置与许多 Fuchsia 工具(包括 ffx、检查和产品组装)集成,在大多数情况下应是您的首选。
组件开发者通过在组件的清单中定义配置键(每个配置键都有名称和数据类型)来使用结构化配置。系统保证在组件启动时为所有这些配置键提供值。库是自动生成的,以便在运行时轻松读取配置值。组件无需关心系统的哪个部分提供了结构化配置值,也不需要处理缺少的配置。
结构化配置值可通过多种不同的路径提供,例如:
- 软件包构建规则。通过构建规则设置的配置值会与组件包含在同一软件包中。此配置在构建时固定,因此可以在发布签名期间进行验证。
- Realm 构建器。借助 Realm 构建器集成,测试可以轻松设置配置值。这两个主要用例是验证可配置行为和更改配置以提高可测试性。
- 产品装配。借助产品组装,平台可以定义由产品提供值的配置键。产品集成商在其产品配置中提供值,这些值会内置到组件软件包中,以便在发布签名期间进行验证。
- 开发覆盖。借助此 ffx 工具,开发者可以在工程 build 运行时更改配置,例如使用预发布功能。
RFC-0127 介绍了指定结构化配置值的几种其他方法,但这些方法尚未构建,正在等待近期的使用情形。如果您的用例需要上述任何功能,请对下方链接的功能跟踪 bug 进行评论:
- Vbmeta (https://fxbug.dev/42178359)。这样,您就可以在不构建新映像的情况下修改已签名的配置以适应版本。
- 父级组件 (https://fxbug.dev/42178351)。这样,组件就可以在创建动态集合中的子项时为这些子项指定配置。这需要两个组件之间的配置定义保持一致,因此可能仅支持在同一映像或软件包中的组件之间使用。
- 车队和企业管理 (https://fxbug.dev/42055769)。这样一来,结构化配置便可用于增量发布、运行 A/B 实验和强制执行企业政策,类似于其他大型平台中的实验系统。
组件的结构化配置定义是相应组件的本地配置定义。不存在全局“配置版本”,并且系统无法保证组件各个版本之间的向前或向后兼容性,兼容性取决于组件开发者。因此,结构化配置目前不适合用作可能针对不同配置版本构建的组件之间的通信方式。
结构化配置非常灵活,适用于大多数情况,但对于某些配置问题,结构化配置并不是最佳解决方案:
- 配置值必须在大量不同组件中保持一致。结构化配置键是在组件的清单中本地定义的。产品组装可用于在几个不同的组件中设置一致的配置值,但这会带来可维护性方面的挑战,并且无法很好地扩缩。如果配置值必须在大量不同组件之间保持一致,则基于软件包的配置或基于服务的配置是更好的解决方案。
- 大型配置。当配置变得非常大(例如超过几千字节)时,结构化配置提供的用于设置和查看配置值的工具会变得非常不方便。结构化配置的实现不会优先处理大型值。基于软件包的配置是适用于大型配置数据的更好解决方案。
- 运行时频繁更改的配置。组件在启动时会收到其结构化配置值,这意味着必须重启组件实例才能获取新配置。对于必须在运行时频繁更改的配置,基于服务的配置是更好的解决方案。
- 由最终用户设置的配置。与开发者不同,最终用户需要界面来控制配置。这种界面意味着界面组件、要配置的组件和本地化数据库都需要就配置定义达成一致,因此必须在某个版本化工件中集中定义配置。对于由最终用户控制的配置,基于服务的配置是更好的解决方案。
基于软件包的配置
同一软件包可以路由到多个不同的组件,并且配置文件可以任意大小。
与结构化配置相比,基于软件包的配置通常不太符合人体工学;必须手动打开和解析文件,组件可能需要处理缺失或格式错误的配置,并且不与标准工具集成以测试、调试或自省配置。
基于软件包的配置不适用于以下问题:
- 需要在运行时更改配置。请对上述跟踪 bug 发表评论,了解结构化配置中的动态配置支持,并/或改用基于服务的配置。
基于软件包的配置有三种不同的变体,具体取决于用于存储配置的软件包:
全局(也称为“config_data”)软件包配置
单个全局 config_data
软件包包含许多不同组件的配置数据。使用“config_data”build 规则添加每个组件的数据。在 CFv1 中,此全局软件包是使用基于软件包的配置的唯一方式,但在 CFv2 中,由于必须手动通过组件拓扑路由 config-data 目录,因此这种方式不灵活且繁琐。
config_data 的用户应迁移到结构化配置或网域/软件包内配置,这两种配置都具有更好的人体工学设计和更高的灵活性。
网域软件包配置
网域中组件的开发者可以定义自己的配置数据包,并将其目录路由到他们控制的组件。与全局软件包配置不同,此机制可在不同的构建系统和花瓣中使用。
软件包内配置
配置文件也可以与其配置的组件放置在同一软件包中。这样可确保配置将随组件分发,而无需复杂且脆弱的路由。不过,这也意味着,如果不重新打包组件,则无法更改配置。如需了解详情,请参阅有关向组件提供数据文件的指南。
软件包内容存储在 blobfs 中,这是一种内容寻址文件系统,用于删除重复的 blob。这意味着,如果多个软件包包含相同的配置 blob,则只会存储一个副本。
基于服务的配置
您可以编写 Fuchsia 组件,以便通过 FIDL 收集、维护和分发网域的配置数据。一个很好的例子是 Fuchsia 平台的设置服务,该服务会维护各种用户设置(例如语言区域):设置服务会在各个电源周期中维护这些用户设置的状态,并公开 fuchsia.settings
FIDL 协议,其他组件可以使用这些协议来读取当前配置数据或请求更改配置数据。
基于服务的配置可能非常灵活且功能强大,但引入服务器组件通常比其他选项工作更多,并且会导致更高的运行时成本。只有在额外费用能够带来价值时,才应使用基于服务的配置。
该组件可能会使用多种不同的输入来确定正确的配置。例如:用于验证和合并客户端请求的业务逻辑、从某些服务器收集的设置或通过某种其他机制(如结构化配置)提供的默认配置值。当必须在各种客户端之间共享配置时,基于服务的配置非常有效,因为配置是由用于提供配置的 FIDL 接口正式定义和版本控制的。当配置可能会频繁更改时,基于服务的配置也非常适用。
基于服务的配置不适用于以下问题:
- 大型配置。配置由 FIDL 消息传送,这些消息受 zircon 通道写入大小的限制。虽然 FIDL 协议可以通过将配置拆分为多个分块或发送 VMO 来解决此问题,但这会破坏基于服务的配置的优势,即客户端的简单性和明确定义。使用大型配置时,基于封装的配置是更好的解决方案。