如何禁用默认的 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.json
和 appsettings.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 rc2 中禁用浏览器缓存?
我如何在登录 asp.net core razor 之前显示加载图标或禁用按钮