【问题标题】:.Net framework to manage background running processess on seperate machines.Net 框架来管理不同机器上的后台运行进程
【发布时间】:2018-01-24 12:34:53
【问题描述】:

我有一个驻留在服务器上的 asp.mvc 应用程序。从这个应用程序中,我想启动一个运行时间较长的进程,并且将是资源密集型操作。

所以我想要做的是我想要一些像 3 这样的用户代理,它将在 3 台机器上,并且这个用户代理将只使用它们各自机器的资源。

与 Hadoop 一样,我们有主节点和集群,其中任务在单个集群上运行,并且有 1 个主节点跟踪所有这些集群。

在 Azure 中,我们有运行任务的虚拟机,如果需要,Azure 可以通过启动新实例来自动水平扩展以加快任务速度。

所以我想创建这样的基础设施,我可以将我的任务从 mvc 应用程序提交给 3 个用户代理,我的应用程序将跟踪这些代理,比如哪个代理是免费的,哪个被占用,哪个不工作这个。

我想从每个用户代理接收进度并显示在我的 MVC 应用程序上。

.net 中是否有任何框架可以让我管理此后台运行操作(跟踪、启动、停止等),或者应该采用什么方法?

更新:我不想为这个长时间运行的操作放置大量服务器,而且我想跟踪这个长时间运行的进程,就像他们在做什么一样,错误在哪里等.

以下是我正在考虑的方法,我不知道哪种方法更有意义:

1) 以本地 2-3 台计算机的代理形式安装 Windows 服务,以利用 resp 资源并打开与该代理的 tcp/ip 连接,除非并且直到长时间运行的过程完成。

2) 使用 hangfire 在 IIS 线程之外运行这个长时间运行的进程,但我想这会给服务器带来负载。

我想知道上述方法可能存在的问题,以及是否有比这更好的方法。

【问题讨论】:

  • 这是一个相当广泛的问题。我个人会为此使用一些消息队列(如rabbitmq) - 从MVC您只需发布描述要完成的任务的消息,而不关心有多少工人以及在哪里。列在队列中的workers和rabbitmq会以循环的方式向它们发送消息。
  • @Evk 我不想把这个处理负载放在我的服务器上。我想在客户端环境中做这个长时间的处理来释放我的服务器。我的服务器(我托管我的 mvc 应用程序的地方)将是只负责跟踪这个长期运行的进程(工作进度、完成、停止等)。我想有一个 wcf 服务,它将由 mvc 应用程序调用并且是免费的。这个 wcf 服务将在客户端环境中.那么 rabbitqueue 会在 wcf 中吗?
  • RabbitMQ 是消息总线。您从一个地方(asp.net 服务)发布消息并在另一个地方(位于不同服务器上的工作人员之一)接收它。这样您就可以在不接触 mvc 服务的情况下添加\删除工作人员,并且您不需要打扰工作人员所在的位置(即 - 不需要知道 IP 地址或其他任何内容)。
  • @Evk 在其中一个答案中提到hangfire 怎么样?
  • 您到底想对流程的结果做什么?由于 asp.net 是 REST,你应该如何显示结果(Signalr?单独的网站?等等?)

标签: c# asp.net-mvc windows-services daemon hangfire


【解决方案1】:

Hangfire 确实是处理后台任务的绝佳解决方案,我们已在项目中大量使用它。

我们已经在单独的 IIS 服务器上设置了 MVC 应用程序,该服务器也是一个 hangfire 客户端,只是将需要由 hangfire 服务器执行的作业排入队列。然后我们有两个hangfire服务器实例,它们是windows服务应用程序。如此有效地,MVC 应用服务器上没有负载来处理后台作业,因为它是由单独的 hangfire 服务器处理的。

hangfire 非常有用的功能之一是其开箱即用的仪表板,它允许您监视和控制后台作业处理的任何方面,包括统计信息、后台作业历史记录等。

在应用程序和hangfire服务器中配置hangfire

public void Configuration(IAppBuilder app)
{
    GlobalConfiguration.Configuration.UseSqlServerStorage("<connection string or its name>");

    app.UseHangfireDashboard();
    app.UseHangfireServer();
}

请注意,您使用相同的连接字符串。仅当您想将实例用作hangfire 服务器时才使用app.UseHangfireServer(),因此在您的情况下,您希望从应用程序服务器配置中省略此行并仅在hangfire 服务器中使用。 在实例中也使用app.UseHangfireDashboard(),它将为您的hangfire仪表板提供服务,这可能是您的MVC应用程序。

当时我们使用Windows Service 完成了它,但如果现在必须这样做,我想使用Azure worker role 甚至更好的现在Azure Web Jobs 来托管我的hangfire 服务器,并管理诸如自动之类的东西轻松缩放。

请参考hangfire overviewdocumentation 了解更多详情。

