.NET 2服务组件(COM+)效率问题
本文关键字:COM+ 效率 问题 组件 服务 服务组 NET | 更新日期: 2023-09-27 17:58:56
这是我第一次创建。NET服务组件(COM+),在可伸缩性方面我遇到了一些问题。我已经对它进行了多达4000名用户的压力测试,但它仍然无法超过原始解决方案的性能。
它背后的基本思想是COM+在内存中保存一个包含字典的静态类,ASP页面调用该组件从字典中检索对象。字典里任何时候都有6000到12000个词条。
静态字典类如下所示:
public class Menus
{
public static Dictionary<string, MenuPage> MenuPages { get; set; }
}
向COM+公开的ServicedComponent类如下所示:
public class MenuManager : ServicedComponent
{
public MenuPage GetMenuPage(string PubCode, int Page)
{
MenuPage ReturnMenuPage;
Menus.MenuPages.TryGetValue(String.Concat(PubCode, Page.ToString()), out ReturnMenuPage);
return ReturnMenuPage;
}
}
COM+组件是从ASP页面调用的,比如…
Dim MenuManager : Set MenuManager = Server.CreateObject("MenuManager.MenuManager")
Dim MenuPage : Set MenuPage = MenuManager.GetMenuPage(UCase(sBook), iPage)
If (Not MenuPage Is Nothing) Then
//Retrieve values from class
Else
Set MenuPage = Nothing
Set MenuManager = Nothing
Throw404()
End If
Set MenuPage = Nothing
Set MenuManager = Nothing
COM+作为本地服务运行,AssemblyInfo中设置了以下选项:
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(false, AccessChecksLevel = AccessChecksLevelOption.ApplicationComponent)]
在单个测试实例下,当前解决方案需要0.03秒才能解析,新组件需要0.0003秒才能解析。然而,在负载下,它的性能实际上比原来的差。
我真正需要知道的是,我到底做错了什么,以至于在缩放时性能没有像预期的那样提高!?!?!
如有任何帮助,我们将不胜感激。
问题
我认为您看到的是使用服务器应用程序并返回的副产品。NET类。当您调用MenuManager
时,您正在进行进程外调用以返回MenuPage
对象。但是MenuPage
是通过引用返回的——对象在服务器应用程序进程中的内存中。为了验证这是真的,在MenuPage
getter方法之一中放置一些代码:
System.Diagnostics.Trace.TraceInformation(
System.Diagnostics.Process.GetCurrentProcess().Id.ToString()
);
您将看到进程ID是服务器应用程序的进程ID。
对于另一个测试,在返回MenuPage
之后放置睡眠,然后在睡眠之后检索MenuPage
的属性。在睡眠结束之前,请手动关闭COM+资源管理器中的服务器应用程序。您将收到一条消息,说明远程服务器计算机不存在或不可用。
因此,对于每个页面,您都将进行一个远程进程外调用来检索MenuPage
,再加上对您在MenuPage
上调用的每个属性的另一个进程外调用。
改进
您是否出于安全目的使用服务器应用程序?如果没有,请尝试转到库应用程序,这样调用就不会脱离进程。这可能会有所帮助。
我还将更改我的组件,使其不返回MenuPage
,而是返回可以按值(string、int等)封送的基元类型(如果可能的话)
最后,我将使用JIT在方法返回后立即停用对象。由于您在服务器进程中处于停用状态,因此不需要从ASP页面调用Dispose。
我不确定你的MenuPage
类是什么样子的,但代码看起来像:
[JustInTimeActivation(true)]
public class MenuManager : ServicedComponent
{
public void GetMenuPageInfo(string PubCode,
int Page,
out string menuPageUrl,
out int menuCode)
{
ContextUtil.DeactivateOnReturn = true;
menuPageUrl = null;
menuCode = 0;
MenuPage ReturnMenuPage;
if (Menus.MenuPages.TryGetValue(
String.Concat(PubCode, Page.ToString()), out ReturnMenuPage))
{
menuPageUrl = ReturnMenuPage.MenuPageUrl;
menuCode = ReturnMenuPage.Code;
}
}
}
希望这能提高可扩展性。
阅读
查看企业服务设计注意事项:
- 只有在需要时才使用企业服务
- 如果可能,请使用库应用程序
- 考虑DLL和类的关系
- 只有在需要时才使用分布式事务
- 使用对象池来减少对象创建开销
- 基于调用模式设计池对象
- 使用显式接口
- 设计不那么健谈的界面
- 设计无状态组件
了解中的企业服务(COM+)。NET是一篇关于COM+的好文章。
尝试用以下属性标记您的COM+
[JustInTimeActivation]
和
[Transaction(TransactionOption.Disabled)]
我认为如果禁用COM+事务,对COM+的调用可以更快地工作。此外,我可以建议您将日志记录添加到服务器和客户端部分。之后,您可以分析COM+调用或Dictionary中性能较差的地方。TryGetValue
提高企业服务性能
根据我的经验,您应该将COM设置为"在与客户端相同的进程中"运行。它是组件服务控制台中的设置之一。速度至少快一千倍。