"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 )
- 上述错误的原因是什么?
- 要是知道PerformanceDataReader的机制就好了
注:
- 它在出错之前获取的数据量为 100k+。获取该数据花了将近一个小时。
- 我认为可能的问题是它必须获取的数据量,它可能是一种 TimoutException。
- 如果我至少对上面提到的两个问题有一些了解就太好了。
谢谢。
如果 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 查询。
一些背景知识:
- SCOM 有两个 DB。 Operational 拥有所有当前状态,包括几乎 "real time" 性能数据。数据仓库数据库保存历史数据,包括聚合(每小时和每天)的性能数据。以下所有查询均针对操作数据库。
- 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 本身。
希望对您有所帮助。
干杯
最大值
我正在执行的脚本片段:
$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 )
- 上述错误的原因是什么?
- 要是知道PerformanceDataReader的机制就好了
注:
- 它在出错之前获取的数据量为 100k+。获取该数据花了将近一个小时。
- 我认为可能的问题是它必须获取的数据量,它可能是一种 TimoutException。
- 如果我至少对上面提到的两个问题有一些了解就太好了。
谢谢。
如果 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 查询。
一些背景知识:
- SCOM 有两个 DB。 Operational 拥有所有当前状态,包括几乎 "real time" 性能数据。数据仓库数据库保存历史数据,包括聚合(每小时和每天)的性能数据。以下所有查询均针对操作数据库。
- 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 本身。
希望对您有所帮助。
干杯 最大值