在 dotnet core 中读取 json 文件时出错“已达到配置的 inotify 实例数量的用户限制 (128)" [英] Error while reading json file in dotnet core "the configured user limit (128) on the number of inotify instances has been reached"

查看:39
本文介绍了在 dotnet core 中读取 json 文件时出错“已达到配置的 inotify 实例数量的用户限制 (128)"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个控制台应用程序(在 dot net core 1.1 中),它在 cron 调度程序中每 1 分钟安排一次.在应用程序内部有对配置文件的调用.我附上下面的代码.

public static T GetAppConfig(string key, T defaultValue = default(T)){T 值 = 默认值(T);logger.Debug($"读取应用配置{key}");尝试{var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");var builder = new ConfigurationBuilder().AddJsonFile($"appsettings.json", true, true).AddJsonFile($"appsettings.{environmentName}.json", true, true).AddEnvironmentVariables();var 配置 = builder.Build();T setting = (T)Convert.ChangeType(configuration[key], typeof(T));值 = 设置;如果(设置 == 空)值 = 默认值;}捕获(异常前){logger.Warn(ex, $"读取应用程序键{key}默认值{defaultValue}应用时发生异常.");值 = 默认值;}返回值;}

运行应用程序一段时间后,此错误出现在我的日志文件中已达到配置的 inotify 实例数量的用户限制 (128)".请找到完整的堆栈跟踪.

<前>读取应用程序密钥 DeviceId 默认值时发生异常.System.IO.IOException:已达到配置的 inotify 实例数量的用户限制 (128).在 System.IO.FileSystemWatcher.StartRaisingEvents()在 System.IO.FileSystemWatcher.StartRaisingEventsIfNotDisposed()在 Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.CreateFileChangeToken(字符串过滤器)在 Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1 changeTokenProducer, Action changeTokenConsumer)在 Microsoft.Extensions.Configuration.Json.JsonConfigurationSource.Build(IConfigurationBuilder builder)在 Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()在 app.Shared.Utilities.GetAppConfig[T](String key, T defaultValue) in/var/app/source/app/app.Shared/Utilities.cs:line 33在 System.IO.FileSystemWatcher.StartRaisingEvents()在 System.IO.FileSystemWatcher.StartRaisingEventsIfNotDisposed()在 Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.CreateFileChangeToken(字符串过滤器)在 Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1 changeTokenProducer, Action changeTokenConsumer)在 Microsoft.Extensions.Configuration.Json.JsonConfigurationSource.Build(IConfigurationBuilder builder)在 Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()在 app.Shared.Utilities.GetAppConfig[T](String key, T defaultValue) in/var/app/source/app/app.Shared/Utilities.cs:line 33

请告诉我这段代码有什么问题.

解决方案

var builder = new ConfigurationBuilder().AddJsonFile($"appsettings.json", true, true);

每次访问设置时,您都在创建文件观察器.第三个参数是 reloadOnChange.

你必须确保,

var 配置 = builder.Build()

仅在您的应用程序中调用一次并将其存储在您可以访问它的位置(最好是避免静态字段).

或者只是禁用文件观察器.

 var builder = new ConfigurationBuilder().AddJsonFile($"appsettings.json", true, false);

或更清洁:

var builder = new ConfigurationBuilder().AddJsonFile($"appsettings.json", optional: true, reloadOnChange: false);

最好的方法是将其抽象到接口后面并使用依赖注入.

公共接口 IConfigurationManager{T GetAppConfig(字符串键,T defaultValue = default(T));}公共类 ConfigurationManager : IConfigurationManager{私有只读 IConfigurationRoot 配置;公共配置管理器(IConfigurationRoot 配置)=>this.config ??throw new ArgumentNullException(nameof(config));public T GetAppConfig(字符串键,T defaultValue = default(T)){T setting = (T)Convert.ChangeType(configuration[key], typeof(T));值 = 设置;如果(设置 == 空)值 = 默认值;}}

然后实例化并注册

