"The requested reader was not valid. The reader either does not exist or has expired" 在 SCOM 中获取性能数据时出错

"The requested reader was not valid. The reader either does not exist or has expired" Error while fetching Performance data in SCOM

我正在执行的脚本片段:

 $reader = $managementgroupobj.GetMonitoringPerformanceDataReader() 
 while ($reader.Read())    // << Error in this line.
 { 
      $perfData = $reader.GetMonitoringPerformanceData() 
      $valueReader = $perfData.GetValueReader($starttime,$endtime) 
      while ($valueReader.Read()) 
      { 
           $perfValue = $valueReader.GetMonitoringPerformanceDataValue()
      } 
 }

这里,$managementgroupobj是classManagementGroup的实例。

$starttime$endtime 的差异从 15 分钟到 1 小时不等,具体取决于同一脚本的最后一次执行。

该代码段成功收集了长时间的性能数据。但是随后,它无处不在地抛出以下错误:

"The requested reader was not valid. The reader either does not exist or has expired"

[ log_level=WARN pid=2716 ] Execute command 'get-scomallperfdata' failed. The requested reader was not valid. The reader either does not exist or has expired.
at GetSCOMPerformanceData, E:\perf\scom_command_loader.ps1: line 628
at run, E:\perf\scom_command_loader.ps1: line 591
at <ScriptBlock>, E:\perf\scom_command_loader.ps1: line 815
at <ScriptBlock>, <No file>: line 1
at <ScriptBlock>, <No file>: line 46
   at Microsoft.EnterpriseManagement.Common.Internal.ServiceProxy.HandleFault(String methodName, Message message)
   at Microsoft.EnterpriseManagement.Common.Internal.EntityObjectsServiceProxy.GetObjectsFromReader(Guid readerId, Int32 count)
   at Microsoft.EnterpriseManagement.Common.DataReader.Read()
   at CallSite.Target(Closure , CallSite , Object )

注:

谢谢。

如果 reader 移动到下一个结果,reader 调用将 return true,否则 false;根据method's documentation。如果你得到一个例外,它不能做任何一个。我假设有什么东西破坏了你和 SCCM 实例之间的连接。

如果是超时问题,我不确定是不是 SCCM 超时。该错误没有说明超时。据我所知,这是引擎盖下的 RPC 调用,RPC doesn't have a timeout:

There are two ways your client can hang: network connectivity can cause server requests to become lost, or the server itself can crash. With default options, RPC will never time out a call, and your client thread will wait forever for a response.

也许防火墙会在一段时间后关闭您的连接?

如果您想提高性能,请考虑 caching。看起来你有一个比我们看到的片段大得多的脚本。抛出这个只是为了让你知道它是一个选项。

由于最终目标是将所有性能数据卸载到另一个工具,SCOM API 将无法提供足够的性能,因此建议直接 SQL 查询。

一些背景知识:

  1. SCOM 有两个 DB。 Operational 拥有所有当前状态,包括几乎 "real time" 性能数据。数据仓库数据库保存历史数据,包括聚合(每小时和每天)的性能数据。以下所有查询均针对操作数据库。
  2. SCOM 作为一个平台可以监控任何东西 -- 它在管理包中实现,因此每个 MP 都可以引入新的 classes(类型)被监控实体,and/or 现有性能计数器class是的。比如,您可以为 SAN 设备创建一个 MP 并开始收集其性能数据。或者你可以创建另一个 MP,它将添加 "Number of Files" 计数器到 "Windows Logical Disk" class.

记住以上几点,下面的查询是针对 "Windows Computer" class(所以如果你监控 Unix 服务器将不起作用,你需要更改 class ) 和所有关联的对象。

第 1 步:按名称查找 Windows 计算机的所有可用计数器。

注意!:结果可能会有所不同,具体取决于 OS 版本和 SCOM 中安装的 MP。

declare @ServerName as nvarchar(200) = 'server1.domain.local'

select pc.*
  from PerformanceCounterView pc
  join TypedManagedEntity tme on tme.TypedManagedEntityId = pc.ManagedEntityId
  join BaseManagedEntity bme on tme.BaseManagedEntityId = bme.BaseManagedEntityId
  where (bme.TopLevelHostEntityId = (select BaseManagedEntityId from BaseManagedEntity where FullName = 'Microsoft.Windows.Computer:'+@ServerName))
order by ObjectName, CounterName, InstanceName

步骤 2: 重试在步骤 1 中找到的每个计数器的实际性能数据。

@SrcId 参数是来自上一个查询的 PerformanceSourceInternalId 列。

注意!:SCOM 中的所有时间戳均采用 UTC。下面的查询接受本地时间的输入并产生本地时间的输出。

declare @SrcID as int = XXXX
declare @End as datetime =  GETDATE()
declare @Start as datetime = DATEADD(HOUR, -4, @End)

declare @TZOffset as int = DATEDIFF(MINUTE,GETUTCDATE(),GETDATE())

SELECT SampleValue, DATEADD(MINUTE, @TZOffset, TimeSampled) as TS
  FROM PerformanceDataAllView
  where (PerformanceSourceInternalId = @SrcID)
        and (TimeSampled > DATEADD(MINUTE, -@TZOffset, @Start))
        and (TimeSampled < DATEADD(MINUTE, -@TZOffset, @End))

默认情况下,SCOM 仅保留最近 7 天的 "real time" 性能,然后将其聚合并卸载到数据仓库。

不要过于频繁地调用这些查询或使用 "NO LOCK" 语句以避免阻塞 SCOM 本身。

希望对您有所帮助。

干杯 最大值