查看运行状况服务故障

适用于:Azure Stack HCI 版本 22H2、Windows Server 2022、Windows Server 2019

本文提供有关 Azure Stack HCI 和 Windows Server 中健康服务故障的详细信息。

关于健康服务故障

运行状况服务持续监视存储空间直通群集,以检测问题并生成“故障”。cmdlet 显示任何当前故障,让你能够轻松验证部署的运行状况,而无需逐一查看每个实体或功能。 故障的描述非常精确、易于理解,且可操作。

每个故障包含五个重要的字段:

  • 严重性
  • 问题的描述
  • 用于解决问题的建议后续步骤
  • 故障实体的标识信息
  • 其物理位置(如果适用)

例如,以下是一个典型的故障:

Severity: MINOR
Reason: Connectivity has been lost to the physical disk.
Recommendation: Check that the physical disk is working and properly connected.
Part: Manufacturer Contoso, Model XYZ9000, Serial 123456789
Location: Seattle DC, Rack B07, Node 4, Slot 11

注意

物理位置源自故障域配置。 有关容错域的详细信息,请参阅容错域感知。 如果未提供此信息,则位置字段的帮助较小。 例如,它可能只显示插槽编号。

有关故障的参考信息,请参阅健康服务故障参考

根本原因分析

运行状况服务可以评估故障实体之间的潜在因果关系以标识和合并由相同根本问题导致的故障。 通过识别作用链,可降低报告的繁琐性。 例如,如果服务器关闭,则预计服务器内的任何驱动器也将无法连接。 因此,根本原因(本例中为服务器)只引发一个错误。

PowerShell 中的用法

若要在 PowerShell 中查看任何当前故障,请运行以下 cmdlet:

Get-HealthFault

这会返回任何影响整体存储空间直通群集的故障。 大多数情况下,这些故障与硬件或配置相关。 如果没有故障,cmdlet 将不返回任何内容。

注意

在非生产环境中,你可以自行触发故障来试验此功能,风险由你自己承担。 例如,可以通过删除一个物理磁盘或关闭一个节点来这样做。 故障出现后,重新插入物理磁盘或重启节点,以使故障消失。

.NET 和 C# 中的用法

本部分演示如何连接到运行状况服务、使用发现对象和运行故障查询。

连接

为了查询运行状况服务,你需与群集建立一个 CimSession。 为此,您需要一些只有在完整版 Microsoft .NET 中才有的工具,这意味着您无法直接通过 Web 或移动应用程序来实施这一操作。 本部分中的代码示例使用 C#,这是此数据访问层的最直接的选择。

using System.Security;
using Microsoft.Management.Infrastructure;

public CimSession Connect(string Domain = "...", string Computer = "...", string Username = "...", string Password = "...")
{
    SecureString PasswordSecureString = new SecureString();
    foreach (char c in Password)
    {
        PasswordSecureString.AppendChar(c);
    }

    CimCredential Credentials = new CimCredential(
        PasswordAuthenticationMechanism.Default, Domain, Username, PasswordSecureString);
    WSManSessionOptions SessionOptions = new WSManSessionOptions();
    SessionOptions.AddDestinationCredentials(Credentials);
    Session = CimSession.Create(Computer, SessionOptions);
    return Session;
}

提供的用户名应为目标计算机的本地管理员。

建议直接根据用户输入实时构造 Password SecureString,这样密码就永远不会以明文方式存储在内存中。 这有助于缓解各种安全问题。 但在实践中,按如上所述构造它对于原型制作来说很常见。

发现对象

建立 CimSession 后,可查询群集上的 Windows Management Instrumentation (WMI)。

在获取故障或指标之前,需要获取多个相关对象的实例。 首先,获取表示群集上的存储空间直通的 MSFT_StorageSubSystem。 使用它可以获取群集中的每个 MSFT_StorageNode 和数据卷的每个 MSFT_Volume。 最后,需要获取 MSCluster_ClusterHealthService,即运行状况服务本身。

CimInstance Cluster;
List<CimInstance> Nodes;
List<CimInstance> Volumes;
CimInstance HealthService;

