gpt4 book ai didi

.net - 仅根据环境拾取服务器上的 Hangfire 任务(交换槽)

转载 作者:行者123 更新时间:2023-12-02 23:10:13 28 4
gpt4 key购买 nike

我们正在使用 Azure 应用服务为网站运行 Hangfire。我们还用了精彩的swapping mechanism 。这意味着我们不是部署到生产环境,而是部署一个槽并在部署完成后交换它。

问题是,交换槽不断地从hangfire中获取作业。

我想确保只有生产槽实际上正在执行hangfire 作业。挑战在于,无论是生产状态还是非生产状态,都无需重新启动应用程序(双向)即可发生。

我可以在 Azure 中设置插槽粘性应用程序设置,以便我可以确定我是否处于生产模式。这只是给我留下了一个关键问题:

如何启用和禁用我的应用在运行时处理作业?

最佳答案

我为此提出了一个解决方案,该解决方案不需要将 Hangfire 服务分开,如已接受的答案中所述。

public class SkipProcessingPreProdFilter: IElectStateFilter
{
private readonly IServiceProvider _serviceProvider;
public SkipProcessingPreProdFilter(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

public void OnStateElection(ElectStateContext context)
{
if(context.CandidateState.Name == EnqueuedState.StateName)
{
//wait for prd server to pickup job, reschedule keep trying
if (!IsPrdServer())
{
context.CandidateState = new ScheduledState(TimeSpan.FromSeconds(5));
}
}
}

private bool IsPrdServer()
{
var config = _serviceProvider.GetService<IConfiguration>();
var isPrd = config.GetSection("APPSERVICE_SLOT")?.Value?
.Equals("prd", StringComparison.OrdinalIgnoreCase);
return isPrd == true;
}
}

在 Startup.Configure 中执行以下操作:

 GlobalJobFilters.Filters.Add(new SkipProcessingPreProdFilter(app.ApplicationServices));

此过滤器在每个作业入队时对其进行检查,并检查服务器是否具有 pre-prd 或 prd 插槽的环境变量。如果不是 prd,它会重新安排作业 5 秒后重试,但下次尝试时(可能)使用新服务器(它会根据您配置的轮询间隔重试)。

此实现有时可能需要重试几次才能最终找到 prd 服务器,特别是如果您具有多个 Web 服务器的水平扩展。如果有人有任何想法可以改进它,我可以将工作引导到具有匹配服务器前缀的其他服务器,请发表评论。

下面是配置了交换槽并使用“横向扩展”配置了 2 个 Web 应用程序实例的 Hangfire 示例。这最终是 4 台服务器。同一实例上的服务器(prd 之前/prd 交换服务器)具有相同的名称前缀,即 LN1SDLWK0006LS。

enter image description here

或者...您可以像评论中提到的那样为每个插槽使用单独的连接字符串。

编辑:我只是再次考虑了一下,如果您为每个插槽执行单独的连接字符串,那么它仍然会在 preprd 挂火中运行应用程序的重复作业的基本列表,这可能会导致许多意想不到的结果。最好是使用 ENV 变量来阻止应用程序启动时挂火和所有基本重复作业的初始化。

关于.net - 仅根据环境拾取服务器上的 Hangfire 任务(交换槽),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51924132/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com