Akka.net在Azure WebJob

时间:2018-06-19 10:00:06

标签: azure azure-webjobs akka.net

在工作中,我们在使用Rabbit的Azure WebJob中有一些代码

基本工作流程是

  • 消息到达RabbitMQ队列
  • 我们有传入消息的消息处理程序
  • 在消息处理程序中,我们启动一个顶级(用户)主管演员,我们在那里问"它来处理消息

主管演员层次结构就像这样

enter image description here

相关的顶级代码是这样的(这是WebJob代码)

static void Main(string[] args)
{
    try
    {
        //Bootstrap akka IoC resolver well ahead of any actor usages
        new AutoFacDependencyResolver(ContainerOperations.Instance.Container, ContainerOperations.Instance.Container.Resolve<ActorSystem>());

        var system = ContainerOperations.Instance.Container.Resolve<ActorSystem>();

        var busQueueReader = ContainerOperations.Instance.Container.Resolve<IBusQueueReader>();
        var dateTime = ContainerOperations.Instance.Container.Resolve<IDateTime>();
        busQueueReader.AddHandler<ProgramCalculationMessage>("RabbitQueue", x =>
        {

            //This is code that gets called whenever we have a RabbitMQ message arrive
            //This is code that gets called whenever we have a RabbitMQ message arrive
            //This is code that gets called whenever we have a RabbitMQ message arrive
            //This is code that gets called whenever we have a RabbitMQ message arrive
            //This is code that gets called whenever we have a RabbitMQ message arrive

            try
            {
                //SupervisorActor is a singleton
                var supervisorActor = ContainerOperations.Instance.Container.ResolveNamed<IActorRef>("SupervisorActor");
                var actorMessage = new SomeActorMessage();
                var supervisorRunTask = runModelSupervisorActor.Ask(actorMessage, TimeSpan.FromMinutes(25));

                //we want to wait this guy out
                var supervisorRunResult = supervisorRunTask.GetAwaiter().GetResult();
                switch (supervisorRunResult)
                {
                    case CompletedEvent completed:
                    {
                        break;
                    }
                    case FailedEvent failed:
                    {
                        throw failed.Exception;
                    }

                }
            }
            catch (Exception ex)
            {
                _log.Error(ex, "Error found in Webjob");
                //throw it for the actual RabbitMqQueueReader Handler so message gets NACK
                throw;
            }

        });
        Thread.Sleep(Timeout.Infinite);
    }
    catch (Exception ex)
    {
        _log.Error(ex, "Error found");
        throw;
    }
}

这是相关的IOC代码(我们使用Autofac + Akka.NET DI for Autofac)

builder.RegisterType<SupervisorActor>();

_actorSystem = new Lazy<ActorSystem>(() =>
{
    var akkaconf = ActorUtil.LoadConfig(_akkaConfigPath).WithFallback(ConfigurationFactory.Default());
    return ActorSystem.Create("WebJobSystem", akkaconf);
});

builder.Register<ActorSystem>(cont => _actorSystem.Value);

builder.Register(cont =>
                    {
                        var system = cont.Resolve<ActorSystem>();
                        return system.ActorOf(system.DI().Props<SupervisorActor>(),"SupervisorActor");
                    })
        .SingleInstance()
        .Named<IActorRef>("SupervisorActor");

问题

所以代码工作正常并按照我们的要求行事,除了Akka.Net&#34;问&#34;上面显示的WebJob代码中的超时。

令人讨厌的是,如果我尝试在本地运行webjob,这似乎工作正常。在哪里我可以模拟一个&#34;问&#34;通过提供一个新的 supervisorActor 来暂停,该 supervisorActor 根本不会通过回复给发送者&#34;来回复消息。

这可以在我的机器上完美运行,但是当我们在Azure中运行此代码时,我们看不到&#34;问&#34;即使我们的一个工作流程超出了&#34;问&#34;超时一英里。

我只是不知道可能导致这种行为的原因,是否有人有任何想法?

我需要为WebJob设置一些特定于Azure的配置值。

1 个答案:

答案 0 :(得分:0)

对此的答案是使用异步兔子处理程序,该处理程序显然是在C#兔子客户端的V5.0中推出的。官方文档仍然显示同步使用情况(可悲)。

本文相当不错:https://gigi.nullneuron.net/gigilabs/asynchronous-rabbitmq-consumers-in-net/

一旦我们做到了,一切都会很好