有时,在 Web 浏览器或客户端应用程序中,我会看到 500 内部服务器错误,该错误似乎来自 IIS 本身读取其
web.config
文件。我看到发生这种情况的服务器正在运行带有 IIS 10.0.17763.1 的 Windows Server 2019。
Microsoft.Web.Administration.ServerManager
以及一些作为自己的 ASP.NET 进程运行的服务。
ServerManager
会导致这种情况吗?还是服务器上的其他恶意进程偶尔会锁定文件?
如果确实导致这种情况,是否有其他方法可以更新 IIS 重写规则而不触发停机?也许编写一个新的
web.config
文件而不“锁定”现有文件,然后交换活动配置?
using (ServerManager serverManager = new ServerManager())
{
Configuration config = serverManager.GetWebConfiguration("Softdial");
ConfigurationSection rulesSection = config.GetSection("system.webServer/rewrite/rules");
ConfigurationElementCollection rulesCollection = rulesSection.GetCollection();
ConfigurationElement ruleElement = rulesCollection.CreateElement("rule");
ruleElement["name"] = "My Rule";
ruleElement["stopProcessing"] = "true";
ConfigurationElement matchElement = ruleElement.GetChildElement("match");
matchElement["url"] = @"example/(.*)";
ConfigurationElement actionElement = ruleElement.GetChildElement("action");
actionElement["type"] = @"Rewrite";
actionElement["url"] = "http://localhost:8999/{R:1}";
actionElement["logRewrittenUrl"] = "true";
rulesCollection.Add(ruleElement);
serverManager.CommitChanges();
}
Server Error in '/' Application.
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: An error occurred loading a configuration file: The process cannot access the file 'C:\MyWebSite\web.config' because it is being used by another process.
Source Error:
[No relevant source lines]
Source File: C:\MyWebSite\web.config Line: 0
Click here to show additional error information:
Exception Details: System.IO.IOException: The process cannot access the file 'C:\MyWebSite\web.config' because it is being used by another process.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[IOException: The process cannot access the file 'C:\MyWebSite\web.config' because it is being used by another process.]
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +935
System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) +1242
System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) +126
System.Configuration.Internal.InternalConfigHost.StaticOpenStreamForRead(String streamName) +102
System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.OpenStreamForRead(String streamName, Boolean assertPermissions) +149
System.Configuration.BaseConfigurationRecord.InitConfigFromFile() +470
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.8.4718.0
难道
CommitChanges
打开文件进行写入但不允许后续读取?考虑到异常消息,无需查看其源代码,您就可以假设它是这样做的。
当
web.config
被锁定以进行读取并且请求到来时,IIS 似乎只是抛出异常。
如果确实导致这种情况,是否有其他方法可以更新 IIS 重写规则而不触发停机?
是的,有。有几个选项是从蓝绿部署的理念演变而来的。
选项 1. 在反向代理后面至少有两台服务器(也适用于两台以上)。禁用第一个,以便流量流向第二个。更新第一个。将流量切换到第一个。更新第二个。启用两者的流量。
这样做的一个缺点是你需要在短时间内缩小流量。
选项 2。(不需要多个服务器)在两个单独的文件夹中拥有应用程序的两个相同的物理副本。配置 IIS 以使用第一个。更新第二个。将 IIS 配置切换为使用第二个。更新第一个。
这样做的一个优点是,在 IIS 网站中切换应用程序文件的路径是即时的,除了重新启动应用程序之外不会导致任何问题。
根据您的部署方式,这两个选项之一可能更适合您。