我有一个脚本,作为生产环境中集群上的作业运行几分钟。有 0 到 100 个这样的作业,每个作业有 1 个脚本,在集群上同时运行。通常,没有作业正在运行,或者突发大约 4-8 个这样的作业。
当我将新版本的代码部署到生产中时,我想阻止此类作业运行。
如何优化可维护性?
我最初的想法是这样的:
我担心可能的竞争条件,并考虑使用基于数据库的解决方案。就我的应用程序而言,我将使用 postgreSQL。这种基于数据库的解决方案的实施和维护可能更复杂,但对竞争条件的探测可能更少。
也许 Capistrano 中有一个标准机制可以实现此目的,用于部署此代码?
常见问题:
这些作业在部署期间不应该运行有什么特殊原因吗?
我遇到过多个作业在部署中期运行并因此失败的情况。查找并重新运行此类失败的作业非常耗时。在部署期间延迟它们只会对性能造成很小且罕见的影响,并且是迄今为止最可接受的解决方案。对于我们的系统,可维护性是第一位的。
正如我在评论中所述,此功能可以集成为功能标志。非常流行的 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')