NServiceBus - 使用相同的键对 sagas 进行排队
NServiceBus - queue up sagas with the same key
场景:
我用 10 个步骤构建了一个传奇。它正在更新各种系统,整个传奇可能需要几分钟才能完成。
传奇始于另一个系统的数据,用户在该系统中输入客户信息。
我无法看到用户何时在他们的系统中完成数据输入,但我每隔 x 分钟从系统中读取一次数据并更改。
我的问题是,每当我开始使用客户数据的 saga 时,我需要确保同一客户的先前 saga 已经完成。
如果用户花 10 分钟输入数据,系统可能会针对同一个客户启动 5 个流程,并且流程可能会超过之前的流程,并弄乱数据。
有人知道我该如何解决这个问题吗?
提前致谢。
奥莱
如果不更改 saga 和可能由客户端系统发送的消息,您将无法解决此问题。
您的问题是 saga 可能配置为在收到特定消息类型时启动,每次用户对客户进行更改时客户端应用程序都会生成该消息类型。
让我们调用此消息:
public class ClientTypedSomethingAboutCustomer
{
int CustomerId {get;set;}
...
}
您的 saga 将设置如下:
public class CustomerSaga : Saga<CustomerSagaData>, IAmStartedByMessages<ClientTypedSomethingAboutCustomer>
{
public override void ConfigureHowToFindSaga()
{
ConfigureMapping<ClientTypedSomethingAboutCustomer>
(message => message.CustomerId).ToSaga(saga => saga.CustomerId);
...
}
...
}
这会导致 saga 初始化,并在 IContainSagaData 实现中为收到的每条客户端消息设置客户 ID 值。
要解决更多消息初始化新 sagas 的问题,您可以创建另一种消息类型,以区分某人何时开始键入有关客户的内容,然后键入有关该客户的其他内容。
类似于:
public class ClientTypedSomethingElseAboutCustomer
{
int CustomerId {get;set;}
...
}
那么您的 saga 将如下所示:
public class CustomerSaga : Saga<CustomerSagaData>, IAmStartedByMessages<ClientTypedSomethingAboutCustomer>
,IHandleMessages<ClientTypedSomethingElseAboutCustomer>
{
public override void ConfigureHowToFindSaga()
{
ConfigureMapping<ClientTypedSomethingAboutCustomer>
(message => message.CustomerId).ToSaga(saga => saga.CustomerId);
ConfigureMapping<ClientTypedSomethingElseAboutCustomer>
(message => message.CustomerId).ToSaga(saga => saga.CustomerId);
}
...
}
这将确保有关客户的所有消息都将路由到单个 saga 实例。
在单线程模式下,运行 NServiceBus 可能会实现近似的排队行为。这可能会限制为客户创建并发传奇,但我不想依赖它。
@janpieter_z 和@tom-redfern 都是正确的:确保您可以将 saga 映射到某种客户 ID。
您还可以实现 complex saga finding logic 以找到与传入消息相对应的正确 saga。
此外,如果多条消息没有按正确的顺序到达,可以将它们设置为 "IAmStartedByMessages"。
最后,是谁向您的 saga 发送消息? saga 不应该负责发送收集数据的请求吗?也许每 10 秒通过超时或其他方式,直到几分钟内没有收到任何消息,或者处理程序回复不同的消息?
场景: 我用 10 个步骤构建了一个传奇。它正在更新各种系统,整个传奇可能需要几分钟才能完成。
传奇始于另一个系统的数据,用户在该系统中输入客户信息。
我无法看到用户何时在他们的系统中完成数据输入,但我每隔 x 分钟从系统中读取一次数据并更改。
我的问题是,每当我开始使用客户数据的 saga 时,我需要确保同一客户的先前 saga 已经完成。 如果用户花 10 分钟输入数据,系统可能会针对同一个客户启动 5 个流程,并且流程可能会超过之前的流程,并弄乱数据。
有人知道我该如何解决这个问题吗?
提前致谢。
奥莱
如果不更改 saga 和可能由客户端系统发送的消息,您将无法解决此问题。
您的问题是 saga 可能配置为在收到特定消息类型时启动,每次用户对客户进行更改时客户端应用程序都会生成该消息类型。
让我们调用此消息:
public class ClientTypedSomethingAboutCustomer
{
int CustomerId {get;set;}
...
}
您的 saga 将设置如下:
public class CustomerSaga : Saga<CustomerSagaData>, IAmStartedByMessages<ClientTypedSomethingAboutCustomer>
{
public override void ConfigureHowToFindSaga()
{
ConfigureMapping<ClientTypedSomethingAboutCustomer>
(message => message.CustomerId).ToSaga(saga => saga.CustomerId);
...
}
...
}
这会导致 saga 初始化,并在 IContainSagaData 实现中为收到的每条客户端消息设置客户 ID 值。
要解决更多消息初始化新 sagas 的问题,您可以创建另一种消息类型,以区分某人何时开始键入有关客户的内容,然后键入有关该客户的其他内容。
类似于:
public class ClientTypedSomethingElseAboutCustomer
{
int CustomerId {get;set;}
...
}
那么您的 saga 将如下所示:
public class CustomerSaga : Saga<CustomerSagaData>, IAmStartedByMessages<ClientTypedSomethingAboutCustomer>
,IHandleMessages<ClientTypedSomethingElseAboutCustomer>
{
public override void ConfigureHowToFindSaga()
{
ConfigureMapping<ClientTypedSomethingAboutCustomer>
(message => message.CustomerId).ToSaga(saga => saga.CustomerId);
ConfigureMapping<ClientTypedSomethingElseAboutCustomer>
(message => message.CustomerId).ToSaga(saga => saga.CustomerId);
}
...
}
这将确保有关客户的所有消息都将路由到单个 saga 实例。
在单线程模式下,运行 NServiceBus 可能会实现近似的排队行为。这可能会限制为客户创建并发传奇,但我不想依赖它。
@janpieter_z 和@tom-redfern 都是正确的:确保您可以将 saga 映射到某种客户 ID。
您还可以实现 complex saga finding logic 以找到与传入消息相对应的正确 saga。
此外,如果多条消息没有按正确的顺序到达,可以将它们设置为 "IAmStartedByMessages"。
最后,是谁向您的 saga 发送消息? saga 不应该负责发送收集数据的请求吗?也许每 10 秒通过超时或其他方式,直到几分钟内没有收到任何消息,或者处理程序回复不同的消息?