我的 ASP.NET Core MVC 应用程序在对 MySQL 数据库(在 Ubuntu 14.04/16.04 上)运行某些查询后报告错误,并显示以下消息:
已达到 inotify 实例数量配置的用户限制(128)。
引发错误的原因是控制器打开了太多文件并超出了 iNotify 设置的限制(在 /proc/sys/fs/inotify/max_user_instances 中)。但当 ASP.NET 在每个 HTTP 请求上打开文件时,我感到很困惑;为什么它不能正确关闭文件?
我正在使用 Mysql.data.core 和 Mysql.data.entityframeworkcore 提供程序。
private static string classiferstring = "sports,outdoor,startup,pets,child,adult,elderly";
[AllowAnonymous]
[HttpGet]
public async Task<object> Classify([FromQuery] string classifyword)
{
string[] classifers = classiferstring.Split(',');
if (!classifers.Contains(classifyword))
{
return new
{
status = 0,
info = "WrongClassifier",
Data = ""
};
}
try
{
var predata = await (from d in _context.descriptor
join a in _context.combination on d.ID equals a.ID
select new ProductsVM
{
CREATETIME = a.CREATETIME,
ID = a.ID,
COMPANY = a.COMPANY,
NAME = a.NAME,
PRICE = a.PRICE,
TYPE = a.TYPE,
HEADPHOTO = a.HEADPHOTO,
REMARK = a.REMARK,
Tags = d.Tags,
Classifier = d.Classifier,
OriginName = d.OriginName,
Briefing = d.Briefing
}).ToListAsync();
var data = (from x in predata
where x.Classifier.Contains(classifyword.ToLower())
select x).ToList();
if(predata.Count<=0)
{
return new
{
status = 2,
info = "NoResult",
Data = ""
};
}else
{
return new
{
status = 1,
info = "Success",
Data = data
};
};
}
catch(Exception e)
{
return new
{
status = 0,
info = "Error",
Data = e.Message
};
}
}
仅在 try/catch 代码块中引发异常,而不是在调用操作后立即引发异常。
到目前为止,我发现的最佳解决方案是通过运行以下命令来增加
fs.inotify.max_user_instances
中的 /etc/sysctl.conf
:
echo fs.inotify.max_user_instances=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
来源:https://github.com/dotnet/aspnetcore/issues/8449#issuecomment-512275929
对于容器化环境(其中配置在容器的整个生命周期内不会更改)或在构建服务器上,缓解问题的方法是设置环境变量
DOTNET_HOSTBUILDER__RELOADCONFIGONCHANGE=false
这允许继续使用
Host.CreateDefaultBuilder
并防止服务创建不必要的inotify实例。
发生错误的原因是
reloadOnChange
导致访问appSetting.json
文件时出现问题。
已达到 inotify 实例数量配置的用户限制(128)
将
reloadOnChange
设置为 false
:
.AddJsonFile($"appsettings.json", optional: true, reloadOnChange: false);
注意:如果您还使用默认的
WebHost.CreateDefaultBuilder
,请注意其中的 reloadOnChange
也设置为 true
。
因此,从头开始配置您的主机可能会更安全 - 这是一个如何做到这一点的示例(微软的
WebHost.CreateDefaultBuilder
的副本,但没有FileWatcher
依赖项和IISIntegration
,因为您不需要Ubuntu 上的 IIS)。
我只需关闭一些 Visual Studio Code 窗口,尤其是在 Visual Studio Code 编辑器中打开的文件。
@dmitry-pavlov 是错误的,您可以使用默认构建器作为最后添加的构建器获胜 - 但这样做会使 appsettings.json 设置覆盖所有其他配置源、环境和命令行。请参阅 https://github.com/dotnet/AspNetCore.Docs/pull/22391,很快就会正式记录这一点。如果您不关心 appsettings.json 重新加载,请将其设置为
false
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddJsonFile("appsettings.json",
optional: true,
reloadOnChange: false);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
我通过 SWARM 在 Docker 容器中运行的应用程序遇到了这个问题。在主机上,系统 max_user_instances 设置为 128
cat /proc/sys/fs/inotify/max_user_instances
.
两个解决方案对我有用:
echo 256 | sudo tee /proc/sys/fs/inotify/max_user_instances
DOTNET_USE_POLLING_FILE_WATCHER=1
。在较新的服务器上,我正在使用此过程:
vim /etc/sysctl.conf
fs.inotify.max_user_instances=1024
sudo sysctl -p
我最近在 dot.net 5.0 上看到了这个问题。就我而言,这是由于使用此处找到的捆绑标签助手引起的:https://github.com/meziantou/Meziantou.AspNetCore.BundleTagHelpers。 似乎已知使用 asp-append-version 的标签助手会导致此问题,请参见此处 https://github.com/dotnet/runtime/issues/27272#issuecomment-525007303 .
对于那些不总是关注自己在做什么的人:当我在尝试启动同一服务的新实例时忘记了另一个终端中正在运行的同一服务的实例时,我遇到了此错误。