簡體   English   中英

ServiceFabric 無狀態 WebApi 自動重試 503 和 404 響應

[英]ServiceFabric stateless WebApi automatically retries 503 and 404 responses

我們有一個構建在 do.net5 之上的 ServiceFabric 無狀態 WebAPI 前端。 我已經為它實現了以下異常處理過濾器:

    public class OrderServiceRetryFilter : IExceptionFilter
    {
        public void OnException(ExceptionContext context)
        {
            var exc = context.Exception;
            if (exc is AggregateException ae && (
                ae.InnerException is OrdersNotFetchedException onfe))
            {
                context.HttpContext.Response.Headers.Add("Retry-After", "2");
                var result = new ObjectResult(onfe.Message) { StatusCode = 591 };
                context.Result = result;
                context.ExceptionHandled = true;
            }
            if (exc is AggregateException ate && (
                ate.InnerException is System.TimeoutException toex))
            {
                context.HttpContext.Response.Headers.Add("Retry-After", "1");
                var result = new ObjectResult(toex.Message) { StatusCode = 504 };
                context.Result = result;
                context.ExceptionHandled = true;
            }
            if (exc is AggregateException anfe && (
                anfe.InnerException is OrderNotFoundException onf))
            {
                var result = new NotFoundObjectResult(onf.Message);
                context.Result = result;
                context.ExceptionHandled = true;
            }
        }
    }

如果有狀態后端服務拋出異常,此過濾器將找到內部異常並為 HTTP 查詢返回正確的狀態代碼(591、504、404)。

現在,如果后端服務拋出OrdersNotFetchedException ,狀態代碼將設置為 591,客戶端將獲取它。 我正在使用我們自己的 591,因為返回 503 會導致重試呼叫。 這種重試也發生在 404 的情況下。如果我進行 GET 調用,將導致 404,從 Postman,它最終將超時。 調試代碼顯示代碼不斷返回到返回 404 的OnException方法。如果我在調試期間將錯誤代碼更改為 592,它將將該結果代碼返回給調用客戶端,而無需重試。

某處某處,我認為它是 ServiceFabric,正在重試簡單的 API 調用(如果它返回 503 或 404)。我在哪里可以禁用這種行為,或者我是否正在做一些違反面向公眾的 Web API 使用 ServiceFabric 設計的方式?

這就是我啟動 Kestrel 服務器的方式:

        private IWebHost BuildWebHost(string url, AspNetCoreCommunicationListener listener)
        {
            ServiceEventSource.Current.ServiceMessage(Context, $"Starting Kestrel on {url}");

            var webHost = new WebHostBuilder()
                .UseKestrel()
                .ConfigureServices(
                    services => services
                        .AddSingleton(Context)                     
                        .AddSingleton(ServiceFabricRemoting.CreateServiceProxy<IOrderService>(new Uri($"{ServiceFabricRemoting.GetFabricApplicationName()}/MyApp.OrderService"), new MyLogger(Context), 1))                        
                        
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
                .UseUrls(url)
                .Build();

            HandleWebHostBuilt(webHost);

            return webHost;
        }

根據https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reverseproxy#special-handling-for-port-sharing-services正確答案是添加X-ServiceFabric: ResourceNotFound header為響應繞過404情況下的重試。

所以,在這種情況下:

context.HttpContext.Response.Headers.Add("X-ServiceFabric", "ResourceNotFound");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM