2

我正在执行的脚本片段:

 $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是 class 的一个实例ManagementGroup

$starttime15 分钟到 1 小时的差异$endtime取决于同一脚本的最后一次执行。

该片段长时间成功收集数据的性能。但随后,它突然抛出以下错误:

“请求的阅读器无效。阅读器不存在或已过期”

[ 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 )
  • 上述错误的原因是什么。?
  • 如果能了解 PerformanceDataReader 的机制就好了。

笔记:

  • 它在出错之前获取的数据量是 100k+。获取这些数据花了将近一个小时。
  • 我认为可能的问题是它必须获取的数据量,它可能是一种 TimoutException。
  • 如果我对上面提到的两个问题至少有一些了解,那就太好了。

谢谢。

4

2 回答 2

2

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

一点背景:

  1. SCOM 有两个数据库。Operational 保存所有当前状态,包括几乎“实时”的性能数据。Data Warehouse DB 保存历史数据,包括汇总(每小时和每天)的性能数据。以下所有查询均针对 Operational DB。
  2. SCOM 作为一个平台可以监控任何东西——它在管理包中实现,因此每个 MP 可以引入新的受监控实体类(类型)和/或现有类的新性能计数器。比如说,您可以为 SAN 设备创建 MP 并开始收集其性能数据。或者您可以创建另一个 MP,它将“文件数”计数器添加到“Windows 逻辑磁盘”类。

牢记以上几点,以下查询是针对“Windows 计算机”类(因此如果您监视 Unix 服务器将不起作用,您需要更改类)和所有相关对象。

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

注意!:结果可能会有所不同,具体取决于您 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 天的“实时”性能,然后将其聚合并卸载到数据仓库。

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

希望有帮助。

干杯马克斯

于 2018-05-08T23:37:19.957 回答
0

true如果阅读器移动到下一个结果,阅读器调用将返回,否则返回false;根据方法的文档。如果您遇到异常,则无法执行其中任何一项。我假设有什么东西破坏了你和 SCCM 实例之间的联系。

如果是超时问题,我不确定这是 SCCM 超时。该错误没有说明超时。据我所知,这是一个底层的 RPC 调用,并且RPC 没有超时

客户端挂起的方式有两种:网络连接可能导致服务器请求丢失,或者服务器本身可能崩溃。使用默认选项,RPC 将永远不会使调用超时,并且您的客户端线程将永远等待响应。

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

如果您想调入您的性能,请考虑缓存. 看起来你有一个比我们看到的片段大得多的脚本。把它扔掉只是为了让你意识到它是一种选择。

于 2018-05-07T14:29:42.377 回答