【发布时间】: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