Web App 后台任务的暂存槽处理消息

Posted

技术标签:

【中文标题】Web App 后台任务的暂存槽处理消息【英文标题】:Staging Slot processing messages for Web App background task 【发布时间】:2021-06-22 08:50:33 【问题描述】:

我正在使用 Azure App 服务计划来托管处理服务总线主题消息的 Web 应用程序。 我正在使用 Azure Function App,它也有 http 触发器来执行事件网格数据。 Web 应用(应用服务计划)和函数应用(弹性高级计划)在生产中都有暂存槽。

在交换插槽时,我观察到 Web 应用程序的 stgaing 插槽正在处理消息。这是预期的行为吗? 对于功能应用暂存槽,我没有观察到这种行为。为什么会这样?

【问题讨论】:

您的应用服务是否正在运行网络作业来消费消息? @Juanma Feliu - 不,应用服务正在作为 Web 应用 (REST API) 而不是 Web 作业运行。 @Juanma Feliu - 对不起,我正在使用 IHostedService,所以它将在网络应用程序中作为网络作业运行 用网络作业代码更新了我的答案。希望它可以帮助您适应自己的代码。 代码适用于 webjobs 而不是 IHostedService 但它可以让您了解如何处理它。 【参考方案1】:

在每个名为“IsStaging”的插槽中添加一个应用设置,其值为 true 和 false,然后当应用服务预热时(启动或消耗消息的方法)停止请求,因此不会从 Staging 插槽消耗消息。

                if (CurrentConfiguration.IsStaging)
                
                   logger.LogWarn("Staging slot cannot consume messages");
                   return;
                

WebJob 更新

        static void Main(string[] args)
        
            JobHost host = CreateJobHost();
            if (CurrentConfiguration.IsStaging)
            
                host.Call(typeof(Program).GetMethod("DoStagingInfiniteLoop"));
            
            else
            
                host.Call(typeof(Program).GetMethod("ProcessQueue"));
            
        


        private static JobHost CreateJobHost()
        
            JobHostConfiguration jobHostConfig = new JobHostConfiguration();
            jobHostConfig.DashboardConnectionString = "DashboardCS";
            jobHostConfig.StorageConnectionString = "StorageCS";

            var JobHost = new JobHost(jobHostConfig);
            return JobHost;
        


        [NoAutomaticTrigger]
        public static void DoStagingInfiniteLoop(TextWriter logger, CancellationToken token)
        
            const int LOOP_TRACE_INTERVAL = 10000;
            ProcessLogger.WriteTrace("This is a staging environment, waiting...");
            while (true)
            
                Task.Delay(LOOP_TRACE_INTERVAL).Wait(token);
            
        

        [NoAutomaticTrigger]
        public static void ProcessQueue(TextWriter logger, CancellationToken token)
        
            //Your processing code here
        

【讨论】:

【参考方案2】:

请确保您停止该插槽,否则它将处于运行状态(可以接收消息)。如果你不希望它接收信息,你应该停止它。

【讨论】:

Function App 和 Web App 从 staging 切换到 production 时是否会 staging slot 处理数据? @AmitAgrawal 是的,如果您不想让它处理,请停止。 @Bowman Zhu - 我观察到处理只交换我们无法避免的插槽。我们正在部署到 staging 插槽,然后交换到 prod 插槽。在通过暂存槽交换没有处理之后,如果暂存槽正在运行,那么没关系,但我们不想在交换时通过暂存槽处理消息。 为什么在从暂存到生产的交换发生时,在 Web 应用的情况下而不是在功能应用的情况下暂存槽进程数据? @AmitAgrawal 我认为问题在于网络应用程序即使在插槽状态下仍然允许外部请求。但是函数应用中的HttpTrigger在函数应用处于slot状态时会拒绝外部请求。

以上是关于Web App 后台任务的暂存槽处理消息的主要内容,如果未能解决你的问题,请参考以下文章

Web后台任务处理

在 Java Web 应用程序中处理重复性后台任务的策略?

访问 Azure 应用服务暂存槽 URL 时出现 HTTP 错误 401

如何在Android开发中用AsyncTask异步更新UI界面

Win 10 应用开发在App所在的进程中执行后台任务

iOS后台运行任务