public void DiscoverObjects(CimSession Session)
{
    // Get MSFT_StorageSubSystem for Storage Spaces Direct
    Cluster = Session.QueryInstances(@"root\microsoft\windows\storage", "WQL", "SELECT * FROM MSFT_StorageSubSystem")
        .First(Instance => (Instance.CimInstanceProperties["FriendlyName"].Value.ToString()).Contains("Cluster"));

    // Get MSFT_StorageNode for each cluster node
    Nodes = Session.EnumerateAssociatedInstances(Cluster.CimSystemProperties.Namespace,
        Cluster, "MSFT_StorageSubSystemToStorageNode", null, "StorageSubSystem", "StorageNode").ToList();

    // Get MSFT_Volumes for each data volume
    Volumes = Session.EnumerateAssociatedInstances(Cluster.CimSystemProperties.Namespace,
        Cluster, "MSFT_StorageSubSystemToVolume", null, "StorageSubSystem", "Volume").ToList();

    // Get MSFT_StorageHealth itself
    HealthService = Session.EnumerateAssociatedInstances(Cluster.CimSystemProperties.Namespace,
        Cluster, "MSFT_StorageSubSystemToStorageHealth", null, "StorageSubSystem", "StorageHealth").First();
}

这些是你在 PowerShell 中使用 cmdlet(如 Get-StorageSubSystem、Get-StorageNode 和 Get-Volume)得到的相同对象。

你可以访问记录在存储管理 API 类中的所有相同属性。

using System.Diagnostics;

foreach (CimInstance Node in Nodes)
{
    // For illustration, write each node's Name to the console. You could also write State (up/down), or anything else!
    Debug.WriteLine("Discovered Node " + Node.CimInstanceProperties["Name"].Value.ToString());
}

查询故障

调用 Diagnose 可获取范围为目标 CimInstance(可以是群集或任何卷)的任何当前故障。

public void GetFaults(CimSession Session, CimInstance Target)
{
    // Set Parameters (None)
    CimMethodParametersCollection FaultsParams = new CimMethodParametersCollection();
    // Invoke API
    CimMethodResult Result = Session.InvokeMethod(Target, "Diagnose", FaultsParams);
    IEnumerable<CimInstance> DiagnoseResults = (IEnumerable<CimInstance>)Result.OutParameters["DiagnoseResults"].Value;
    // Unpack
    if (DiagnoseResults != null)
    {
        foreach (CimInstance DiagnoseResult in DiagnoseResults)
        {
            // TODO: Whatever you want!
        }
    }
}

可选:MyFault 类

构造并保留自己的故障表示形式可能是有意义的。 例如,MyFault 类存储多个故障的关键属性(包括 FaultId),稍后可以使用这些属性来关联更新、删除通知或在多次检测到同一故障时删除重复故障。

public class MyFault {
    public String FaultId { get; set; }
    public String Reason { get; set; }
    public String Severity { get; set; }
    public String Description { get; set; }
    public String Location { get; set; }

    // Constructor
    public MyFault(CimInstance DiagnoseResult)
    {
        CimKeyedCollection<CimProperty> Properties = DiagnoseResult.CimInstanceProperties;
        FaultId     = Properties["FaultId"                  ].Value.ToString();
        Reason      = Properties["Reason"                   ].Value.ToString();
        Severity    = Properties["PerceivedSeverity"        ].Value.ToString();
        Description = Properties["FaultingObjectDescription"].Value.ToString();
        Location    = Properties["FaultingObjectLocation"   ].Value.ToString();
    }
}
List<MyFault> Faults = new List<MyFault>;

foreach (CimInstance DiagnoseResult in DiagnoseResults)
{
    Faults.Add(new Fault(DiagnoseResult));
}

每个故障 (DiagnoseResult) 中属性的完整列表记录在稍后的故障属性部分。

故障事件

创建、删除或更新故障时,运行状况服务会生成 WMI 事件。 这些对于保持应用程序状态同步而不需要频繁轮询至关重要,并且可以帮助确定何时发送电子邮件警报等。 为了订阅这些事件,下面的示例代码使用观察程序设计模式。

首先,订阅 MSFT_StorageFaultEvent 事件。

public void ListenForFaultEvents()
{
    IObservable<CimSubscriptionResult> Events = Session.SubscribeAsync(
        @"root\microsoft\windows\storage", "WQL", "SELECT * FROM MSFT_StorageFaultEvent");
    // Subscribe the Observer
    FaultsObserver<CimSubscriptionResult> Observer = new FaultsObserver<CimSubscriptionResult>(this);
    IDisposable Disposeable = Events.Subscribe(Observer);
}

接下来,实现其 OnNext() 方法在每次生成新事件时被调用的观察程序。

每个事件都包含 ChangeType(用于指示是创建、删除还是更新了故障),以及相关的 FaultId。