【讨论】:

  • 非常感谢您的回答和您为帮助我所做的努力。我将拥有相同的东西,例如 1 个 mvc 应用程序和 1or2 个 Windows 服务,其中将进行后台处理。所以我必须编写应用程序.UseHangfireDashboard();在 mvc 应用程序和 Windows 服务应用程序中?
  • @Learning-Overthinker-Confused - 仅在 MVC 应用程序中使用仪表板。并确保应用程序服务器和hangfire服务器的连接字符串相同
  • 对不起,我的意思是询问 app.UseHangfireServer();我需要 app.UseHangfireServer();仅在将进行后台作业处理的 Windows 服务中,而不是在 mvc 中(我只会将作业排入队列)。对吗?
  • @Learning-Overthinker-Confused - 没错。如果您有超过 1 台 HF 服务器,请在所有服务器中使用 app.UseHangfireServer()
  • 所以hangfire服务器将驻留在我的后台处理将发生的地方,因为我想在windows应用程序中处理后台处理,所以hangfire服务器将驻留在windows服务上。我不需要mvc应用程序中的hangfire服务器,因为在mvc 应用程序我只是想排队工作。如果我错了,请纠正我,如果我问愚蠢的问题,我很抱歉,但我只是想用 hangfire 来理解事情:)
【解决方案2】:

将消息从您的 MVC 应用程序推送到 MSMQ,并让您的 Windows 服务侦听(或循环)进入队列的新消息。

在您的 MVC 应用程序中为每个排队的消息创建一个 ID,以便在工作取得进展时从您的 Windows 服务返回到 mvc 应用程序的 restful API 调用?

【讨论】:

    【解决方案3】:

    看看 Hangfire,它可以管理后台任务并跨 VM 工作而不会发生冲突。我们已经使用它替换了 Windows 服务,它运行良好。

    https://www.hangfire.io

    【讨论】:

    • 所以考虑我有一个 mvc 应用程序,我将从那里开始长时间运行的操作和 1 个 wcf 服务,我想在其中处理这个长时间运行的操作,而且这个 mvc 应用程序将显示这个长时间运行的进程的跟踪。 Wcf 服务将驻留在客户端环境中。因此,如果我会触发并忘记 mvc 应用程序的工作,那么这会将负载放在我的 mvc 应用程序服务器上吗?
    • 是的,Hangfire 将在应用服务器上的 IIS 中创建进程。
    • 但我从文档中了解到hangfire 使用 IIS 之外的线程
    • 好的,这样更好,在这种情况下,负载仍将在服务器上,但不会直接在 IIS 或您的 Web 应用程序上。
    • 但我想从 mvc 应用服务器中移除该负载,并将该负载放在正在执行该长时间运行操作的服务上。这可以通过 hangfire 实现吗?
    【解决方案4】:

    试试http://easynetq.com/

    EasyNetQ 是一个简单易用、固执己见的 RabbitMQ .NET API。

    EasyNetQ 是在 RabbitMQ.Client 库之上提供服务的组件集合。它们执行序列化、错误处理、线程编组、连接管理等操作。

    使用 EasyNetQ 发布

    var message = new MyMessage { Text = "Hello Rabbit" };
    bus.Publish(message);
    

    要订阅消息,我们需要给 EasyNetQ 一个动作,以便在消息到达时执行。我们通过传递 subscribe 一个委托来做到这一点:

    bus.Subscribe<MyMessage>("my_subscription_id", msg => Console.WriteLine(msg.Text));
    

    现在,每次发布 MyMessage 的实例时,EasyNetQ 都会调用我们的委托并将消息的 Text 属性打印到控制台。

    EasyNetQ 的性能与 RabbitMQ 代理的性能直接相关。这可能因网络和服务器性能而异。在具有本地 RabbitMQ 实例的开发人员机器上进行的测试中,实现了每秒约 5000 条 2K 消息的持续过夜性能。所有 EasyNetQ 端点的内存使用在夜间运行中都很稳定

    【讨论】:

    • 但是我需要在服务器上安装 RabbitMQ 才能使用 RabbitMQ?
    • 是的,因为easyNetQ只是RabbitMQ的一个API,虽然它会处理RabbitMQ的所有复杂性,并使AMQP更流畅。
    • 假设我在 RabbitMq 队列中提交了 2 个作业,并且我想跟踪每个作业的进度。这可以使用 RabbitMQ 和 easyNetQ 吗?
    • 你可以通过delivery tags来实现,你可以查看这个链接,它有很好的解释:jack-vanlightly.com/blog/2017/3/11/…
    • 非常感谢您的回答和您对帮助我的帮助。考虑一下我有一个 mvc 应用程序,我将在其中发布驻留在 azure cloud 中的工作。我有 Windows 服务在客户端执行所有这些后台工作。那么这个 rabbitmq 将驻留在哪里?在天蓝色或客户端,以便与生产者和消费者握手
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-11
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-17
    相关资源
    最近更新 更多