Azure Service Fabric Actors - 未处理的异常?

时间:2022-11-05 11:12:16

Right now our ASF cluster is running:

现在我们的ASF集群正在运行:

  • Web API project - stateless and public facing
  • Web API项目 - 无状态和面向公众
  • Actor project - mostly volatile, keeping data in memory, used by certain APIs
  • Actor项目 - 主要是volatile,将数据保存在内存中,由某些API使用

We are trying out Application Insights, and I can setup unhandled error tracking like their docs here have for our Web API project.

我们正在尝试Application Insights,我可以设置未处理的错误跟踪,就像他们的文档对我们的Web API项目一样。

Issue is, I want this for our Actor project as well.

问题是,我希望这也适用于我们的Actor项目。

Is there a global place for catching unhandled errors within an Actor? I know it's new, and maybe that is why I can't find documentation on this.

是否存在捕捉Actor内未处理错误的全局位置?我知道这是新的,也许这就是为什么我找不到这方面的文件。

Right now I'm doing this inside every actor method, but doesn't seem like a great solution:

现在我在每个actor方法中都这样做,但似乎不是一个很好的解决方案:

public async Task DoStuff()
{
    try
    {
        //Do all my stuff
    }
    catch (Exception exc)
    {
        //Send to Windows Event Source
        ActorEventSource.Current.ActorMessage(this, "Unhandled error in {0}: {1}", nameof(DoStuff), exc);

        //Send to Application Insights
        new TelemetryClient().TrackException(exc);

        throw exc;
    }
}

2 个解决方案

#1


5  

You have a few options:

