C# 使用路由配置在多租户环境中检查ASP.NET核心运行状况

C# 使用路由配置在多租户环境中检查ASP.NET核心运行状况,c#,asp.net-core,health-monitoring,C#,Asp.net Core,Health Monitoring,我从Asp.net Core开始使用运行状况检查,我喜欢它们,但我找不到一种简单的方法将其与基于租户的路由连接起来,例如支持: /运行状况[通用非租户特定检查] /{tenant}/health[特定于租户的检查] 如果我成功地使用了这种方法,我本可以使用标记来筛选要使用的健康检查,但不幸的是,我没有为请求配置路由 app.UseEndpointRouting(); app.UseHealthChecks("/{tenant}/health", new HealthCheckOptions

我从Asp.net Core开始使用运行状况检查,我喜欢它们,但我找不到一种简单的方法将其与基于租户的路由连接起来,例如支持:

  • /运行状况[通用非租户特定检查]
  • /{tenant}/health[特定于租户的检查]
如果我成功地使用了这种方法,我本可以使用标记来筛选要使用的健康检查,但不幸的是,我没有为请求配置路由

app.UseEndpointRouting();
app.UseHealthChecks("/{tenant}/health", new HealthCheckOptions
    {
        ResponseWriter = WriteCustomHealthResponse,
        AllowCachingResponses = false,
        Predicate = _ => _.Tags.Contains("tenant-specific")
    });
以上代码的路由不正确。 我探讨了使用以下内容的可能性:

app.MapWhen(context => 
    context.Request.Method == HttpMethod.Get.Method &&
    context.Request.?ROUTEDATA?.SOMECHECK("/{tenant}/HealthCheck"),
                builder => builder.UseHealthChecks());

但是在这种情况下,我没有办法检查路由是否正确。

到目前为止,我找到的解决方案是使用查询字符串参数并使用
IHttpContextAccessor
搜索租户参数。 为此,我创建了
IHealthCheck
的基本抽象实现

public abstract class BaseTenantHealthCheck : IHealthCheck
{
    private IHttpContextAccessor _httpContextAccessor;

    public BaseTenantHealthCheck(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    protected string GetTenant()
    {
        return _httpContextAccessor?.HttpContext?.Request?.Query["tenant"].ToString();
    }

    protected bool IsTenantSpecificCheck() => !string.IsNullOrEmpty(GetTenant());

    public abstract Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context,
        CancellationToken cancellationToken = default(CancellationToken));
}
public抽象类BaseTenantHealthCheck:IHealthCheck
{
专用IHttpContextAccessor_httpContextAccessor;
公共基址租户远程检查(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor=httpContextAccessor;
}
受保护字符串GetTenant()
{
返回_httpContextAccessor?.HttpContext?.Request?.Query[“租户”].ToString();
}
受保护的bool IsTenantSpecificCheck()=>!string.IsNullOrEmpty(GetTenant());
公共抽象任务CheckHealthAsync(HealthCheckContext上下文,
CancellationToken CancellationToken=默认值(CancellationToken));
}
然后在实现类中传递如下所示的上下文访问器

public class MylAvailabilityHealthCheck : BaseTenantHealthCheck
{
    public MyAvailabilityHealthCheck(IOptionsMonitor<MyAvailabilityCheckOptions> options, IHttpContextAccessor httpContextAccessor)
    : base(httpContextAccessor)
    {
        [..]
public类MyAvailabilityHealthCheck:BaseTenantHealthCheck
{
公共MyAvailabilityHealthCheck(IOptionsMonitor选项,IHttpContextAccessor httpContextAccessor)
:base(httpContextAccessor)
{
[..]
要访问健康检查,我使用:

  • http://{url}/health
    [用于多租户检查]
  • http://{url}/health?tenant=TenantName
    [用于租户特定的检查]

我期待着听到是否有更优雅的方法来做到这一点。

您为什么需要这样做?健康检查是针对整个应用程序的。我不同意,在我的体系结构中,可用性问题只会影响某些租户,而且我有租户特定的数据库,例如,各种租户驱动的配置、集成ons等。我想检查多租户资源(以及更多资源),但也要检查特定于租户的资源,我不知道这些资源是否存在。也许我正在重载该功能,但这确实让我对系统状态有了很好的了解。你有一篇关于healthchecks的好文章implementations@Norcino-假设Asp.Net Core 3.0(可能需要是3.1)-您可以在运行状况检查中使用端点路由解析路径参数。您需要将HttpContextAccessor注入运行状况检查并从上下文中提取RoutedData对象。
//在运行状况检查中var routedData=_accessor.HttpContext.GetRoutedData();var databaseName=RoutedData.Values[“nameOfPathParameter”].ToString();//Startup.cs-ConfigureServices注册表.AddHealthChecks().AddTypeActivatedCheck(“mssql”,HealthStatus.Degraded”);
其余代码:
app.UseEndpoints(endpoints=>{endpoints.MapController();endpoints.MapHealthChecks(”/api/health check/db/mssql/{nameOfPathParameter}”,新的HealthCheckOptions{Predicate=SqlServerHealthCheckPredicate};});公共静态函数SqlServerHealthCheckPredicate=registration=>registration.Name.Equals(“mssql”,StringComparison.OrdinalIgnoreCase);
谢谢JGx714791,我将尝试您建议的不同映射