与 Service Fabric 中的两个或多个有状态服务共享队列
Share queue with two or more stateful services within Service Fabric
是否可以在 2 个或多个有状态服务之间共享一个队列,或者我是否需要通过 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();
}
}
}
}
然后我的第二个服务从那个队列中读取,然后继续处理。
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();
}
}
}
}
我在文档中看不到太多关于此的内容,我可以看到 GetOrAddAsync
方法可以接受一个 uri,但我没有看到任何关于它如何工作的例子,或者你是否可以交叉服务?
这背后的想法是将处理拆分到单独的队列中,这样当我们尝试重试消息时就不会陷入不一致的状态。
无法跨服务共享状态。 statemanager 作用于服务分区级别。
您可以为此目的使用外部队列,例如服务总线。
您也可以使用 Event Driven 方法反转控制。服务 1 将引发一个事件,服务 2 将使用该事件作为继续处理的触发器。要处理的数据可以在事件内部,或者存储在另一个位置的数据,从事件中引用。
是否可以在 2 个或多个有状态服务之间共享一个队列,或者我是否需要通过 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();
}
}
}
}
然后我的第二个服务从那个队列中读取,然后继续处理。
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();
}
}
}
}
我在文档中看不到太多关于此的内容,我可以看到 GetOrAddAsync
方法可以接受一个 uri,但我没有看到任何关于它如何工作的例子,或者你是否可以交叉服务?
这背后的想法是将处理拆分到单独的队列中,这样当我们尝试重试消息时就不会陷入不一致的状态。
无法跨服务共享状态。 statemanager 作用于服务分区级别。
您可以为此目的使用外部队列,例如服务总线。
您也可以使用 Event Driven 方法反转控制。服务 1 将引发一个事件,服务 2 将使用该事件作为继续处理的触发器。要处理的数据可以在事件内部,或者存储在另一个位置的数据,从事件中引用。