我有一个Windows服务,它会在特定时间每天醒来,并找到需要处理的大约10万个事务。它将产生25个线程,这些线程查看需要处理的事务桶,并将调用WCF服务。
此WCF服务将执行一些内部处理并对外部服务进行同步调用(为了进行卷测试,我们已经模拟并编写了一个模拟器)。使用此设置进行大约10k次交易的短期运行,我们能够实现大约10的TPS。
我将此设置扩展为运行我们的WCF服务的三个负载平衡服务器和运行模拟器的另外两个服务器,我们还将Windows服务上的线程数增加到75个线程。有了这个新设置,我们预计性能会提高,但TPS仍然是10。
我在所有五台机器上都运行了性能监视器。拥有WCF服务的三个负载平衡服务器正在显示" Outstanding Calls"大约25个不断在" ServiceModelService" WCF服务的类别。但是运行模拟器的两台服务器只能显示9" Outstanding Calls"不断为嘲弄的服务。同样的模拟器显示了大约20个" Outstanding Calls"当它在一台服务器上运行时。
我的问题是: 为什么三台负载平衡机设置中的TPS没有增加? 这个系统的瓶颈在哪里?
目标是使用运行WCF服务的三个加载的平衡服务器获得大约30的TPS。
注意:我已将WCF服务和Windows服务上的Web配置中的maxconnection限制增加到200,这将TPS从大约6增加到当前值10。
编辑:更多信息,如果每个负载均衡服务器有25个未完成的呼叫,那么模拟的外部服务是否应该有3 * 25 = 75个未完成的呼叫?
通过maxconnection limit我的意思是:
<system.net>
<connectionManagement>
<add address="*" maxconnection="200" />
</connectionManagement>
</system.net>
答案 0 :(得分:0)
您可能无法向我们提供足够的信息来准确诊断问题。但是,你所描述的内容足以推荐一些值得一看的地方。
首先,您可能不应该在Windows服务中生成25个(或更多)线程。相反,您可以让一个线程查看“事务桶”,并将asynchronous calls发送到WCF服务。您可以使用信号量控制并发事务的数量。类似的东西:
Semaphore _transactionSemaphore = new Semaphore(25, 25);
while (transactionCount > 0)
{
transactionSemaphore.WaitOne(); // wait for a free spot
var transaction = getTransaction();
DoAsyncWcfCall(transaction);
}
异步完成事件(参见上面关于异步调用的链接)释放信号量:
void AsyncCompletedEvent(...)
{
// do after-call processing
// and then release the semaphore
transactionSemaphore.Release();
}
当transactionCount
变为0时,您必须等待所有未完成的呼叫完成。你通过反复等待信号量来做到这一点:25次。那就是:
for (int i = 0; i < 25; ++i)
{
transactionSemaphore.WaitOne();
}
如果您的主线程已经吞噬了信号量,那么您就知道没有任何未完成的呼叫。
您可以将并发事务计数扩展到50或75,或任何您喜欢的值。当然,你的硬件能够处理它。
这里的区别在于异步服务调用使用I / O完成端口而不是单个线程。分配一个只是坐在那里并等待的线程是非常浪费的。使用I / O完成端口,线程涉及的唯一时间是调用完成时 - 在async completed方法中。这些线程由线程池自动分配。
如果该服务不断显示25个未完成的呼叫,那么所有服务器的未完成呼叫总数最好不要超过该呼叫。如果WCF服务显示的事务比Windows服务显示的事务更多,那么您就遇到了问题。想想看,如果服务显示更多未完成的调用,而不是负载平衡服务器,那么您也遇到了问题。如果两者不匹配,那么有人会放弃一些东西:要么Windows服务认为它有WCF服务认为已填充的未完成的调用,反之亦然。
很难说瓶颈在哪里。如果您在Windows服务计算机上遇到高CPU使用率,那可能是您的瓶颈。你说WCF服务调用另一个外部服务。外部服务可能是瓶颈。根据你嘲笑它的方式,模拟可能是瓶颈。您确定了外部服务需要多长时间?运行模拟服务的服务的吞吐量似乎低于与真实服务通信的WCF服务,这让我觉得你的模拟性能有问题。
我认为您的WCF服务可能没有正确清理资源,并且他们在垃圾收集中花费了过多的时间。您确认自己使用的是server garbage collector吗?我认为这是WCF服务的默认设置,但您需要检查。
根据您提供的信息,我认为这些可能是瓶颈。
另一件事。拥有Windows服务除了坐在那里并且每天“醒来”处理一些交易之外什么都不做,这是非常浪费的。您应该将其设置为控制台应用程序并schedule a task每天运行一次。您可以使用任务计划程序GUI,也可以使用schtasks命令对其进行计划。请参阅Programs are not cats。
使您的程序成为控制台应用程序而非服务的另一个好处是调试控制台应用程序要容易得多。