services.AddSingleton(new ConfigurationManager(this.Configuration));

并通过构造函数将其注入您的服务

I have an console application (in dot net core 1.1) which is scheduled in cron scheduler for every 1 min. Inside the application there is call to configuration file. I'm attaching the code below.

public static T GetAppConfig<T>(string key, T defaultValue = default(T))
{

    T value = default(T);
    logger.Debug($"Reading App Config {key}");
    try
    {
        var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
        var builder = new ConfigurationBuilder()
            .AddJsonFile($"appsettings.json", true, true)
            .AddJsonFile($"appsettings.{environmentName}.json", true, true)
            .AddEnvironmentVariables();
        var configuration = builder.Build();
        T setting = (T)Convert.ChangeType(configuration[key], typeof(T));
        value = setting;
        if (setting == null)
            value = defaultValue;
    }
    catch (Exception ex)
    {
        logger.Warn(ex, $"An exception occured reading app key {key} default value {defaultValue} applied.");
        value = defaultValue;
    }
    return value;
}

After running the application for sometime, this error is getting in my log file "the configured user limit (128) on the number of inotify instances has been reached". Please find the full stack trace.

An exception occured reading app key DeviceId default value  applied.
System.IO.IOException: The configured user limit (128) on the number of inotify instances has been reached.
   at System.IO.FileSystemWatcher.StartRaisingEvents()
   at System.IO.FileSystemWatcher.StartRaisingEventsIfNotDisposed()
   at Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.CreateFileChangeToken(String filter)
   at Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1 changeTokenProducer, Action changeTokenConsumer)
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationSource.Build(IConfigurationBuilder builder)
   at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
   at app.Shared.Utilities.GetAppConfig[T](String key, T defaultValue) in /var/app/source/app/app.Shared/Utilities.cs:line 33
   at System.IO.FileSystemWatcher.StartRaisingEvents()
   at System.IO.FileSystemWatcher.StartRaisingEventsIfNotDisposed()
   at Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.CreateFileChangeToken(String filter)
   at Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1 changeTokenProducer, Action changeTokenConsumer)
   at Microsoft.Extensions.Configuration.Json.JsonConfigurationSource.Build(IConfigurationBuilder builder)
   at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
   at app.Shared.Utilities.GetAppConfig[T](String key, T defaultValue) in /var/app/source/app/app.Shared/Utilities.cs:line 33

Please tell me what is wrong with this code.

解决方案

var builder = new ConfigurationBuilder()
        .AddJsonFile($"appsettings.json", true, true);

You are creating file watchers, every time you access an setting. The 3rd parameter is reloadOnChange.

You have to make sure,

var configuration = builder.Build()

is only called once in your application and store it in a place where you can access it (preferably AVOID static fields for it).

Or just disable the file watcher.

  var builder = new ConfigurationBuilder()
        .AddJsonFile($"appsettings.json", true, false);

or cleaner:

var builder = new ConfigurationBuilder()
        .AddJsonFile($"appsettings.json", optional: true, reloadOnChange: false);

Best way is to abstract that behind an interface and use dependency injection.

public interface IConfigurationManager
{
    T GetAppConfig<T>(string key, T defaultValue = default(T));
}

public class ConfigurationManager : IConfigurationManager
{
    private readonly IConfigurationRoot config;

    public ConfigurationManager(IConfigurationRoot config)
        => this.config ?? throw new ArgumentNullException(nameof(config));

    public T GetAppConfig<T>(string key, T defaultValue = default(T))
    {
        T setting = (T)Convert.ChangeType(configuration[key], typeof(T));
        value = setting;
        if (setting == null)
            value = defaultValue;
    }
}

Then instantiate and register it

services.AddSingleton<IConfigurationManager>(new ConfigurationManager(this.Configuration));

and inject it into your services via constructor

这篇关于在 dotnet core 中读取 json 文件时出错“已达到配置的 inotify 实例数量的用户限制 (128)"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