一个简单的ASP.NET状态服务器故障转移方案





5.00/5 (9投票s)
为使用ASP.NET状态服务器的Web应用程序设置故障转移和负载均衡支持

引言
当设置Web应用程序以使用状态服务器时,一个常见的问题是“如果状态服务器发生故障怎么办?”,答案是Web应用程序会失败。
本文提出了一种故障转移解决方案,使得如果一个状态服务器出现故障,Web应用程序将切换到另一个状态服务器。此外,该解决方案通过在可用状态服务器之间分配请求来执行状态服务器负载均衡。
概述
提出的故障转移系统监视指定的状态服务器列表,以确定哪些服务器正在运行;然后Web应用程序可以决定使用哪个服务器。监视状态服务器的过程成本很高,因此它由一个专用的外部服务处理。该服务在状态服务器上线或离线时通知Web应用程序(和其他Web应用程序)。该过程如下所示。

工作原理
故障转移系统包括两部分。
第一部分是监视服务,它通过不断地连接和断开服务器来轮询给定服务器列表的状态。如果服务器的可用性发生任何变化,例如,一个以前不可用的服务器变得可用,反之亦然;则会更新一个或多个状态文件以反映这种变化。状态文件包含有关正在使用的状态服务器及其在线状态的信息。ASP.NET应用程序可以检测到这些状态文件的更改并作出相应反应。
监视服务有一个可配置的时间段,在此期间,在线的受监视服务器必须保持在线,服务才会更新状态文件中该服务器状态的变化。这有助于减少与连续上线和离线的服务器的连接——即所谓的闪烁服务器现象。该时间段的长度由ServerWarmUpTime配置设置确定。
需要注意的是,监视服务可以检测其他类型的服务器的可用性,而不仅仅是ASP.NET状态服务器,因此也可以用于其他目的。
第二部分包括Web应用程序中的配置设置和代码,该代码扩展了Martin Bartimolew关于状态服务器分区和负载均衡的极佳系列文章。Web应用程序的配置方式是将配置文件扩展到外部状态文件。对状态文件的更改会导致应用程序配置设置被重新读取并更新为新值。因此,Web应用程序始终拥有最新的服务器可用性信息,并使用该信息将请求分发到可用的状态服务器——从而实现负载均衡和故障转移支持。
例如,如果正在使用五个状态服务器并且它们都正在运行,状态文件将指示这五个服务器是可用的;然后Web应用程序将状态服务器请求均匀地分发到这五个服务器。如果其中两个状态服务器突然出现故障,状态文件将被更新为指示只有三个状态服务器可用;然后Web应用程序将状态服务器请求重新分发到这三个服务器。总的效果是,在状态服务器停机期间,用户将能够继续使用该应用程序。某些会话将会丢失,但与整个应用程序长时间不可用相比,这只是一个小麻烦。
要使用这种负载均衡、支持故障转移的设置,Web应用程序需要在App_Code文件夹中进行一些配置更改和添加两个代码文件;即ServerListSectionHandler.cs和PartitionResolver.cs。ServerListSectionHandler.cs允许将状态文件作为应用程序配置的一部分进行读取。PartitionResolver.cs包含一个自定义的状态服务器分区解析器类,该类决定连接到哪个状态服务器。该类还尝试将用户固定到特定的状态服务器,以便状态文件的更改只会影响其会话存储在发生故障的服务器上的用户。
Using the Code
设置服务器监视服务
- 下载源文件。
- 在Visual Studio中打开
ServerMonitor
解决方案。该解决方案包含两个项目。一个项目将服务作为控制台应用程序运行,另一个项目将其作为Windows服务运行。
ServerMonitorService
项目编译为Windows服务,并可以使用包含的install_service.bat和uninstall_service.bat文件进行安装和卸载。ConsoleServerMonitor
项目将服务作为控制台应用程序运行,这样更容易测试和调试。两个项目共享相同的源代码,功能相同。 - 打开项目的应用程序配置文件。
- 在
Servers
部分,指定您要使用的状态服务器,如下所示<Servers> <!-- List of servers to poll --> <add key="Server1" value="localhost:42424" /> <add key="Server2" value="appserver1:42424" /> <add key="Server3" value="72.27.255.9:42424" /> </Servers>
- 在
StatusFilePaths
部分,添加状态文件的完整文件路径名。
该文件应位于包含您的Web应用程序的文件夹或其子文件夹中。您可以添加多个路径,如果您想通知多个Web应用程序,如下所示
<StatusFilePaths> <!-- List of file paths where status files are saved/updated --> <add key="Web1" value="C:\Inetpub\wwwroot\MyWeb1\server_status.config.xml"/> <add key="Web2" value="C:\Inetpub\wwwroot\SuperWeb2\server_status.config.xml"/> </StatusFilePaths>
- 构建项目。
- 如果您构建了
ServerMonitorService
项目,请导航到输出文件夹并运行install_service.bat以安装服务。 - 如果您构建并安装了Windows服务,可以在服务列表中启动Server Monitoring Service。如果您构建了控制台服务器,请运行ConsoleServerMonitor.exe或直接从Visual Studio开始调试。
- 请注意,状态文件将在指定文件夹中创建。
配置您的Web应用程序
- 在Visual Studio中打开您的Web应用程序。
- 如果您的应用程序没有App_Code ASP.NET文件夹,请添加一个。
- 将SampleWeb\App_Code文件夹中的PartitionResolver.cs和ServerListSectionHandler.cs复制到您的Web应用程序的App_Code文件夹中。
- 打开项目的Web配置文件。(如果您的应用程序没有Web配置文件,请添加一个新的)
- 在
configSections
集合中添加一个新的SessionStateServers
节元素,如下所示<configSections> <section name="SessionStateServers" type="ServerListSectionHandler" restartOnExternalChanges="false"/> </configSections>
- 如下所示,配置新添加的
SessionStateServers
节从外部文件读取<SessionStateServers configSource="server_status.config.xml"/>
(如果状态文件具有不同的文件名,请指定该文件名。) - 在
system.web
元素中,如下所示配置应用程序使用自定义分区解析器
<system.web> <sessionState mode="StateServer" partitionResolverType="PartitionResolver"/> ...
- 您的Web应用程序现在已设置为使用状态服务器故障转移系统。
关注点
我最初希望监视服务更新一个由多个Web应用程序共享的单个状态文件。那个计划不起作用,因为ASP.NET只适用于位于应用程序文件夹或其子文件夹中的外部配置文件。由于这个限制,不同的Web应用程序无法共享一个外部配置文件。
在web.config文件中,不需要将节元素的restartOnExternalChanges
属性设置为true
。将此属性设置为true
会导致Web应用程序在每次更新外部config文件时重新启动,这会导致Application
对象中存储的任何数据丢失。
如果该属性的值设置为false
,Web应用程序仍然会读取外部config文件中的最新数据,而不会重新启动应用程序。
状态文件的根元素的名称由监视服务的配置的StatusXMLRootTag
设置决定。
该名称必须与您添加到Web应用程序web.config文件的新节的名称匹配。该名称也必须在状态服务器分区解析器类(PartitionResolver.cs)中指定。
历史
- 2010年2月2日:首次发布