我需要在发行者和订阅者之间建立双向沟通。这是为了方便前端MVC3应用程序使用相关过滤器定义订阅,然后将消息放置到主题上。最后,MVC3控制器调用SubscriptionClient上的BeginReceive(),并等待响应。
问题似乎是创建和删除这些订阅对象。开销是巨大的,它使应用程序慢到爬行。这就没有提到对某个主题的各种限制,例如不超过2000次订阅。
在发行者和订阅者之间建立这种双向通信的最佳实践是什么?我们希望MVC3应用程序发布一条消息,然后等待对该消息的响应(通过CorrelationId属性和CorrelationFilter)。我们已经缓存了NamespaceManager和MessagingFactory,因为它们昂贵得令人望而却步,也是因为我们被告知服务总线使用了一个显式的供应模型,在这个模型中,我们需要在角色启动时预先创建大部分这些东西。
因此,这给我们带来了将请求与响应相关联以及创建和删除订阅的巨大开销的挑战。还有什么更好的做法吗?我们是否应该保存一个SubscriptionClients缓存,并每次交换过滤器?其他人都做什么?通过Web集群,我需要每秒5到10,000个MVC3请求的请求吞吐量。我们已经在使用AsyncController,并在SubscriptionClient上使用异步BeginReceive()。似乎是成千上万的人创建和删除了订阅,在这一点上扼杀了系统。
UPDATE1:基于这里提供的很好的建议,我们已经更新了这个解决方案,以便在每个web角色实例上保持SubscriptionClient对象的缓存。此外,我们已经迁移到了面向MessageSession的方法。
然而,这仍然没有扩大。AcceptMessageSession()似乎是一个非常昂贵的操作。MessageSession对象也应该被缓存和重用吗?每个打开的MessageSession对象是否使用到服务总线的连接?如果是,这算在订阅的并发连接配额中吗?
非常感谢。我想我们快到了。web上的大多数示例代码显示:创建主题(),然后是CreateSubscription(),然后是CreateSubscriptionClient(),然后是客户机上的BeginReceive(),然后是所有对象的删除。我能说的是,如果你在现实生活中这么做,你的服务器就会崩溃,你很快就会在连接上达到极限。
我们需要以每秒数千次的速度处理这些请求,很明显,这些对象必须被大量缓存和重用。那么,MessageSession是否是另一个要缓存的项呢?我将有一个有趣的缓存,因为我们必须实现一个引用计数机制,其中一次只能发出一个对MessageSession的引用,因为这是针对http请求特定的请求/响应的,而且我们不能让其他订阅者同时使用MessageSession对象。
UPDATE2: OK,缓存MessageSession以供重用是不可行的,因为它们只存在于订阅上的LockDuration。这是一个令人沮丧的,因为最大的LockDuration是5分钟。它们似乎适用于短时间的pub/子进程,而不是长时间运行的分布式进程。看来我们需要回到轮询Azure表。
SUMMARY/COMMENTARY我们尝试在服务总线上构建,因为它具有规模潜力和持久性以及交付语义。然而,似乎有些情况下,大量的请求/响应,其中不适合它。发布部分工作得很好,在后端有竞争的消费者是很好的,但是在定义的单用户响应上等待前端请求并不能很好地扩展,因为MessageSessions通过AcceptMessageSession()或BeginAcceptMessageSession()创建太长时间了,而且它们不适合缓存。
如果有人有另一种观点,我很想听听。
发布于 2012-09-27 05:19:27
这个场景是一个典型的请求/响应,是一个很好的使用会话的候选。这是另一种相关机制。创建一个简单的请求队列和响应队列。每个web角色线程都为一个请求创建一个惟一的会话in,并将该值放入brokeredmessage的"ReplyToSessionID“属性中。此外,这个线程用sessionid值在响应队列上调用一个AcceptMessageSession,从而锁定它。代理消息被发送到请求队列,所有工作人员角色都会竞争消息。当一个worker角色获得一个请求时,它会处理它,创建一个响应消息,并在响应message = replytosessinid上设置sessionid属性。然后,这将被发送到响应队列,并且只会被传递到已锁定该会话id的线程。详细的样本使用会话在这里。这里还有两个额外的示例,使用排队和主题来实现请求响应相关性。
发布于 2012-10-04 05:13:28
另一种方法是使用关联ids和回调委托的字典,在web角色实例上执行消息关联。
每个web角色(发布服务器)实例都有一个订阅,由单个订阅id筛选,用于响应主题。
在发送消息之前,将在字典中注册该消息的回调,并以关联id作为键。将相关id和订阅id与消息一起发送,以便可以将响应与相关id一起发送回正确的订阅。
每个web角色实例监视单个订阅,在收到响应时,删除字典条目并调用回调。
发布于 2012-09-26 23:16:06
对于单个发送方和接收方,您只需要有一个主题/订阅。您可以在同一订阅上设置多个相关滤波器,从而使需要关联的所有响应在同一订阅中显示出来。目前,我们支持单个订阅上的最多100,000相关过滤实例,并且可以添加/删除这些实例(如果需要的话,可以添加/删除这些实例)以及主题/订阅上的消息发送/接收操作。
此外,如果需要,可以使用带有操作的规则为消息加上附加属性,具体取决于匹配的筛选器。
https://stackoverflow.com/questions/12602546
复制相似问题