你有几个选择:

  • Actors do have a built-in ETW provider (Microsoft-ServiceFabric-Actors) that has an ActorMethodThrewException event. You can either:

    Actor有一个内置的ETW提供程序(Microsoft-ServiceFabric-Actors),它有一个ActorMethodThrewException事件。你可以:

    • Use an external process to collect ETW events and forward them to Application Insights (e.g. using SLAB or Azure Diagnostics)
    • 使用外部进程收集ETW事件并将其转发到Application Insights(例如,使用SLAB或Azure诊断)
    • Use the EventListener class to listen to the events in-process and forward it to App Insights (slightly less reliable, but simpler)
    • 使用EventListener类来监听进程中的事件并将其转发到App Insights(稍微不那么可靠,但更简单)
  • Use a custom ActorServiceRemotingDispatcher, which is the class responsible for dispatching operations to the actors

    使用自定义ActorServiceRemotingDispatcher,它是负责向actor调度操作的类

    class CustomActorServiceRemotingDispatcher : ActorServiceRemotingDispatcher
    {
        public CustomActorServiceRemotingDispatcher(ActorService actorService) : base(actorService)
        {
        }
    
        public override async Task<byte[]> RequestResponseAsync(IServiceRemotingRequestContext requestContext, ServiceRemotingMessageHeaders messageHeaders,
            byte[] requestBodyBytes)
        {
                try
                {
                    LogServiceMethodStart(...);
    
                    result = await base.RequestResponseAsync(requestContext, messageHeaders, requestBodyBytes).ConfigureAwait(false);
    
                    LogServiceMethodStop(...);
    
                    return result;
                }
                catch (Exception exception)
                {
                    LogServiceMethodException(...);
    
                    throw;
                }
        }
    }
    

    To use this class, you'll need to create a custom ActorService class and override the CreateServiceReplicaListeners method. Note this will override any ActorRemotingProviderAttributes you may be using.

    要使用此类,您需要创建一个自定义的ActorService类并重写CreateServiceReplicaListeners方法。请注意,这将覆盖您可能正在使用的任何ActorRemotingProviderAttributes。

    Side notes:

    附注:

    • You can also use this method to read your own headers (you'll also need a client-side custom IServiceRemotingClientFactory to add them)
    • 您也可以使用此方法来读取您自己的标题(您还需要一个客户端自定义IServiceRemotingClientFactory来添加它们)
    • The same technique can be applied to Reliable Services (using the ServiceRemotingDispatcher class)
    • 相同的技术可以应用于Reliable Services(使用ServiceRemotingDispatcher类)

#2


1  

No, there is no global place to get exceptions thrown from an actor in the actor framework today. The framework itself does catch exception that are thrown from methods that are managed by the actor runtime - these are your actor interface methods (the ones that are callable from ActorProxy), timer callbacks, reminder callbacks, and base actor overrides like OnActivateAsync - but they're not exposed through the actor API.

不,今天没有全球的地方可以从演员框架中的演员抛出异常。框架本身确实捕获了由actor运行时管理的方法引发的异常 - 这些是您的actor接口方法(可从ActorProxy调用的方法),计时器回调,提醒回调和基本actor重写,如OnActivateAsync - 但它们'不会通过actor API公开。

#1


5  

You have a few options:

你有几个选择:

  • Actors do have a built-in ETW provider (Microsoft-ServiceFabric-Actors) that has an ActorMethodThrewException event. You can either:

    Actor有一个内置的ETW提供程序(Microsoft-ServiceFabric-Actors),它有一个ActorMethodThrewException事件。你可以:

    • Use an external process to collect ETW events and forward them to Application Insights (e.g. using SLAB or Azure Diagnostics)
    • 使用外部进程收集ETW事件并将其转发到Application Insights(例如,使用SLAB或Azure诊断)
    • Use the EventListener class to listen to the events in-process and forward it to App Insights (slightly less reliable, but simpler)
    • 使用EventListener类来监听进程中的事件并将其转发到App Insights(稍微不那么可靠,但更简单)
  • Use a custom ActorServiceRemotingDispatcher, which is the class responsible for dispatching operations to the actors

    使用自定义ActorServiceRemotingDispatcher,它是负责向actor调度操作的类

    class CustomActorServiceRemotingDispatcher : ActorServiceRemotingDispatcher
    {
        public CustomActorServiceRemotingDispatcher(ActorService actorService) : base(actorService)
        {
        }
    
        public override async Task<byte[]> RequestResponseAsync(IServiceRemotingRequestContext requestContext, ServiceRemotingMessageHeaders messageHeaders,
            byte[] requestBodyBytes)
        {
                try
                {
                    LogServiceMethodStart(...);
    
                    result = await base.RequestResponseAsync(requestContext, messageHeaders, requestBodyBytes).ConfigureAwait(false);
    
                    LogServiceMethodStop(...);
    
                    return result;
                }
                catch (Exception exception)
                {
                    LogServiceMethodException(...);
    
                    throw;
                }
        }
    }
    

    To use this class, you'll need to create a custom ActorService class and override the CreateServiceReplicaListeners method. Note this will override any ActorRemotingProviderAttributes you may be using.

    要使用此类,您需要创建一个自定义的ActorService类并重写CreateServiceReplicaListeners方法。请注意,这将覆盖您可能正在使用的任何ActorRemotingProviderAttributes。

    Side notes:

    附注:

    • You can also use this method to read your own headers (you'll also need a client-side custom IServiceRemotingClientFactory to add them)
    • 您也可以使用此方法来读取您自己的标题(您还需要一个客户端自定义IServiceRemotingClientFactory来添加它们)
    • The same technique can be applied to Reliable Services (using the ServiceRemotingDispatcher class)
    • 相同的技术可以应用于Reliable Services(使用ServiceRemotingDispatcher类)

#2


1  

No, there is no global place to get exceptions thrown from an actor in the actor framework today. The framework itself does catch exception that are thrown from methods that are managed by the actor runtime - these are your actor interface methods (the ones that are callable from ActorProxy), timer callbacks, reminder callbacks, and base actor overrides like OnActivateAsync - but they're not exposed through the actor API.

不,今天没有全球的地方可以从演员框架中的演员抛出异常。框架本身确实捕获了由actor运行时管理的方法引发的异常 - 这些是您的actor接口方法(可从ActorProxy调用的方法),计时器回调,提醒回调和基本actor重写,如OnActivateAsync - 但它们'不会通过actor API公开。