此外,每个事件都包含故障本身的所有属性。

class FaultsObserver : IObserver
{
    public void OnNext(T Event)
    {
        // Cast
        CimSubscriptionResult SubscriptionResult = Event as CimSubscriptionResult;

        if (SubscriptionResult != null)
        {
            // Unpack
            CimKeyedCollection<CimProperty> Properties = SubscriptionResult.Instance.CimInstanceProperties;
            String ChangeType = Properties["ChangeType"].Value.ToString();
            String FaultId = Properties["FaultId"].Value.ToString();

            // Create
            if (ChangeType == "0")
            {
                Fault MyNewFault = new MyFault(SubscriptionResult.Instance);
                // TODO: Whatever you want!
            }
            // Remove
            if (ChangeType == "1")
            {
                // TODO: Use FaultId to find and delete whatever representation you have...
            }
            // Update
            if (ChangeType == "2")
            {
                // TODO: Use FaultId to find and modify whatever representation you have...
            }
        }
    }
    public void OnError(Exception e)
    {
        // Handle Exceptions
    }
    public void OnCompleted()
    {
        // Nothing
    }
}

了解故障生命周期

故障不应标记为“已发现”或由用户解决。 故障是在运行状况服务发现问题时创建的,并且只有在运行状况服务不再观察到该问题时才会自动被删除。 一般情况下,这反映了问题已得到解决。

但是,在某些情况下(如在故障转移之后、连接时好时坏等),运行状况服务可能会重新发现故障。 因此,保留自己的故障表示形式可能有意义,以便可以轻松删除重复故障。 在发送电子邮件警报或等效项时,这一点尤其重要。

故障属性

下表显示了故障对象的多个关键属性。 对于完整的架构,请检查 storagewmi.mof 中的 MSFT_StorageDiagnoseResult 类。

属性 示例
故障标识 {12345-12345-12345-12345-12345}
故障类型 Microsoft.Health.故障类型.容量
原因 “卷的可用空间不足。”
感知严重性 5
故障对象描述 Contoso XYZ9000 序列号 123456789
故障对象位置 机架 A06,RU 25,插槽 11
推荐操作 {“扩展卷。”,“将工作负载迁移到其他卷。”}

FaultId:一个群集范围内的唯一 ID。

PerceivedSeverity:PerceivedSeverity = { 4, 5, 6 } = {“信息”,“警告”和“错误”},或等效颜色(如蓝色、黄色和红色)。

FaultingObjectDescription:硬件的部分信息,通常软件对象为空白。

FaultingObjectLocation:硬件的位置信息,通常软件对象为空白。

RecommendedActions:独立且无特定顺序的建议操作列表。 目前,此列表的长度通常为 1。

故障事件属性

下表显示了故障事件的多个关键属性。 对于完整的架构,请检查 storagewmi.mof 中的 MSFT_StorageFaultEvent 类。

记下 ChangeType(指示是创建、删除还是更新了故障)和 FaultId。 事件还包含受影响故障的所有属性。

属性 示例
变更类型 0
故障标识 {12345-12345-12345-12345-12345}
故障类型 Microsoft.Health.故障类型.容量
原因 “卷的可用空间不足。”
感知严重性 5
故障对象描述 Contoso XYZ9000 序列号 123456789
故障对象位置 机架 A06,RU 25,插槽 11
推荐操作 {“扩展卷。”,“将工作负载迁移到其他卷。”}

ChangeType: ChangeType = { 0, 1, 2 } = { “Create”, “Remove”, “Update” }.

健康服务故障参考

Azure Stack HCI 和 Windows Server 中的运行状况服务可以检测各种系统组件(包括存储、网络和计算资源)的故障。

有关健康故障的详细概述,包括故障严重性映射、健康设置(数据类型、故障关联、默认值和说明),以及收集的指标列表,请下载 健康服务故障 电子表格。

健康服务故障注意事项:

  • 默认情况下,某些故障处于禁用状态。 若要启用故障,请将相应的运行状况设置设置为 true。 例如,默认禁用错误类型 Microsoft.Health.FaultType.PhysicalDisk.HighLatency.AverageIO 。 若要启用它,请将运行状况设置 System.Storage.PhysicalDisk.HighLatency.Threshold.Tail.Enabled 设置为 true。

  • 存储机箱组件的运行状况(例如风扇、电源和传感器)派生自 SCSI 机箱服务(SES)。 如果您的供应商未提供此信息,健康服务将无法显示它。

其他参考