池自定义WCF通道

时间:2010-01-13 01:22:05

标签: wcf performance channel ibm-mq pooling

我们开发了一个自定义WCF通道,它通过IBM Websphere MQ进行通信。

我们创建了一个渠道工厂:

public class MqChannelFactory : ChannelFactoryBase<IRequestChannel>

返回我们频道的实例:

public class MqRequestChannel : ChannelBase, IRequestChannel

连接到IBM MQ队列管理器是一项昂贵的操作。目前,我们在Channel.OnOpen()中执行此操作。

遵循正确使用频道的准则,每当我们需要频道,发送消息,然后调用Channel.Close()时,我们就会调用ChannelFactory.CreateChannel()。

我们的假设是,ChannelFactory执行了通道池,因此当调用Channel.Close()时,通道实际上并未关闭,而是返回到池中。但是,每当我们调用ChannelFactory.CreateChannel时,都会实例化一个新通道,并且在发送请求时,会执行昂贵的通道打开。

所以,问题是:阻止每个请求打开频道的最佳方法是什么?

我们正在研究的一些选项:

  • 无论如何通过配置来指定应该进行频道合并吗?我们应该在我们的ChannelFactory中实现我们自己的频道池吗?

  • 我们是否应该在应用程序的生命周期内保持我们的频道开放,通过它发送所有请求?

  • 我们是否应该在渠道工厂中执行昂贵的操作(连接到队列管理器),我们会在应用程序的生命周期内进行缓存?

1 个答案:

答案 0 :(得分:1)

关于最佳选择是什么,确实没有硬性规定。最初,我想说最简单的解决方案是在应用程序级别缓存客户端通道。根据您的实现,可能需要进行一些同步工作,顺便说一下。

您可以在ChannelFactory级别池连接。我会犹豫是否要整合整个渠道(那里总是存在一些复杂性),但是你可以在内部汇集连接,让渠道在需要时从渠道工厂所持有的池中获取连接。

这确实具有从.NET 3.0 SP1开始的ClientBase already caches ClientFactory实例的优势,因此可以使应用程序代码更容易(如果您正在使用它)。

但缺点是,如果端点地址具有打开与队列管理器的连接所需的信息,那么实现可能会更难实现,因为您可能会为不同的端点创建通道来自单个ChannelFactory对象的地址。可能这意味着你需要明确地禁止这个,或者你的ChannelFactory实现可能需要在内部保留多个连接池(每个端点地址一个或类似的东西)。