使用共享ASP.NET应用程序减少IIS设置中的内存开销

时间:2012-04-11 09:44:36

标签: asp.net performance iis-7.5 windows-server-2008-r2

我需要运行三个核心ASP.NET应用程序。我正在设置两台带有镜像IIS 7.5配置的Windows Server 2008 R2服务器,然后设置一个负载均衡器来引导流量,另一台服务器作为状态服务器。这都是设置和工作(尚未投入生产)。

我们有大约120个客户端(并且还在增长),现在我的设置是每个客户端从IIS根目录下获取自己的虚拟目录(作为.NET应用程序)。虚拟目录应用程序指向磁盘上的目录,其中存在自己的web.config以存储连接字符串和一些核心应用程序参数等内容。然后,每个客户端的应用程序都有一个虚拟目录应用程序,用于三个核心ASP.NET应用程序中的每一个。所以像这样:

/ (IIS root)
    /client1    => c:\inetpub\clients\client1
        /app1   => c:\inetpub\applications\app1\current
        /app2   => c:\inetpub\applications\app2\current
        /app3   => c:\inetpub\applications\app3\current
    /client2    => c:\inetpub\clients\client2
        /app1   => c:\inetpub\applications\app1\current
        /app2   => c:\inetpub\applications\app2\current
        /app3   => c:\inetpub\applications\app3\current

'current'目录是当前正在使用的版本的符号链接。

此设置有一些优点

  • 自动隔离.NET会话,应用程序和身份验证信息。任何跨应用程序污染或安全问题的可能性为零(例如,client1更改URL以查看client2)。
  • 自动web.config继承,因此无需在磁盘上搜索每个客户端的配置文件。设置“正常工作”。
  • 每个客户端都可以(并且)配置为拥有自己的应用程序池,这样一个客户端就性能而言不会给其他任何人造成问题。

缺点:

  • 每个客户端有一个应用程序池,会产生大量内存开销
  • 每个应用程序实例(例如/ client1 / app1,/ client1 / app2,/ client2 / app1,...)都是由ASP.NET单独编译的,即使只有三个“真实”应用程序
  • 有应用程序池预热时间开销。如果一个客户端暂时没有访问服务器,则第一次访问必须等待其工作进程启动。我通过以32位模式运行所有池来缓解这个问题。

我最大的问题是内存消耗。如果我使用curl遍历并命中每个客户端的每个应用程序,则每个工作进程使用大约100 MB的RAM。这意味着我需要16 GB的服务器RAM才能安全运行。考虑到应用程序本身确实不是那么大或非常复杂,这是疯了。每个工作进程的内存细分大致为:专用字节70 MB,工作集85 MB,WS共享:32 MB。内存是一个问题,因为这些是云服务器,其成本与RAM使用率直接相关。即使不是成本,但是让内存像这样浪费似乎仍然是疯狂的。

我的第一个问题是:我可以做些什么来配置IIS或ASP.NET以不单独编译每个应用程序实例,但是要意识到这三个应用程序实际上是完全相同的代码,因此希望减少启动时间甚至内存使用?如果我做客户*应用程序*两个服务器,那就是在磁盘上编译的720'应用程序。

第二个问题是最佳实践之一。我的设置是正义的(因为没有更好的词)?为了简化代码和安全性,RAM浪费是否值得?有没有其他方法可以实现web.config继承和session / application / forms auth的好处,而不需要以这种方式使用单独的应用程序?

考虑更改设置所需的代码更改,因此只有三个应用程序,并且这些应用程序变得客户端感知是相当艰巨和粗略的。

  1. 将{client}添加到每个MVC路由的根目录(一个应用程序不是MVC,因此不同)
  2. 使用{client}搜索并加载存储在磁盘上其他位置的配置文件。也许用json格式或其他东西。
  3. 在每个请求上,确保{client}未更改,如果有,请清除所有会话和应用程序变量。取消授权用户以防止出现安全问题。
  4. 我不是在寻找任何人为我下定决心,但如果有人以前遇到类似的问题,那么听到他们会很高兴。或者可能会达成共识,我完全走错了路,需要更改我的代码和设置。我认为对这些问题的任何反馈都是有用的,当然也很感激。

1 个答案:

答案 0 :(得分:0)

感谢@ airmanx86指出我在多方租用的正确方向。

我发现以下两篇博客文章在此过程中非常有用:

http://blogs.planetcloud.co.uk/mygreatdiscovery/post/Simple-approach-to-multi-tenancy-in-ASPNET-MVC.aspx

http://blogs.planetcloud.co.uk/mygreatdiscovery/post/Simple-approach-to-multi-tenancy-in-ASPNET-MVC-Part-2.aspx

我花了几天时间努力才能真正理解这一点,并让它设置并重构我的代码以使其更灵活,但结果真是太棒了。之前,如果我使用curl循环为每个客户端点击一个非常简单的“调试”页面,那么有几秒的启动时间,大约100 MB的内存使用量,当我点击所有客户端时,第一个拥有加载被换掉内存。

现在,我运行相同的卷曲循环,它几乎是瞬间达到100多个应用程序,我的工作进程ram使用量大约为150 MB。我很高兴!

现在是时候让我跑步,而不是走路,将我的其他应用转换成真正的多租户。