【问题标题】:ServiceFabric stateless WebApi automatically retries 503 and 404 responsesService Fabric 无状态 Web Api 自动重试 503 和 404 响应
【发布时间】:2023-01-30 22:52:33
【问题描述】:

我们有一个构建在 dotnet5 之上的 Service Fabric 无状态 Web API 前端。我已经为它实现了以下异常处理过滤器:

    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 调用,将导致来自 Postman 的 404,它最终将超时。调试代码显示代码不断返回到返回 404 的 OnException 方法。如果我在调试期间将错误代码更改为 592,它将将该结果代码返回给调用客户端,而无需重试。

某个地方,我认为它是 ServiceFabric,如果它返回 503 或 404,它正在重试简单的 API 调用。我在哪里可以禁用这种行为,或者我是否在做一些违反使用 ServiceFabric 设计面向公众的 Web API 的方式的事情?

这就是我启动 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;
        }

【问题讨论】:

    标签: asp.net-core-webapi service-fabric-stateless


    【解决方案1】:

    根据https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reverseproxy#special-handling-for-port-sharing-services,正确答案是将X-ServiceFabric: ResourceNotFound 标头添加到响应中,以绕过 404 情况下的重试。

    所以,在这种情况下:

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

    【讨论】:

      猜你喜欢
      • 2016-08-17
      • 1970-01-01
      • 2016-08-27
      • 2017-12-13
      • 2019-07-24
      • 2017-05-20
      • 2017-06-09
      • 2020-02-20
      • 2017-11-23
      相关资源
      最近更新 更多