Azure functions Azure持久功能-诊断故障
我正在测试持久的函数可以如何扇入/扇出,以及如何扩展代码。对于这个例子,我模拟了许多短时间运行的cpu密集型操作 并不是所有的活动都完成了,我不知道为什么或者在哪里查找失败日志 请参阅下面的代码:Azure functions Azure持久功能-诊断故障,azure-functions,azure-durable-functions,Azure Functions,Azure Durable Functions,我正在测试持久的函数可以如何扇入/扇出,以及如何扩展代码。对于这个例子,我模拟了许多短时间运行的cpu密集型操作 并不是所有的活动都完成了,我不知道为什么或者在哪里查找失败日志 请参阅下面的代码: public static class ParallelLoadDurable { [FunctionName("ParallelLoadDurable")] public static async Task<string> RunOrchestra
public static class ParallelLoadDurable
{
[FunctionName("ParallelLoadDurable")]
public static async Task<string> RunOrchestrator(
[OrchestrationTrigger] DurableOrchestrationContext context, ILogger log)
{
DateTime StartTimer = DateTime.Now;
int counter = 0;
var parallelTasks = new List<Task<string>>();
var retryOptions = new RetryOptions(
firstRetryInterval: TimeSpan.FromSeconds(5),
maxNumberOfAttempts: 5);
for (int i = 0; i < 1000; i++)
{
counter += 1;
DurablePassModel DPM = new DurablePassModel()
{
LoopNum = counter,
StartedOn = StartTimer
};
Task<string> task = context.CallActivityWithRetryAsync<string>("ParallelLoadDurable_Hello", retryOptions, DPM);
parallelTasks.Add(task);
}
await Task.WhenAll(parallelTasks);
DateTime CompleteTime = DateTime.Now;
TimeSpan TS = CompleteTime.Subtract(StartTimer);
string ret = $"PROCESS COMPLETED: {counter} times for: {TS.TotalMilliseconds} ms.";
log.LogInformation(ret);
return ret;
}
[FunctionName("ParallelLoadDurable_Hello")]
public static string SayHello([ActivityTrigger] DurablePassModel val, ILogger log)
{
log.LogInformation($"Starting child function num {val.LoopNum.ToString()}.");
DateTime StartTimer = DateTime.Now;
var endTime = DateTime.Now.AddSeconds(10);
while (true)
{
if (DateTime.Now >= endTime)
break;
}
DateTime CompleteTime = DateTime.Now;
TimeSpan TS = CompleteTime.Subtract(val.StartedOn);
TimeSpan TSThis = CompleteTime.Subtract(StartTimer);
string ret = $"Ran this for: {TSThis.TotalSeconds}s - LoopNum: {val.LoopNum} - total time: {TS.TotalSeconds}s.";
log.LogInformation(ret);
return ret;
}
[FunctionName("ParallelLoadDurable_HttpStart")]
public static async Task<HttpResponseMessage> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
[OrchestrationClient]DurableOrchestrationClient starter,
ILogger log)
{
// Function input comes from the request content.
string instanceId = await starter.StartNewAsync("ParallelLoadDurable", null);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
}
public静态类并行加载
{
[函数名(“并行加载”)]
公共静态异步任务RunOrchestrator(
[OrchestrationTrigger]DurableOrchestrationContext上下文,ILogger日志)
{
DateTime StartTimer=DateTime.Now;
int计数器=0;
var parallelstasks=新列表();
var retryOptions=新的retryOptions(
firstRetryInterval:TimeSpan.FromSeconds(5),
最大尝试次数:5次;
对于(int i=0;i<1000;i++)
{
计数器+=1;
DurablePassModel DPM=新的DurablePassModel()
{
LoopNum=计数器,
StartedOn=StartTimer
};
Task Task=context.CallActivityWithRetryAsync(“ParallelLoadDurable\u Hello”,retryOptions,DPM);
parallelstasks.Add(任务);
}
等待任务。WhenAll(并行任务);
DateTime CompleteTime=DateTime.Now;
TimeSpan TS=完成时间减去(起始时间);
string ret=$“进程已完成:{TS.totalmillizes}ms.{counter}次”;
日志、登录信息(ret);
返回ret;
}
[FunctionName(“ParallelLoad\u Hello”)]
公共静态字符串SayHello([ActivityTrigger]DurablePassModel val,ILogger日志)
{
log.LogInformation($“启动子函数num{val.LoopNum.ToString()}”);
DateTime StartTimer=DateTime.Now;
var endTime=DateTime.Now.AddSeconds(10);
while(true)
{
如果(DateTime.Now>=endTime)
打破
}
DateTime CompleteTime=DateTime.Now;
TimeSpan TS=CompleteTime.Subtract(val.StartedOn);
TimeSpan TSThis=CompleteTime.Subtract(起始时间);
string ret=$“为{TSThis.TotalSeconds}s运行此操作-LoopNum:{val.LoopNum}-总时间:{TS.TotalSeconds}s.”;
日志、登录信息(ret);
返回ret;
}
[FunctionName(“ParallelLoad\u HttpStart”)]
公共静态异步任务HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous,“获取”、“发布”)]HttpRequestMessage请求,
[OrchestrationClient]DurableOrchestrationClient启动器,
ILogger日志)
{
//函数输入来自请求内容。
字符串instanceId=await starter.StartNewAsync(“ParallelLoadDurable”,null);
LogInformation($“启动了ID为“{instanceId}”的业务流程”;
返回starter.CreateCheckStatusResponse(请求,实例ID);
}
}
几乎在所有情况下,我都能完成96%的预期活动。这来自历史记录表中的结果,其中EventType=TaskCompleted
此外,在“实例”表中,RuntimeStatus仅保持“正在运行”
在哪里可以找到失败列表
谢谢你的帮助
尼克用
块包围你的代码,然后用Ilogger
记录异常
它可以通过这样的方式实现
try
{
//Do something
}
catch(Exception ex){
log.LogError($"Error in function: {ex.Message}");
}
然后,您可以查看日志中的错误消息,也可以查看应用程序洞察(如果有)。我建议您为Azure功能配置应用程序洞察:
虽然存储数据需要一些成本,但在调查问题时确实会有很大帮助
此外(或当您不需要应用程序洞察时),您可以通过或查询业务流程的状态。当您在本地计算机上运行和调试时,这也非常有效
使用HTTP API,您可以执行以下查询以确定失败的实例:
@functionAppUrl = https://{{appName}}.azurewebsites.net
@code = YOUR_HOST_KEY
@taskHub = YOUR_HUB_NAME (see host.json)
@createdFrom = 2019-02-01T20:00:00Z
GET {{functionAppUrl}}/runtime/webhooks/durabletask/instances
?taskHub={{taskHub}}
&code={{code}}
&createdTimeFrom={{createdFrom}}
&runtimeStatus=Failed
我注意到您在编排代码中使用了DateTime.Now
。建议使用DurableCOrchestrationContext
中的CurrentUtcDateTime
属性,因为编排函数中的行为应该是确定性的。请参见关于编排器代码约束