因此,这是一个相当广泛的问题,但已经用尽了所有想法。
我们目前正在运行2个辅助角色实例,它们执行以下操作:
我们面临的问题是在高峰期我们的CPU明显增加了,但可悲的是从来没有降下来,通常会升至100%并坐在那儿,直到我重新启动实例以将其降下来。我一直在研究线程,尽管仍然看不到原因,但我仍然认为它可能与“while(1)”类型的场景有关。现在让我们进入代码...
在 WorkerRole.cs 中:
class WorkerRole : RoleEntryPoint
{
private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false);
public override void Run()
{
_eventprocessor.Start(instanceId, instanceIndex);//.Wait(-1);
//Wait for shutdown to be called, else the role will recycle
this.runCompleteEvent.WaitOne();
}
}
在 EventProcessor.cs 中:
我将尝试省掉很多果汁,但添加我认为值得的东西。尽可能添加“伪代码”。
public class EventProcessor : IEventProcessor
{
private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false);
public async Task Start(string serviceId, int InstanceIndex)
{
//Setup Topic
//Setup Queue
//Setup EventProcessorHost for receiving events and operations monitoring and start listening
//Receiving cloud to device feedback from service
ReceiveFeedbackAsync();
runCompleteEvent.WaitOne();
}
async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
{
if (messages.Count() > 0)
{
if (!_cancellationSource.IsCancellationRequested)
{
await ProcessEventsBulk(context, messages);
}
}
if (messages.Count() > 0)
{
await context.CheckpointAsync();
}
}
async Task ProcessEventsBulk(PartitionContext context, IEnumerable<EventData> messages)
{
List<Task> TaskList = new List<Task>();
foreach (EventData message in messages)
{
var LastTask = Task.Run(() => GoBoy(context, message));
TaskList.Add(LastTask);
}
await Task.WhenAll(TaskList);
}
async Task GoBoy(PartitionContext context, EventData message)
{
try
{
using (var db = new AppDbContext(_dbContextConnectionString))
{
await ProcessEvent(message, context.Lease.PartitionId, new CoreManagerContainer(db), db);
await db.SaveChangesAsync();
}
}
catch (Exception e)
{
//Do Some stuff...
}
}
private async void ReceiveFeedbackAsync()
{
var feedbackReceiver = serviceClientReceiver.GetFeedbackReceiver();
while (true)
{
try
{
var feedbackBatch = await feedbackReceiver.ReceiveAsync();
if (feedbackBatch == null) continue;
foreach (var records in feedbackBatch.Records)
{
}
await feedbackReceiver.CompleteAsync(feedbackBatch);
}
catch (Exception)
{
Thread.Sleep(30000);
}
}
}
}
如果还有其他任何需要的东西,请不要犹豫。我真的非常感谢您的帮助。
这里显示一旦我重新启动工作程序,CPU下降
Microsoft支持人员协助我进行一些PerfViews和一些ProcDumps。结果是我们应该调查调用中心的线程“https://abcxyz.azure-devices.net:443/ $ iothub/websocket”。这就是为什么我决定添加ReceiveFeedbackAsync()方法的原因,因为我知道该方法依赖于永久连接到我们的集线器来收集反馈。
从我看到的信息来看,我们正在正确地注册EVPH,但也请告知是否有人也想查看该代码。
最佳答案
您是否已遍历代码并确保没有创建不会引发任何异常的无限循环条件,所以Thead.Sleep才能执行。由于您期望在代码中进入休眠状态,因此最好避免使用Exception来触发它。可能在处理每一批反馈后将其编码为“ sleep ”。异常适用于错误处理和特殊情况,无助于控制逻辑流。
关于c# - 高CPU Azure worker 角色,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46360355/