Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实现.net核心工作者服务编排器_C#_Asp.net Core_Rabbitmq_Backgroundworker_Masstransit - Fatal编程技术网

C# 实现.net核心工作者服务编排器

C# 实现.net核心工作者服务编排器,c#,asp.net-core,rabbitmq,backgroundworker,masstransit,C#,Asp.net Core,Rabbitmq,Backgroundworker,Masstransit,我有一个.net核心控制台应用程序,目前有1个IHostedService,我需要在应用程序启动时生成和管理此服务的多个实例 我希望实现某种协调器,负责启动、监视和重新启动工作人员。我知道这个概念,但我不确定它的实施情况 工人自己将在实例化时通过ICallProgService打开一个到proprietry数据库的会话并对其进行维护。然后,工作人员将使用masstransit库通过RabbitMq以请求/响应模式监听消息队列 这里的细微差别是,我相信(不是100%确定)它们都需要连接到masst

我有一个.net核心控制台应用程序,目前有1个IHostedService,我需要在应用程序启动时生成和管理此服务的多个实例

我希望实现某种协调器,负责启动、监视和重新启动工作人员。我知道这个概念,但我不确定它的实施情况

工人自己将在实例化时通过
ICallProgService
打开一个到proprietry数据库的会话并对其进行维护。然后,工作人员将使用masstransit库通过RabbitMq以请求/响应模式监听消息队列

这里的细微差别是,我相信(不是100%确定)它们都需要连接到masstransit的相同
IBusControl

工作人员的代码如下所示:

public class MessageQueueWorker : BackgroundService
{
    private readonly ICallProgService _callProgService;
    private readonly IBusControl _bus;

    public MessageQueueWorker(ICallProgService callProgService)
    {
        _callProgService = callProgService;
        _bus = Bus.Factory.CreateUsingRabbitMq(cfg =>
        {
            cfg.Host(new Uri("rabbitmq://localhost/"), h => { });

            cfg.ReceiveEndpoint("callprog-service", e =>
            {
                e.Handler<ICallProgRequest>(context =>
                {
                    Console.WriteLine($"Calling Program: {context.Message.ProgramName}");
                    return context.RespondAsync<ICallProgResponse>(new
                    {
                        Result = _callProgService.CallProgProgramAsync(
                            new CallProgRequest
                            {
                                ProgramName = context.Message.ProgramName,
                                ProgramParams = context.Message.ProgramParams
                            })
                    });
                });
            });
        });
    }

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        return _bus.StartAsync(stoppingToken);
    }

    public override Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.WhenAll(base.StopAsync(cancellationToken), _bus.StopAsync(cancellationToken));
    }
}
public类MessageQueueWorker:BackgroundService
{
专用只读ICallProgService _callProgService;
专用只读IBusControl总线;
public MessageQueueWorker(ICallProgService callProgService)
{
_callProgService=callProgService;
_bus=bus.Factory.CreateUsingRabbitMq(cfg=>
{
主机(新Uri(“rabbitmq://localhost/),h=>{});
ReceiveEndpoint(“callprog服务”,e=>
{
e、 处理程序(上下文=>
{
WriteLine($“调用程序:{context.Message.ProgramName}”);
返回context.RespondAsync(新的
{
结果=\u callProgService.CallProgProgramAsync(
新的CallProgRequest
{
ProgramName=context.Message.ProgramName,
ProgramParams=context.Message.ProgramParams
})
});
});
});
});
}
受保护的覆盖任务ExecuteAsync(CancellationToken stoppingToken)
{
返回总线启动同步(停止停止);
}
公共覆盖任务StopAsync(CancellationToken CancellationToken)
{
返回Task.WhenAll(base.StopAsync(cancellationToken))\u bus.StopAsync(cancellationToken));
}
}
节目开始

static async Task Main(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(System.IO.Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings2.json", optional: true, reloadOnChange: true)
            .Build();

        var builder = new HostBuilder()
            .ConfigureServices((hostcontext, services) =>
            {
                services.Configure<QmClientOptions>(config);
                services.AddSingleton<IQmClient, QmClient>();
                services.AddSingleton<ICallProgService, QmCallProgService>()
                .AddHostedService<MessageQueueWorker>();
            });

        await builder.RunConsoleAsync();
    }
static async Task Main(字符串[]args)
{
var config=new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile(“appsettings2.json”,可选:true,重载更改:true)
.Build();
var builder=新主机生成器()
.ConfigureServices((主机上下文,服务)=>
{
services.Configure(config);
services.AddSingleton();
services.AddSingleton()
.AddHostedService();
});
等待builder.RunConsoleAsync();
}

所需解决方案的最佳实施方法是什么?

由于您使用的是Microsoft的依赖项注入和通用主机,我强烈建议您遵循并让MassTransit设置和管理总线。这还将为您提供运行状况监视,以确保服务正常运行(当然,运行状况监视是可选的)


我还建议使用,并使用
ConfigureConsumer(context)
对其进行配置,以便可以为每条消息利用容器作用域。除了简单的测试之外,不鼓励使用处理程序,因为它们不会创建容器范围。它们工作正常,但鼓励将消费者功能分离出来。

谢谢,您提供的链接看起来为我指明了正确的方向。我一定是忽视了它。关于多个工人使用机器翻译的方法,您有什么建议吗?这里需要的是请求/响应模式,而不是发布/订阅模式。我大概需要在工作实例上共享一条总线?我是否需要消费者的多个实例等。MT是否处理此问题?如果您能提供一个概念性的示例,那就太好了。ThanksMassTransit将创建多个使用者实例,最多可达到接收端点上配置的限制。您的请求者可以使用请求客户端与消费者交互,也可以使用AddRequestClient配置方法添加。谢谢。我想说清楚。数据库上需要以下逻辑1 consumer=1活动会话,该会话是在应用程序启动和维护时创建的,因此这里的解决方案是让MT充当编排器。注册同一消费者的多个实例,每个实例都有自己连接到DB的会话?