【发布时间】:2011-09-16 10:56:49
【问题描述】:
我们有一些用每个人都喜欢的语言(?)——VB6 编写的 COM+ 代码。该 COM+ 组件调用由第三方编写的标准 COM 组件,该组件执行对 SQL Server 数据库的调用。我们在 COM+ 中没有做任何花哨的事情——仅此而已(这只是一个示例;我们并没有真正调用我们的函数 doStuff :-)):
Function doStuff
Dim o As Library.Object
Set o = New Library.Object
str = o.DoSomething()
Set o = Nothing
doStuff = str
End Function
作为一个非常快速的压力测试,我们将调用封装在一个非常简单的 VBScript 中,它简单地创建对象、循环调用方法、将对象设置为空,然后重复几次。然后我们在命令提示符下同时运行其中的四个。
我们所经历的是四个 COM+ 窗口停止死机,就好像它们以某种方式相互阻塞一样。根据输出的行为,看起来不同的窗口在沿途某处共享对象的实例:例如,输出出现在窗口之间的速度在窗口之间同步......所以两个窗口可能会以速度起泡,而另外两个每秒吐出一行(当他们吐出一行时,他们同时这样做)。
然后最终,所有四个窗口似乎都停止了 - 在组件服务中,我们看到调用时间开始攀升(因此从每次调用的几毫秒开始,它攀升至 30、40 秒)。有时 dllhost.exe 失败,我们会出现 COM Surrogate 错误对话框(此时窗口会随着新的 dllhost 生成而恢复)。
数据库上没有活动,所以我们已经排除了数据库层的阻塞。通过将 COM+ 组件设置为“事务:禁用”,我们似乎取得了更好的结果,但挂起并没有消失。而不是new,我们将尝试使用CreateObject 创建COM 对象,看看它做了什么(如果有的话)。一旦在 COM+ 和 VBScript 层完成,对象就会设置为 Nothing。
值得注意的是,如果直接从 VBScript(绕过 COM+)调用 3rd 方库,则不会出现任何问题。因此,这似乎与 COM+ 与 COM 对象交互的方式有关,但除了在组件服务中的对象属性下摆弄不同的设置之外,不确定还发生了什么。
关于导致这种情况的幕后原因有什么建议吗?还是要调整的设置?
额外信息
回答中的问题:
- 未使用全局变量(根据http://support.microsoft.com/kb/815053)
- 无人值守执行和内存保留设置正确(根据http://support.microsoft.com/kb/264957)
- 由于对象是 VB COM+ 对象,它正在运行 STA,因此无法配置对象池
进一步的工作...... 看起来这是 COM+ 或 COM 深处某处的同步问题。在我们的测试脚本中,如果我们在每次迭代中添加 10-50ms 的随机延迟,问题就会消失。如果我们有一个固定的延迟,我们锁定。一些谷歌搜索似乎表明在带有 STA 的重负载 COM+ 上可能是一个问题,即documented here on an MS blog。回到 Server 2000 机器或 Server 2003 SP1 机器会很好:这可能是接下来要看的东西......
【问题讨论】: