C# 与服务结构中的两个或多个有状态服务共享队列

C# 与服务结构中的两个或多个有状态服务共享队列,c#,azure-service-fabric,service-fabric-stateful,C#,Azure Service Fabric,Service Fabric Stateful,是否可以在两个或多个有状态服务之间共享队列,或者我是否需要通过tcp/http直接调用它以将消息放入其自身的内部队列 比如,;假设我有我的第一个服务,它根据一个条件向队列下订单: public sealed class Service1 : StatefulService { public Service1(StatefulServiceContext context, IReliableStateManagerReplica reliableStateManagerReplica)

是否可以在两个或多个有状态服务之间共享队列,或者我是否需要通过tcp/http直接调用它以将消息放入其自身的内部队列

比如,;假设我有我的第一个服务,它根据一个条件向队列下订单:

public sealed class Service1 : StatefulService
{
    public Service1(StatefulServiceContext context, IReliableStateManagerReplica reliableStateManagerReplica)
        : base(context, reliableStateManagerReplica)
    { }

    protected override async Task RunAsync(CancellationToken cancellationToken)
    {
        var customerQueue = await this.StateManager.GetOrAddAsync<IReliableQueue<Order>>("orders");

        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();

            using (var tx = this.StateManager.CreateTransaction())
            {
                if (true /* some logic here */)
                {
                    await customerQueue.EnqueueAsync(tx, new Order());
                }

                await tx.CommitAsync();
            }
        }
    }
}
公共密封类服务1:StatefulService
{
公共服务1(StatefulServiceContext上下文,IReliableStateManagerReplica reliableStateManagerReplica)
:base(上下文,reliableStateManagerReplica)
{ }
受保护的覆盖异步任务RunAsync(CancellationToken CancellationToken)
{
var customerQueue=wait this.StateManager.GetOrAddAsync(“订单”);
while(true)
{
cancellationToken.ThrowIfCancellationRequested();
使用(var tx=this.StateManager.CreateTransaction())
{
if(true/*此处有一些逻辑*/)
{
等待customerQueue.EnqueueAsync(tx,neworder());
}
wait tx.CommitAsync();
}
}
}
}
然后,我的第二个服务从该队列读取数据,然后继续处理

public sealed class Service2 : StatefulService
{
    public Service2(StatefulServiceContext context, IReliableStateManagerReplica reliableStateManagerReplica)
        : base(context, reliableStateManagerReplica)
    { }

    protected override async Task RunAsync(CancellationToken cancellationToken)
    {
        var customerQueue = await this.StateManager.GetOrAddAsync<IReliableQueue<Order>>("orders");

        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();

            using (var tx = this.StateManager.CreateTransaction())
            {
                var value = await customerQueue.TryDequeueAsync(tx);
                if (value.HasValue)
                {
                    // Continue processing the order.
                }

                await tx.CommitAsync();
            }
        }
    }
}
公共密封类服务2:StatefulService
{
公共服务2(StatefulServiceContext上下文,IReliableStateManagerReplica reliableStateManagerReplica)
:base(上下文,reliableStateManagerReplica)
{ }
受保护的覆盖异步任务RunAsync(CancellationToken CancellationToken)
{
var customerQueue=wait this.StateManager.GetOrAddAsync(“订单”);
while(true)
{
cancellationToken.ThrowIfCancellationRequested();
使用(var tx=this.StateManager.CreateTransaction())
{
var value=wait customerQueue.TryDequeueAsync(tx);
if(value.HasValue)
{
//继续处理订单。
}
wait tx.CommitAsync();
}
}
}
}
我在文档中看不到太多关于此的内容,我可以看到
GetOrAddAsync
方法可以接受uri,但我没有看到关于此方法如何工作的示例,或者您是否可以执行跨服务


这背后的想法是将处理拆分为单独的队列,以便在尝试重试消息时不会处于不一致的状态。

无法跨服务共享状态。作用于服务分区级别

为此,您可以使用外部队列,如服务总线


您还可以使用一种方法来反转控制。服务1将引发一个事件,服务2将该事件用作继续处理的触发器。要处理的数据可能在事件内部,或者存储在另一个位置的数据,从事件中引用。

无法跨服务共享状态。作用于服务分区级别

为此,您可以使用外部队列,如服务总线


您还可以使用一种方法来反转控制。服务1将引发一个事件,服务2将该事件用作继续处理的触发器。要处理的数据可能在事件内部,或者存储在另一个位置的数据,从事件中引用。

是的,看起来是这样,与基于命令的方法相比,非常类似于发布/订阅方式。感谢您的澄清。是的,看起来是这样的,与基于命令的方法相比,非常像pub/sub方法。谢谢你的澄清。