同步: 使用 Artifactory 跨多站点拓扑管理二进制文件 | JFrog
简介
软件开发趋于从高度本地化的团队工作转变为遍布全球的大型团队的协同工作。 这种全球协作需要一个同为全球规模的架构来管理软件制品和可部署软件包。 这其中有三大目标: 本地性、可靠性和冗余性。
本地性是现代分布式开发的一个重要方面。 当一个组织的开发团队分布在世界各地时,确保开发效率不受网络延迟和带宽限制非常重要。 要实现这一点,就要确保所有开发需求(例如外部和内部依赖项)都存在于本地。 本地性还有利于提高可靠性,因为它可以确保开发和部署活动不会因为外部网络故障而停止。 此外,您还希望区域内的关键服务具有高可用性,以免数据中心内的单个硬件故障限制对服务的访问。
这样一来,可靠性又因冗余性而增强。 即使是通常仅在特定数据中心中使用的软件包,当该数据中心突然变得不可用时,也可能需要在其他地方使用。
本白皮书从这三个目标出发,描述了 JFrog Artifactory Pro 专业版制品仓库和 Artifactory Enterprise 企业版制品仓库的架构和使用方面的最佳实践。
无论采用哪种网络拓扑或开发方法,Artifactory 独特的同步功能集都可确保本地性。 考虑到建立特定的分布式流水线和协作的要求,您有多种方案可以选择。 这些方案包括推拉同步拓扑、远程仓库以及不同的同步计划策略,例如按需同步、定期同步或基于事件的同步。
本白皮书为使用这些不同方案提出了最佳实践,并就选择方案时的考虑因素作出指导。
本白皮书还介绍了如何使用 JFrog Mission Control 来设置、管理和操作这些全球拓扑。
按需代理
按需代理是所有远程仓库的默认行为,无论是代理组织控制下的其他节点,还是代理第三方节点。 当某项作业需要使用远程按需仓库中的制品时,Artifactory 会下载并缓存该文件,以备将来使用。 如果要禁用这一行为,您可以在仓库配置中选择“离线”按钮。 这样,Artifactory 便会只提供已缓存的远程制品。制品的跨站点同步可以依赖远程仓库所实现的按需代理或者本地仓库所实现的不同同步选项。远程仓库
远程仓库可以作为通过远程站点(如 JCenter 或 Maven Central)管理的仓库的缓存代理。 制品在远程仓库中的存储和更新遵循各项配置参数,这些参数用于控制缓存和代理行为。
了解更多 >
本地仓库
本地仓库是物理的、本地管理的仓库,您可以在其中部署制品。 本地仓库一般用于部署内部和外部的版本发布以及开发构建,也可用于存储未在公共仓库中广泛提供的二进制文件, 比如第三方商业组件。 如果使用本地仓库,您的所有内部资源都可以通过一个通用 URL 经由一个访问点共享到您的整个组织内。
了解更多 >
同步仓库
Artifactory 支持两种主要的同步模式: 推送同步和拉取同步。 每种模式都支持两种触发方式,即定期触发和事件触发。1. 推送同步
推送同步用于同步本地仓库,其实现方式是近端的 Artifactory 服务器向远端发起制品同步。 制品制作者可以利用推送同步,将其制品分发到其他站点,以供其用作依赖项。 除了极少数例外情况,用户没有对远端的“写”访问权,并且应该只有一个站点充当主站点,其他站点均为它的从站点。 调用推送同步的方法有两种: 定期调用和基于事件的调用。定期同步
以异步方式安排的定期推送,使用 Cron 表达式来决定何时触发下一次同步。 即使计划使用事件触发的方式来调用同步,也需要 Cron 表达式。 定期同步可以作为基于事件的同步的备用方案,确保即使某个制品的基于事件的同步由于某种原因(例如网络错误)而失败,最终也能实现所有制品的同步。 Artifactory 采用基于校验和的存储和同步机制,因此,如果某些制品已经存在于远端(即使名称或存储路径不同),则这些制品不会被传输。也就是说,即使您配置的同步方式有所重叠(例如同时采用定期同步和基于事件的同步),也不会造成任何妨碍。基于事件的同步
每次制品创建、复制、移动或删除操作都会立即传播到远端,因此推送几乎是实时发生的。 Artifactory 支持从一个仓库向远端另一个仓库进行基于事件的推送同步。 制品仓库 JFrog Artifactory 企业版 支持多通道推送同步,允许您同时向多个节点同步仓库。 另一种方法是建立同步链,即每个节点将制品传播到另一个节点,从而建立一条节点链。 这种解决方案更加复杂,难以建立,并且增加了节点之间不一致的风险,因此不符合仓库同步的最佳实践理念。 这种解决方案还存在循环同步的风险(即 A 推送到 B,B 推送到 C,C 推送回 A),可能对您的系统产生灾难性影响,所以必须极力避免。 如果您需要向多个仓库同步,并且没有 Artifactory 企业版,建议您使用拉取同步。 为了确保近端的所有更改都传播到远端,必须要采用定期同步与基于事件的同步相结合的方式。2. 拉取同步
拉取同步是指有计划的预填充远程仓库缓存。 远程站点需要获取制品时,一般是在首次请求时获取,这是远程仓库的常规操作。但是远程站点采用拉取同步则可以提早获取(按需获取)所需的制品。 例如,某一天在远程站点中生成的制品可以在夜间同步并保存在缓存中,以备第二天早上作为依赖项使用。 远程仓库调用拉取同步的方式有两种: 定期调用和基于事件的调用。 从远端调用同步的远程仓库可以从任何类型的仓库(本地、远程或虚拟仓库)中拉取制品。 推送和拉取同步仓库中均可配置同步删除。 这项配置是可选的,默认不启用。 按需代理同步不支持删除。虚拟仓库
虚拟仓库可以封装任意数量的本地和远程仓库,并将它们表示为通过单个 URL 访问的统一仓库。 借助虚拟仓库,您可以管理开发人员对各个仓库的访问权限,因为您可以自由混合、匹配和修改虚拟仓库中包含的实际仓库。 为了优化制品解析过程,Artifactory 会首先查询本地仓库,再查询远程仓库缓存,只有在前两者都没有所需制品的情况下,才会通过网络直接向远程资源请求制品。 对于开发人员来说,这很简单。 只需发出软件包请求,Artifactory 就会根据您组织的政策以安全且最佳的方式获取它。
了解更多 >
定期同步
通过由 Cron 表达式定义的计划来调用拉取同步,以定期同步仓库。基于事件的同步
拉取同步由远端的远程仓库调用,可以从任何类型的仓库(源 Artifactory 服务器的本地、远程或虚拟仓库)中拉取制品。 每次制品的创建、复制、移动或删除操作都会立即从源 Artifactory 服务器传播到远端,因此拉取操作几乎是实时发生的。 当事件触发同步时,正在向远端同步的制品无论同步过程是否完成,都可以通过 Artifactory 的远程仓库的远程代理机制准备就绪。 因此,对这些制品的请求不会失败。 利用基于事件的拉取同步,多个目标服务器可以从有效实现一对多同步配置的同一个源服务器拉取制品,而不必通过同步链依次传递制品,从而减少目标服务器上的流量。 利用基于事件的拉取同步,可以均衡定期同步所导致的网络吞吐量突发。 这种方案还可以减少对源节点计算资源的需求,将同步计算逻辑分布到目标节点。 仅 Artifactory 企业版仓库支持基于事件的拉取同步。 为了确保近端的所有更改都传播到远端,必须要采用定期同步与基于事件的同步相结合的方式。高可用性
Artifactory 支持高可用性网络配置,一个集群可包含同一局域网上的 2 个或更多个 Artifactory 服务器。 集群中的服务器之间可以共享资源,从而构建一个冗余的网络架构,实现负载平衡和故障转移,避免出现单点故障。 但是,为了保持高可用性,集群中的各个 Artifactory 服务器的地理位置需要彼此靠近(最好是安装在同一个数据中心),网络延迟不超过 1 毫秒。 高延迟会导致系统性能直线下降,不适合高可用性系统。 因此,如果相距较远,则不适用 Artifactory HA 高可用性制品仓库。 要在地理位置较为分散的系统中实现负载平衡和故障转移,可以采用其他技术,本文对此不作详述。高可用性系统
对组织至关重要的系统可以采用高可用性配置进行部署,以提高稳定性和可靠性。 要实现高可用性,您可以同步系统中的节点并将它们作为冗余集群进行部署,从而避免完全依赖任何单个节点。 在高可用性配置中,不会出现单点故障。 任何节点出现故障时,系统将通过其余的冗余节点以无缝且透明的方式继续运行,而不会停机或降低整体系统性能。
了解更多 >
使用 JFrog Mission Control 建立同步关系
在不同的 Artifactory 实例之间建立同步关系的最简单、最有效的方法是使用 JFrog Mission Control。 Mission Control 支持对任意数量的 Artifactory 实例进行集中控制,使企业能够通过单个应用程序监控和管理全球分布的 Artifactory 实例。 就此方面,它允许企业使用来自单个命令和控制中心的简单 DSL 脚本创建同步关系,而无需在每个实例中单独创建和配置仓库并逐个进行同步。 要配置同步,可以在多个实例中创建新仓库并配置它们之间的同步关系(一对一或一对多),或者更新现有仓库并对其应用同步 DSL 脚本。 创建和配置多站点开发拓扑后,Mission Control 会显示一张地图,图中显示拓扑内的 Artifactory 服务器网络及其同步关系。同步类型比较
下表总结了不同同步选项和不同触发方法的区别:推送同步 | 拉取同步 |
网络拓扑——源仓库向目标仓库发起网络通信。 | 网络拓扑——目标仓库向源仓库发起网络通信。 (如果是基于事件的拉取,则需要双向通信) |
使用源仓库上的同步配置。 集中控制。 | 使用远程仓库上的同步配置。 分布式控制。 (也可以通过 JFrog Mission Control 进行集中控制) |
对于同步的制品,在目标仓库上建立索引,使仓库在本地保持一致。 | 索引基于源仓库,但在离线场景中可能不会在本地保持一致。 |
制品立即可用,即使同步尚未完成也是如此。 | |
不在远程仓库上重新计算索引,从而减少计算开销。 |
基于事件的同步 | 定期 (Cron) 同步 | 按需代理 |
极短时间内即可达到全局一致。 最大限度地减少仓库处于未同步状态的时间。 | 同步流量可安排在低流量时段。 | 只同步(以及缓存)在远端解析的制品。 |
同步流量分散。 没有“大宗工作”。 | 在漏掉事件或出错时仍能保证完全同步。 | 仅按需获取和存储制品,从而减少网络流量。 |
实现平滑的基于地理位置的故障转移和灾难恢复。 | 按需缓存,从而减少远程站点的存储。 | |
只能通过远程仓库进行代理。 |
实现多站点开发拓扑的不同方法
下文以一个拥有四个数据中心的组织为例进行说明。 这四个数据中心分别位于阿姆斯特丹、曼谷、开普敦和丹佛。星型拓扑
如果开发工作主要集中在一个站点(例如在阿姆斯特丹),但是又需要将额外的开发托管到多个远程站点(曼谷、开普敦和丹佛),则建议采用星型拓扑。 这种情况下,推送同步和拉取同步都适用,并且各具优势。
基于事件的多通道推送同步阿姆斯特丹站点向曼谷、开普敦和丹佛站点推送。 (注意: 所有站点都必须具有企业版许可证) |
拉取同步曼谷、开普敦和丹佛站点 从阿姆斯特丹站点拉取同步。 |
使用基于事件的拉取同步的星型拓扑:


