目前,我们有一个应用程序,它使用服务代理将消息排队发送到外部系统,我们通过 Web 服务接口与外部系统进行通信。
目前我们只与一家公司集成,因此一个队列就足够了 - 但是我们需要开始将消息传递给所有使用相同 Web 服务接口的多个公司。
我想知道单个队列系统是否足以满足此目的,或者我们应该为每个公司设置一个队列。对于每个公司都有一个队列,我担心将其扩展,因为我们可能有很多队列,然后有很多连接来检查队列。
然而,使用单个队列,我们可以根据需要添加更多读者。然而,如果我们无法与外部系统之一通信(例如连接问题),那么消息就没有问题,我们想重试,但我们不想为那些系统已启动。我想知道人们目前如何处理类似的情况?
我们可以重新插入消息,但我担心的是我们不保证交付顺序。
We currently have an application that uses service broker to queue messages to sent to an external system, which we communicate with via a web service interface.
At present we only integrate with a single company, so one queue is sufficient - however we need to start passing messages to multiple companies who all use the same web service interface.
I'm wondering if a single queue system is sufficient for this or should we have a queue per company. With a queue per company I'm worried about scaling this out as we could have lots of queues and then lots of connections to check the queues.
With a single queue however we can just add more readers as required. However, if we cannot communicate with one of the external systems (e.g. connectivity issue), then there isn't an issue with the message, and we'd want to retry it, but we don't want to delay messages for companies whose systems are up. I was wondering how people are currently dealing with similar scenarios?
We could reinsert the message, but the concern I have about that is that we don't guarantee order of delivery.
发布评论
评论(1)
我假设“重新插入”消息意味着只是回滚接收该消息的事务。其效果是该消息将可供再次接收,作为给定对话中的第一条消息(因此您无需担心保留传递顺序)。也就是说,这种方法存在一个问题,即有毒消息处理。如果回滚来自给定队列的 5 个连续接收,则该队列将被禁用。
Klaus Aschenbrenner 的书中详细描述了另一种方法,即待处理请求表。一旦激活的过程从 Service Broker 队列接收到请求消息,它就会尝试执行 Web 服务调用。如果由于某种原因失败,请求将被放入待处理请求表中并每隔一段时间重试一次(您可以使用 对话计时器来安排重试)。这样,如果 Web 服务不可用,它就不会一直阻止 Service Broker 读取器为其他公司提供服务(假设第一个请求的超时足够小)。而且,由于无论 Web 服务调用是否成功,接收都会提交,因此您不会遇到有毒消息问题。
I'm assuming that by "reinserting" a message you mean just rolling back the transaction that received it. The effect will be that the message will become available for receive again, as a first message from the given conversation (so you don't need to worry about preserving the order of delivery). That said, there is a problem with this approach, namely the poison message handling. If 5 consecutive receives from a given queue are rolled back, the queue will become disabled.
An alternative approach, described in detail in Klaus Aschenbrenner's book, is to have a table of pending requests. As soon as the activated procedure receives a request message from Service Broker queue, it tries to do the web service call. If that fails for some reason, the request is put in the pending requests table and retried every once a while (you can use conversation timers to schedule retries). That way, if a web service is not available, it won't keep blocking the Service Broker reader from servicing other companies (assuming the timeout for the first request is small enough). And since the receive will be committed no matter if the web service call succeeds, you won't run into poison message problem.