如何禁用默认的 asp net core config change watcher?

Posted

技术标签:

【中文标题】如何禁用默认的 asp net core config change watcher?【英文标题】:How can I disable the defaul aspnet core config change watcher? 【发布时间】:2019-10-15 01:46:03 【问题描述】:

我有一个在 Docker 容器中运行的 ASPNET 核心应用程序。我目前无法启动超过 64 个容器 (initially described here) 我创建的图像。

通过交互式运行容器,我在启动阶段发现了这个错误。

未处理的异常:System.IO.IOException:已达到配置的 inotify 实例数量的用户限制 (128)。

在 System.IO.FileSystemWatcher.StartRaisingEvents() 在 System.IO.FileSystemWatcher.StartRaisingEventsIfNotDisposed() 在 System.IO.FileSystemWatcher.set_EnableRaisingEvents(布尔值) 在 Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.TryEnableFileSystemWatcher() 在 Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.CreateFileChangeToken(字符串过滤器) 在 Microsoft.Extensions.FileProviders.PhysicalFileProvider.Watch(字符串过滤器) 在 Microsoft.Extensions.Configuration.FileConfigurationProvider.<.ctor>b__0_0()

在 Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1 changeTokenProducer, Action changeTokenConsumer) 在 Microsoft.Extensions.Configuration.FileConfigurationProvider..ctor(FileConfigurationSource 源) 在 Microsoft.Extensions.Configuration.Json.JsonConfigurationSource.Build(IConfigurationBuilder 生成器) 在 Microsoft.Extensions.Configuration.ConfigurationBuilder.Build() 在

Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors) 在 Microsoft.AspNetCore.Hosting.WebHostBuilder.Build() 在 /src/MyProjectName/Program.cs:line 10 中的 MyProjectName.Program.Main(String[] args) 处

Program.cs只有默认内容

 1 using Microsoft.AspNetCore;
 2 using Microsoft.AspNetCore.Hosting;
 3
 4 namespace CmcIiiCgiSim
 5 
 6    public class Program
 7    
 8        public static void Main(string[] args)
 9        
10            CreateWebHostBuilder(args).Build().Run();
11        
12
13        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
14            WebHost.CreateDefaultBuilder(args)
15                .UseStartup<Startup>();
16     
17 

监视配置更改似乎是 ASP 或任何 ASPNET 核心应用程序的默认设置 (see MS documentation)

我的问题是:如何在 settings 中为 existing 配置文件禁用此选项? 希望这也会禁用文件系统观察程序并消除错误。

我发现了很多示例,这些示例说明了如何以编程方式为其他设置文件完成。但在我的情况下,配置不会改变,我宁愿拥有一个不限于 64 个容器的图像。

【问题讨论】:

默认观察的唯一配置是 JSON(appsettings.jsonappsettings.environment.json)。包含该配置的方法有一个参数来启用或不启用重新加载。 我从这条评论中了解到,在配置中确实有 no 方法可以做到这一点。对吗? 你从哪里得到的?将 reload 设置为 false,这会禁用 watcher。 怎么样?我在这里完全傻了? 【参考方案1】:

默认构建器非常固执己见,并在已设置重新加载的情况下加载 appsettings。无法替换默认构建器中设置的配置。从 .NET Core 3.1.7 开始,这是 CreateDefaultBuilder 方法,其标志已更改以停止重新加载。我已经使用此配置运行了一个服务器,并确认没有创建 FileSystemWatchers。

    public static IHostBuilder CreateDefaultBuilder(string[] args)
        
            HostBuilder hostBuilder = new HostBuilder();
            hostBuilder.UseContentRoot(Directory.GetCurrentDirectory());
            hostBuilder.ConfigureHostConfiguration((Action<IConfigurationBuilder>) (config =>
            
                config.AddEnvironmentVariables("DOTNET_");
                config.AddCommandLine(args);
            ));
            hostBuilder.ConfigureAppConfiguration((hostingContext, config) =>
                
                    IHostEnvironment hostingEnvironment = hostingContext.HostingEnvironment;
                    config.AddJsonFile("appsettings.json", true, false)
                        .AddJsonFile("appsettings." + hostingEnvironment.EnvironmentName + ".json", true, false);
                    if (hostingEnvironment.IsDevelopment() &&
                        !string.IsNullOrEmpty(hostingEnvironment.ApplicationName))
                    
                        Assembly assembly = Assembly.Load(new AssemblyName(hostingEnvironment.ApplicationName));
                        if (assembly != null)
                            config.AddUserSecrets(assembly, true);
                    

                    config.AddEnvironmentVariables();
                    config.AddCommandLine(args);
                )
                .ConfigureLogging((hostingContext, logging) =>
                
                    int num = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 1 : 0;
                    if (num != 0)
                        logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);
                    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                    logging.AddConsole();
                    logging.AddDebug();
                    logging.AddEventSourceLogger();
                    if (num == 0)
                        return;
                    logging.AddEventLog();
                )
                .UseDefaultServiceProvider((Action<HostBuilderContext, ServiceProviderOptions>) ((context, options) =>
                
                    bool flag = context.HostingEnvironment.IsDevelopment();
                    options.ValidateScopes = flag;
                    options.ValidateOnBuild = flag;
                ));
            return hostBuilder;
        

其中的关键部分是对AddJsonFile 的调用。第三个参数作为false 传递,禁用文件系统观察器。

【讨论】:

【参考方案2】:

我已经设法使用带有以下 sn-p 的默认构建器禁用监视 json 文件(在 linux 上):


IWebHostBuilder builder = WebHost.CreateDefaultBuilder();

builder.ConfigureAppConfiguration((context, config) =>

    foreach (var s in config.Sources)
    
        if (s is FileConfigurationSource)
            ((FileConfigurationSource)s).ReloadOnChange = false;
    
);

现在系统不再用尽 inotify 句柄了。

【讨论】:

这会通知应用程序有关配置所在的根文件夹中的任何更改。但由于某种原因,它还会通知所有子目录中的任何更改。我发现 Filewatcher 有一些字符串分配,但不知道为什么,因为我没有在任何地方使用它。事实证明,它触发非常频繁,因为它是由 root/Logs/... 中的更改触发的,并且创建的 FileSystemWatcher 具有 IncludeSubdirectories = true;默认情况下,每次记录某些内容时,它都会将更改的日志文件的路径与配置文件进行比较。无论如何,这个解决方案解决了它。

以上是关于如何禁用默认的 asp net core config change watcher?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core(.NET 6、VS 2022)中禁用浏览器链接

asp.net core 中优雅的进行响应包装

如何在 ASP.NET core rc2 中禁用浏览器缓存?

我如何在登录 asp.net core razor 之前显示加载图标或禁用按钮

如何在 ASP.NET Core 生产服务器上禁用“尝试重新连接到服务器”消息

如何在 ASP.NET Core 生产服务器上禁用“尝试重新连接到服务器”消息