实体的生命周期
本文档高度概括了目录后端以及实体在目录中流动所涉及的技术流程。 它主要面向希望在安装或扩展目录时了解其内部结构的开发人员。 不过,它也可以为其他人员提供信息。
关键概念
目录形成了一个类似中心的地方,从各种权威来源获取实体并保存在数据库中,进行自动处理,然后通过应用程序接口(API)显示出来,供 Backstage 和其他人员快速、方便地访问。 最常见的来源是YAML 文件这些文件在目录中注册,并由各自的 Owner 维护。 目录会确保根据这些文件的变化及时更新。
开发人员可以自定义目录的主要扩展点有
- 实体提供者--将原始实体数据输入目录;
- 政策--制定关于实体形状的基准规则;
- 处理程序--验证、分析和修改原始实体数据,使其成为最终形式。
所涉及的高级流程包括
- 在这里,实体提供者从外部来源获取原始实体数据,并将其播入数据库;
- 在这里,策略和处理器不 断处理所摄取的数据,并可能同时发出其他原始实体(也要进行处理)、错误、与其他实体的关系等;
- 在这里,各种处理器发出的所有数据被组合在一起,成为最终的输出实体。
一个实体在通过最后一个流程并进入最终实体之前,是不会被外界看到的(通过目录 API)。
下文将详细介绍这些过程。
摄取数据
每个目录部署都有一些实体提供者它们负责以自己认为合适的方式从外部权威来源获取数据,将这些数据转化为实体对象,并在添加或删除这些实体时通知数据库。 它们是未处理的实体如果没有实体提供者,就不会有实体进入系统。
数据库会始终跟踪属于每个提供商的实体集;没有两个提供商可以尝试输出相同的实体。 当一个提供商发出删除实体的信号时,就会导致一个急于删除清除:立即清除数据库中的实体及其导致的所有辅助数据。
默认安装了两个提供程序:一个用于处理用户注册的位置(例如 YAML 文件的 URL),另一个用于处理应用程序配置中的静态位置。 你可以在后端初始化代码中将更多第三方提供程序传递给目录创建程序,也可以轻松编写自己的提供程序。
实体提供程序是一个实现EntityProvider
它有三个主要部分:
- 身份:每个提供程序实例都有一个唯一、稳定的标识符,数据库可 以用它来跟踪每个未处理实体的发起者。
- 连接:在后端启动时,每个提供程序都会连接到目录运行时。
- 事件流:在其生命周期内,提供程序可以在任何时间点向运行时发出更改事件,以修改其未处理实体集。
提供商完全可以选择如何以及何时产生这些变化事件。 例如,应用程序配置提供商只在启动时进行一次更新,然后就处于休眠状态。 位置数据库提供商在启动时进行一次初始更新,然后在每次检测到位置数据库发生变化时进行小规模的 delta 更新。 LDAP 提供商由一个定时器循环从外部驱动,偶尔会触发一次全面更新。 未来的某些提供商可能完全由事件驱动,通过事件总线或网络钩子提供信息。 提供商之间不存在神奇的协调;如果它们需要在彼此间安排同步或锁定(例如,为了避免在多个目录服务机器上重复工作),它们需要在带外进行处理。
所发射的实体会经过一些粗略的验证,以确保它们至少符合关于实体形状的最基本模式规则。 例如,它们需要有一个kind
, ametadata.name
和一个metadata.namespace
除此之外,摄取阶段认为自己的工作已经完成,并将未处理的实体存储起来,以便处理系统在稍后时间进行处理。 这意味着,您为实体设置的更精确的验证规则是不是现阶段尚未应用。
处理
每个未处理的实体都带有一个时间戳,它告诉处理循环下次尝试处理它的时间。 当实体首次出现时,这个时间戳被设置为 "现在"--要求尽快处理它。
每个目录部署都有一些处理器它们负责接收目录认为需要处理的未处理实体,然后通过一系列处 理阶段运行这些数据,对实体进行变异,并输出有关实体的辅助数据。 所有这些工作完成后,目录会获取所有信息,并将其作为已处理实体、错误和与其他实体的关系单独存储。 然后,目录会检查这些输出触及了哪些实体,并触发这些实体的最终组装(请参阅下文的 "缝合")。
实体总是一个接一个地处理,但所有目录服务主机都会协同处理,以分散负载。 请注意,每个处理器都可以为处理管道中的一个或多个固定步骤做出贡献。 首先,所有处理器为一个步骤做出的贡献都会按照处理器注册的顺序运行,然后,所有处理器为下一个步骤做出的贡献都会按照相同的顺序运行,依此类推。
每一步都有机会选择性地修改实体,并选择性地发出其他信息。 例如,处理器可能会查看spec
如果处理器输出了一个实体,那么这个实体就会被逐字存储,并带有一个时间戳,说明它也应该尽快被处理。 如果输出了错误,那么就说明这个实体出了问题,它不应该取代我们之前在最终实体中的无错版本。 如果输出了关系,那么它们就会被放到一个专用的关系表中,由下面的拼接过程来处理。
可选的低级细节说明:当实体被发射时,目录会跟踪发射实体和被发射实体之间的 > 边。 这发生在幕后,从外部隐藏起来,用来形成 > 图。 这和关系不是一回事!这些边的目的是 > 能够检测到实体何时成为孤儿(见下文),并 > 能够在整个图中执行急切删除,当根被明确 > 取消注册,并且没有其他东西可以让低级节点存活时。 我们将在本文稍后部分详细讨论 > 孤儿和删除。