防止集群上的作业在部署期间在生产代码上运行

问题描述 投票:0回答:1

我有一个脚本,作为生产环境中集群上的作业运行几分钟。有 0 到 100 个这样的作业,每个作业有 1 个脚本,在集群上同时运行。通常,没有作业正在运行,或者突发大约 4-8 个这样的作业。

当我将新版本的代码部署到生产中时,我想阻止此类作业运行。

如何优化可维护性?

我最初的想法是这样的:

  1. 使用在部署开始时创建并在代码部署后删除的信号量文件或锁定文件。部署运行 0.5 - 10 分钟,具体取决于当前部署任务的复杂性。
  2. 如果部署无法删除此文件,例如 30 分钟后,单独的 cron 作业也会自动删除此锁定文件。例如,如果部署被粗鲁地终止,则该文件不应该永远阻塞作业。也就是说,如果文件超过 30 分钟,则该文件将被单独的 cron 作业删除。
  3. 生产代码检查此锁定文件并等待它消失。所以工作等待时间不会超过 30 分钟。

我担心可能的竞争条件,并考虑使用基于数据库的解决方案。就我的应用程序而言,我将使用 postgreSQL。这种基于数据库的解决方案的实施和维护可能更复杂,但对竞争条件的探测可能更少。

也许 Capistrano 中有一个标准机制可以实现此目的,用于部署此代码?

常见问题:

这些作业在部署期间不应该运行有什么特殊原因吗?

我遇到过多个作业在部署中期运行并因此失败的情况。查找并重新运行此类失败的作业非常耗时。在部署期间延迟它们只会对性能造成很小且罕见的影响,并且是迄今为止最可接受的解决方案。对于我们的系统,可维护性是第一位的。

ruby-on-rails postgresql deployment cluster-computing capistrano
1个回答
0
投票

正如我在评论中所述,此功能可以集成为功能标志。非常流行的 Rails 解决方案是 gem flipper

您的工作的伪代码看起来像(虽然我不知道您的工作代码)

class ProcessingJob < ApplicationJob
  queue_as :default

  def perform
    return unless Flipper.enabled?(:jobs_processing)

    ... job's code
  end
end

Flipper 具有用于启用/禁用功能标志的管理 UI。因此,例如,您可以创建功能

jobs_processing
,启用它,然后在部署之前的某个时刻可以将其关闭。

虽然在部署期间禁用功能标志,您将确保不会执行任何作业。部署后您可以再次启用它。

您可能认为 Flipper 对于您的功能来说是复杂的解决方案,因此您可以在没有 gem 的情况下做一些更简单的事情,只需在数据库中创建表,使用启用/禁用功能更新您的管理页面。

class CreateFeatureFlags < ActiveRecord::Migration[7.1]
  def change
    create_table :feature_flags do |t|
      t.string :name, null: false, index: { unique: true }
      t.timestamps
    end
  end
end

class FeatureFlag < ApplicationRecord
  def self.enabled?(name)
    where(name: name).exists?
  end
end

FeatureFlag.enabled?('jobs_processing')
© www.soinside.com 2019 - 2024. All rights reserved.