0

我有三个需要运行的核心 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

“当前”目录是当前使用的版本的符号链接。

这种设置有一些优点

  • .NET 会话、应用程序和身份验证信息的自动隔离。任何跨应用程序污染或安全问题的可能性为零(例如,客户端 1 更改 URL 以查看客户端 2)。
  • 自动 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 回答 1

0

感谢@airmanx86 为我指明了多租户的正确方向。

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

花了几天的努力才真正理解这一点,并对其进行设置并重构我的代码以使其更加灵活,但结果令人惊叹。之前,如果我使用curl循环为每个客户端点击一个非常简单的“调试”页面,则启动时间只有几秒钟,大约 100 MB 的内存使用量,当我点击所有客户端时,第一个加载的客户端被换出内存。

现在,我运行相同的curl循环,几乎可以瞬间达到 100 多个应用程序,并且我的工作进程 RAM 使用量约为 150 MB。我喜出望外!

是时候让我跑步而不是走路了,将我的其他应用程序转换为真正的多租户。

于 2012-04-12T18:50:00.033 回答