Azure 辅助角色中自定义性能计数器中的随机高数
Random high number in Custom Performance Counter in Azure Worker Role
我从 Azure 辅助角色创建和更新自定义性能计数器时遇到一个奇怪的问题,以跟踪与我的 SOAP WCF 服务的打开连接数。
在 RoleEntryPoint.Run()
方法中,我确保创建了计数器:
if (PerformanceCounterCategory.Exists("WorkerRoleEndpointConnections"))
return true;
var soapCounter = new CounterCreationData
{
CounterName = "# SOAP Connections",
CounterHelp = "Current number of open SOAP connections",
CounterType = PerformanceCounterType.NumberOfItems32
};
counters.Add(soapCounter);
PerformanceCounterCategory.Create("WorkerRoleEndpointConnections", "Connection statistics for endpoint types", PerformanceCounterCategoryType.MultiInstance, counters);
这似乎可以正常工作,因为计数器是在角色启动时正确创建的。我已经通过 RDP > Perfmon 进行了检查。
在计数器 checked/created 之后,我然后使用 PerformanceCounter
对象创建对计数器的单个引用:
m_SoapConnectionCounter = new PerformanceCounter
{
CategoryName = "WorkerRoleEndpointConnections",
CounterName = "# SOAP Connections",
MachineName = ".",
InstanceName = RoleEnvironment.CurrentRoleInstance.Id,
ReadOnly = false,
RawValue = 0L // Initialisation value added in an attempt to fix issue
};
然后我会在需要时更新:
public async Task UpdateSoapConnectionCounter(int connections)
{
await UpdateCounter(m_SoapConnectionCounter, connections);
}
private async Task UpdateCounter(PerformanceCounter counter, int connections)
{
await Task.Run(() =>
{
counter.RawValue = connections; // Implicit cast to long
});
}
我的想法是在需要时以即发即弃的方式简单地覆盖该值。
问题是这似乎只偶尔有效。计数器会随机显示一些比 int.MaxValue
略大的大值,例如21474836353
。奇怪的是,一旦发生这种情况,它就永远不会 returns 到 "normal" 值。
我试过删除计数器,但即使它们是新创建的,它们似乎也采用这个值(有时从一开始就开始),即使在创建 PerformanceCounter
对象时添加了零的初始化值.
我有点不知道问题出在哪里。起初我认为这只是最初创建计数器时的一个问题,但我现在也观察到计数器更改为这些值 - 即 0、1、2、1、21474836350
我只找到了 one post which indicates a similar issue,但唯一的建议是确保它已初始化,因为他们将问题归结为 "uninitialized block of memory that is used to store the performance counter variable" - 但我尝试这样做但没有成功。
请注意,我认为这不是 perfmon 问题,因为我是通过 perfmon 看到的,而且我使用 Azure Diagnostics 导出了计数器,两者都显示了值。
有人有什么想法吗?
好的,经过多次调试后发现问题是因为我有时为计数器分配负数。
似乎将 RawValue
属性 设置为负数会导致某种位掩码,因此它实际上分配了一个等于 int.MaxValue -(负值)的值。
我从 Azure 辅助角色创建和更新自定义性能计数器时遇到一个奇怪的问题,以跟踪与我的 SOAP WCF 服务的打开连接数。
在 RoleEntryPoint.Run()
方法中,我确保创建了计数器:
if (PerformanceCounterCategory.Exists("WorkerRoleEndpointConnections"))
return true;
var soapCounter = new CounterCreationData
{
CounterName = "# SOAP Connections",
CounterHelp = "Current number of open SOAP connections",
CounterType = PerformanceCounterType.NumberOfItems32
};
counters.Add(soapCounter);
PerformanceCounterCategory.Create("WorkerRoleEndpointConnections", "Connection statistics for endpoint types", PerformanceCounterCategoryType.MultiInstance, counters);
这似乎可以正常工作,因为计数器是在角色启动时正确创建的。我已经通过 RDP > Perfmon 进行了检查。
在计数器 checked/created 之后,我然后使用 PerformanceCounter
对象创建对计数器的单个引用:
m_SoapConnectionCounter = new PerformanceCounter
{
CategoryName = "WorkerRoleEndpointConnections",
CounterName = "# SOAP Connections",
MachineName = ".",
InstanceName = RoleEnvironment.CurrentRoleInstance.Id,
ReadOnly = false,
RawValue = 0L // Initialisation value added in an attempt to fix issue
};
然后我会在需要时更新:
public async Task UpdateSoapConnectionCounter(int connections)
{
await UpdateCounter(m_SoapConnectionCounter, connections);
}
private async Task UpdateCounter(PerformanceCounter counter, int connections)
{
await Task.Run(() =>
{
counter.RawValue = connections; // Implicit cast to long
});
}
我的想法是在需要时以即发即弃的方式简单地覆盖该值。
问题是这似乎只偶尔有效。计数器会随机显示一些比 int.MaxValue
略大的大值,例如21474836353
。奇怪的是,一旦发生这种情况,它就永远不会 returns 到 "normal" 值。
我试过删除计数器,但即使它们是新创建的,它们似乎也采用这个值(有时从一开始就开始),即使在创建 PerformanceCounter
对象时添加了零的初始化值.
我有点不知道问题出在哪里。起初我认为这只是最初创建计数器时的一个问题,但我现在也观察到计数器更改为这些值 - 即 0、1、2、1、21474836350
我只找到了 one post which indicates a similar issue,但唯一的建议是确保它已初始化,因为他们将问题归结为 "uninitialized block of memory that is used to store the performance counter variable" - 但我尝试这样做但没有成功。
请注意,我认为这不是 perfmon 问题,因为我是通过 perfmon 看到的,而且我使用 Azure Diagnostics 导出了计数器,两者都显示了值。
有人有什么想法吗?
好的,经过多次调试后发现问题是因为我有时为计数器分配负数。
似乎将 RawValue
属性 设置为负数会导致某种位掩码,因此它实际上分配了一个等于 int.MaxValue -(负值)的值。