使用基于事件的多通道推送同步的星型拓扑:

全网状拓扑
如果开发工作比较均匀地分布在不同的站点,建议采用全网状拓扑。但是,这个术语其实不够恰当。 真正的全网状拓扑意味着每一方都实现完整的双向同步(无论是采用推送方式还是拉取方式),但这通常不是最佳实践。 我们建议采用的这种拓扑其实是星型拓扑,但是它按项目实现,而不是把所有内容都集中起来。 如下文所述,有不同的方法可以做到这一点。在两个站点之间推送的单个本地仓库
如果在多个站点开发模块,那么每个站点可以将这些模块部署到本地仓库,然后这些站点通过基于事件的推送或拉取同步实现彼此之间的同步。
由本地和远程仓库组成的单个虚拟仓库
实现全网状拓扑的更好方法是让每个站点管理一个本地仓库和一个远程仓库。 每个站点只能对自己的本地仓库执行写入操作,其远程仓库的填充则采用从另一个站点的本地仓库拉取同步的方式。 换句话说,曼谷站点的 Artifactory 将阿姆斯特丹站点本地仓库中的文件拉取同步到曼谷站点对应的远程仓库,反之亦然。 要实现这种模式,可以设置一个默认部署目标作为虚拟仓库,使它指向本地仓库(阿姆斯特丹为“local-amsterdam”,曼谷为“local-bangkok”)进行部署。
由两个本地仓库组成的单个虚拟仓库
实现全网状拓扑的另一种方法是让每个站点管理两个本地仓库。 每个站点只能对自己的一个本地仓库执行写入操作,另一个本地仓库则通过 Artifactory 由远程仓库(即另一个站点的本地仓库)推送同步来填充。 换句话说,Artifactory 从阿姆斯特丹站点的本地仓库向曼谷站点的相应仓库推送同步,反之亦然。 要实现这种模式,可以设置一个默认部署目标作为虚拟仓库,使它指向本地仓库(阿姆斯特丹为“local-amsterdam”,曼谷为“local-bangkok”)进行部署。
由一个本地仓库和多个远程仓库组成的单个虚拟仓库(拉取复制)
企业用户可以通过让每个站点管理一个本地仓库和多个远程仓库(代表其他站点的本地仓库)来实现全网状拓扑。 配置如下: 每个站点只能对自己的本地仓库执行写入操作,其远程仓库的填充则采用从其他站点的本地仓库拉取同步的方式。 在下面的示意图中: 曼谷、开普敦和丹佛的 Artifactory 实例中的本地仓库内的文件被拉取同步到阿姆斯特丹的相应远程仓库。 阿姆斯特丹、开普敦和丹佛的本地仓库内的文件被拉取同步到曼谷的相应远程仓库。 阿姆斯特丹、曼谷和丹佛的本地仓库内的文件被拉取同步到开普敦的相应远程仓库。 阿姆斯特丹、曼谷和开普敦的本地仓库内的文件被拉取同步到丹佛的相应远程仓库。 在这种环境中,可靠的命名约定至关重要,原因有两个: 首先,这样可以减少混乱,其次,如果单个节点出现故障,可以更轻松地进行灾难恢复。 我们建议,每个站点为本地节点采用类似如下的命名:“libs-release-amsterdam”、“libs-release-bangkok”、“libs-release-cape-town”和“libs-release-denver”,并且所有站点为远程节点采用类似如下的命名:“libs-release-amsterdam-remote”、“libs-release-bangkok-remote”、“libs-release-cape-town-remote”和“libs-release-denver-remote”。 阿姆斯特丹 CI 环境仅可对“libs-release-amsterdam”执行写入操作,曼谷 CI 环境仅可对“libs-release-bangkok”执行写入操作,以此类推。如果阿姆斯特丹的 Artifactory 发生故障,按照阿姆斯特丹 CI 环境的设计,网状拓扑中的任何其他 Artifactory 都可以代其提供服务,而且只需极少的重新配置。 在下图中我们可以看到一个全网状拓扑,其中的每个站点的本地仓库都被其他站点的相应远程缓存拉取同步。由多个本地仓库组成的单个虚拟仓库(多通道推送同步)
企业用户可以通过让每个站点管理多个本地仓库来实现全网状拓扑。 每个站点只能对自己的一个本地仓库执行写入操作,其他本地仓库则通过 Artifactory 由远程仓库(即另一个站点的本地仓库)推动同步来填充。 换句话说,Artifactory 以多通道推送同步的方式从阿姆斯特丹的本地仓库向曼谷、开普敦和丹佛的相应仓库同步;曼谷的 Artifactory 以多通道推送同步的方式向阿姆斯特丹、开普敦和丹佛同步;开普敦的 Artifactory 以多通道推送同步的方式向阿姆斯特丹、曼谷和丹佛同步;而丹佛的 Artifactory 以多通道推送同步的方式向阿姆斯特丹、曼谷和开普敦同步。 同样,可靠的命名约定在这种环境中也至关重要,原因有两个: 首先,这样可以减少混乱,其次,如果单个节点出现故障,可以更轻松地进行灾难恢复。 我们建议,所有站点为其节点采用类似如下的命名:“libs-release-amsterdam”、“libs-release-bangkok”、“libs-release-cape-town”和“libs-release-denver”。 在这个架构中,Artifactory 将所有仓库视为本地仓库,即使其中一些实际上是远程仓库的同步副本。 阿姆斯特丹 CI 环境仅可对“libs-release-amsterdam”执行写入操作,曼谷 CI 环境仅可对“libs-release-bangkok”执行写入操作,以此类推。所有 CI 环境应将由其他环境推送同步给它们的仓库视作只读仓库,并且它们的用户帐户不应该有写访问权限,以防止出现与同步有关的问题。 这也意味着,如果阿姆斯特丹的 Artifactory 发生故障,按照阿姆斯特丹 CI 环境的设计,网状拓扑中的任何其他 Artifactory 都可以代其提供服务,而且只需极少的重新配置。 在下图中我们可以看到一个全网状拓扑,其中阿姆斯特丹的一个实例向曼谷、开普敦和丹佛的相应仓库同步“local-amsterdam”仓库。 以同样的方式,曼谷、开普敦和丹佛的实例分别向所有其他实例中的相应仓库同步其各自的本地仓库。下图展示了 JFrog Mission Control 中的全网状拓扑界面。下载
您可以通过 GitHub 上的 JFrog Mission Control 配置脚本下载可重用的配置脚本,用以实现本白皮书中介绍的所有拓扑。
使用基于事件的拉取同步的全网状拓扑:
使用基于事件的多通道推送同步的全网状拓扑:
同步制品的单个本地站点
这是最保守的配置,而且如果您不想拥有冗余 CI 服务器,即在只有一个站点实际构建用于分发的制品的情况下,这也是最有效的配置。地理同步拓扑
全网状拓扑的另一种扩展是地理同步拓扑。 这种拓扑中,若干个 Artifactory 实例连接一个地理位置路由。 使用基于事件的推送或拉取同步,我们可以在不同的地理位置拥有多个实例,为不同的全球团队提供服务,而且所有变更都会被即时同步,所以每个实例所包含的制品在任何时间都相同。 这个用例的预期结果是连接路由服务器的所有实例中的配置(仓库名称、用户、组、许可目标等)都完全相同,以便用户使用相同的仓库部署和解析制品,而无需根据他们连接的服务器更改构建工具中的配置(这个用例适用于 DR 模式以及将多个位置的负载划分到不同实例的情形)。 从最终用户的角度来看,无论是交互式服务器还是构建服务器,一切工作都在幕后完成,用户只需通过单个 URL 连接到 Artifactory。 如果没有 Mission Control,这种拓扑结构可能会很繁琐。 借助 Mission Control,您可以使用 DSL 脚本将相同的配置应用到多个实例,或者从一个实例导入配置并将其应用到其他实例。 然后,您便可以轻松地在所有实例之间创建如前所述的事件推送或拉取同步。推荐配置
下表根据不同的设置和您可能需要解决的其他限制提供了配置建议。设置/目标 建议 | |
一个中央 CI 服务器 您在构建制品的中央位置只有一个 CI 服务器,并且您希望将制品同步到卫星站点。 | 使用星型拓扑。 多通道推送同步或者拉取同步的选择取决于您有无企业版许可证以及您重点关注哪些优势。 |
多个 CI 服务器 您有若干个站点,并且每个站点都有自己的 CI 服务器。 每个站点需要构建所有其他站点所需的所有制品的子集。 | 使用全网状拓扑并采用基于事件的拉取同步,以便所有数据甚至早在同步完成之前就可用。 如果网络拓扑需要,也可以实现基于事件的推送同步。 |
在带宽有限的情况下进行同步 您的站点是一个没有 CI 服务器的卫星站点。 您需要从主站点同步仓库,但带宽有限。 | 在流量较低时调用拉取同步。 |
在数据传输有限的情况下进行同步 您需要同步仓库,但希望限制传输的数据量。 | 使用按需代理。定义远程仓库,用以代理您需要同步的远端的仓库。 建议不要启用同步删除。 |
在数据存储有限的情况下进行同步 您希望同步另一个站点的仓库,但是您还希望限制存储在您的站点的数据量。 | 使用按需代理。定义远程仓库,用以代理您需要同步的远端的仓库。 此外,您应该让 Artifactory 清理不再使用的制品。 最好的办法是将 Unused Artifacts Cleanup Period 字段设置为非零值,用以修改和控制缓存消耗的存储量。
|