我有三个需要运行的核心 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 的好处,而无需以这种方式单独的应用程序?
考虑更改设置所需的代码更改,因此只有三个应用程序,并且这些应用程序要成为客户端感知是相当令人生畏和粗暴的。
- 将 {client} 添加到每个 MVC 路由的根目录(一个应用程序不是 MVC,所以会有所不同)
- 使用 {client} 搜索和加载存储在磁盘其他位置的配置文件。也许是 json 格式之类的。
- 在每个请求上,确保 {client} 没有更改,如果有,请清除所有会话和应用程序变量。取消用户身份验证以防止出现安全问题。
我不是在寻找任何人为我下定决心,但如果有人以前遇到过类似的问题,很高兴听到他们的消息。或者也许会达成共识,我完全走错了路,需要更改我的代码和设置。我认为关于这些问题的任何形式的反馈都会很有用,当然也值得赞赏。