dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.72k stars 3.17k forks source link

asp.net core issue: "The configured user limit (128) on the number of inotify instances has been reached." #8301

Closed imadyTech closed 2 years ago

imadyTech commented 7 years ago

Describe what is not working as expected. I use Asp.net core (Microsoft.NETCore.App 1.1.0 + MySql.Data.EntityFrameworkCore) on both Ubuntu 14.04/16.04. The MVC works well but the database request failed after some times (around 100 queries). I was first blaming the Mysql and switched to Dapper, untill the bug was reported again after several dotnet restarts.

If you are seeing an exception, include the full exceptions details (message and stack trace).

Exception message:
The configured user limit (128) on the number of inotify instances has been reached.

Stack trace:
Unhandled Exception: 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 ZebaoIntra.Startup..ctor(IHostingEnvironment env)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.AspNetCore.Hosting.Internal.StartupLoader.LoadMethods(IServiceProvider services, Type startupType, String environmentName)
   at Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.<>c__DisplayClass1_0.<UseStartup>b__1(IServiceProvider sp)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureStartup()
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at ZebaoIntra.Program.Main(String[] args)
Aborted (core dumped)

Steps to reproduce

When using mysql, every query to the controller willl increase the value of "inotify instaces" (you may use "lsof -p dotnetpid |wc -l" command to check the value, and you may find the value increases after every query till the error is reported). ----------------------Project.json:---------------------- `{ "title": "ZebaoIntra", "dependencies": { "Microsoft.NETCore.App": { "version": "1.1.0", "type": "platform" }, "Microsoft.ApplicationInsights.AspNetCore": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.1", "Microsoft.AspNetCore.Routing": "1.0.1", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.1", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", "Microsoft.Extensions.Configuration.Json": "1.0.0", "Microsoft.Extensions.Logging": "1.1.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Extensions.Logging.Debug": "1.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0", "Microsoft.EntityFrameworkCore.Sqlite": "1.1.0", "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", "Microsoft.EntityFrameworkCore.Design": { "type": "build", "version": "1.0.0-preview2-final" }, "Microsoft.AspNetCore.Mvc.WebApiCompatShim": "1.0.1", "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0", "Microsoft.AspNetCore.StaticFiles": "1.0.0", "Swashbuckle.AspNetCore": "1.0.0-rc3", "ZBModels": "1.0.0-", "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", "Common": "1.0.0-", "MySql.Data": "7.0.7-m61", "MySql.Data.EntityFrameworkCore": "7.0.7-m61", "Dapper": "1.50.2" },

"tools": { "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final", "Microsoft.EntityFrameworkCore.Tools": { "version": "1.1.0-preview4-final", "imports": [ "portable-net45+win8+dnxcore50", "portable-net45+win8" ] } },

"frameworks": {
  "netcoreapp1.0": {
    "imports": [
      "dotnet5.6",
      "portable-net45+win8"
    ]
  }
},

"buildOptions": {
  "emitEntryPoint": true,
  "preserveCompilationContext": true,
  "copyToOutput": {
    "include": "appsettings.json"
  },
  "xmlDoc": true
},

"runtimeOptions": {
  "configProperties": {
    "System.GC.Server": true
  }
},

"publishOptions": {
  "include": [
    "wwwroot",
    "**/*.cshtml",
    "appsettings.json",
    "web.config"
  ]
},

"scripts": { "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] }, "userSecretsId": "aspnet-ZebaoAPI-20170329055116" } ----------MySQLContext ------------ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks;

using Microsoft.EntityFrameworkCore; using ZebaoIntra; using Microsoft.Extensions.Configuration; using MySQL.Data.EntityFrameworkCore.Extensions; using Microsoft.Extensions.DependencyInjection; using ZBModels;

namespace ZebaoIntra {

public class MySQLContext : DbContext
{
    public MySQLContext()
    {
    }

    public DbSet<ipn_insurance_combination> ipn_insurance_combination { get; set; }
    public DbSet<ipn_insurance_descriptor> ipn_insurance_descriptor { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var builder = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

        var configuration = builder.Build();

        //string connectionString = configuration.GetConnectionString("ZBCloudMysqlConnection");
        string connectionString = configuration.GetConnectionString("ZBLocalMysqlConnection");

        //2017-04-21 断开
        //optionsBuilder.UseMySQL(connectionString);
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<ipn_insurance_combination>()
            .HasKey(m => m.ID);
        builder.Entity<ipn_insurance_descriptor>()
            .HasKey(m => m.ID);
        base.OnModelCreating(builder);
        //Console.WriteLine("========== Model Created. ");
    }
}

} ---------------------Startup.cs---------------------- using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging;

using ZebaoIntra; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json.Serialization; MySQL.Data.EntityFrameworkCore.Extensions; using Microsoft.AspNetCore.Http; using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.SwaggerUI; using Microsoft.Extensions.PlatformAbstractions; using System.IO; using Microsoft.AspNet.Builder;

namespace ZebaoIntra { public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsEnvironment("Development"))
        {
            // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
            builder.AddApplicationInsightsSettings(developerMode: true);
        }

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    /// This method gets called by the runtime. Use this method to add services to the container
    public void ConfigureServices(IServiceCollection services)
    {
        #region Framework services.
        services.AddApplicationInsightsTelemetry(Configuration);

        services.AddMvc()
            .AddJsonOptions (options => { options.SerializerSettings.ContractResolver = new DefaultContractResolver(); }); ;

        services.AddLogging();
       #endregion

        #region Swagger - API参考文档
        // Register the Swagger generator, defining one or more Swagger documents
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1.2.0", new Info
            {
                Version = "v1.2.0",
                Title = "ZebaoAPI",
                Description = "泽保API接口自动帮助文档",
                TermsOfService = "相关权利保留。",
            });
            //Set the comments path for the swagger json and ui.
            var basePath = PlatformServices.Default.Application.ApplicationBasePath;
            var xmlPath = Path.Combine(basePath, "ZebaoIntra.xml");
            c.IncludeXmlComments(xmlPath);
        });
        services.ConfigureSwaggerGen(options =>
        {
            options.IgnoreObsoleteProperties();
            options.DescribeAllParametersInCamelCase();
            options.DescribeAllEnumsAsStrings();
        });
        #endregion

        #region data services
        //Mysql数据库
        string mysqlconnectionstring = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                    .Build()
                    .GetConnectionString("ZBLocalMysqlConnection");
        services
            .AddDbContext<MySQLContext>(options => options.UseMySQL(mysqlconnectionstring));

        //这部分是为了让controller能够访问到appsettings.json中的参数
        services.AddOptions();
        services.Configure<ConnectionStringsOptions>(Configuration.GetSection("ConnectionStrings"));
        services.Configure<WXConfigurationOptions>(Configuration.GetSection("WXConfigurationOptions"));
        services.Configure<MappingPathOptions>(Configuration.GetSection("MappingPathOptions"));
        #endregion
    }

    /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline
    public void Configure(Microsoft.AspNetCore.Builder.IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseApplicationInsightsRequestTelemetry();
        app.UseApplicationInsightsExceptionTelemetry();

        //发布Zebao的官网用静态文件
        app.UseStaticFiles();
        app.UseMvcWithDefaultRoute();

        // Enable middleware to serve generated Swagger as a JSON endpoint.
        app.UseSwagger();

        // Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1.2.0/swagger.json", "ZebaoIntranet V1.2.0");
        });

        app.UseMvc(routes =>
        {
            routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

public class ConnectionStringsOptions
{
    public string ZBLocalMysqlConnection { get; set; }
}

public class WXConfigurationOptions
{
    public string AppId { get; set; }
    public string AppSecret { get; set; }
    public string Token { get; set; }
    public string EncodingAESKey { get; set; }
    public string OriginId { get; set; }
}

} -------------------InsuranceController --------------------- using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using ZebaoIntra; using Newtonsoft.Json; using ZBModels; using Microsoft.EntityFrameworkCore; using System.Net.Http; using Microsoft.AspNetCore.Http; using Microsoft.Net.Http.Headers; using System.IO; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Authorization; using Dapper; using System.Data; using Microsoft.AspNetCore.Builder; using System.Runtime.InteropServices; using Microsoft.Extensions.Options; using System.Reflection; using Microsoft.Extensions.WebEncoders; using System.Text;

namespace ZebaoIntra.Controllers { [Route("[controller]/[action]")] public class InsuranceController : Controller { private MySQLContext _context; private IHostingEnvironment _hostingEnv; private readonly ConnectionStringsOptions _options;

    public InsuranceController(IHostingEnvironment env, IOptions<ConnectionStringsOptions> optionsAccessor)
    {
        _context = context;
        _hostingEnv = env;
        _options = optionsAccessor.Value;
    }

[HttpGet] public async Task EFClassify([FromQuery] string classifyword) { try { var predata = await ( from d in _context.ipn_insurance_descriptor join a in _context.ipn_insurance_combination on d.ID equals a.ID select new ZBProductsVM { CREATETIME = a.CREATETIME, ID = a.ID, COMPANY = a.COMPANY, NAME = a.NAME, CONTENT = a.CONTENT, PRICE = a.PRICE, SALEAMOUNT = a.SALEAMOUNT, 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();

            //Console.WriteLine("==========Mysql result: " + data.Count());
            if(predata.Count<=0)
            {
                return new
                {
                    status = 2,
                    info = "NoResult",
                    Data = ""
                };
            }else
            {
                return new
                {
                    status = 1,
                    info = "Success",
                    Data = data
                };
            };
        }
        catch(Exception e)
        {
            //Console.WriteLine("==========Error: " + e.Message);
            return new
            {
                status = 0,
                info = "Error",
                Data = e.Message
            };
        }
  }

} `

`using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks;

namespace ZBModels { public class ZBProductsVM : ipninsurance { public DateTime UPDATETIME { get; set; }

    #region ipn_insurance_descriptor部分,增强的产品信息描述

    public String Tags { get; set; }

    public string Classifier { get; set; }

    public string OriginName { get; set; }

    public string Briefing { get; set; }
    #endregion
}

}

using System;

namespace ZBModels { public class ipn_insurance_combination { public int ID { get; set; } public DateTime CREATETIME { get; set; } //public DateTime MODIFYTIME { get; set; } public String COMPANY { get; set; } public string NAME { get; set; } public string CONTENT { get; set; } public bool ISACTIVE { get; set; } public bool ISDELETED { get; set; } public int? ORDERBY { get; set; } public string REMARK { get; set; } public decimal? PRICE { get; set; } public int? SALEAMOUNT { get; set; } public int? REALSALEAMOUNT { get; set; } public string TYPE { get; set; } public String TIMELENGTH { get; set; } public string HEADPHOTO { get; set; } public int? INSURANCESINGLE_ID { get; set; } public String NOTETERMS { get; set; } public String HEALTHINFORMED { get; set; } public String EXCEMPLE { get; set; } public String TERMS { set; get; } public string WARRANTIES { get; set; } public string CLAIMS { get; set; } public string electronicPolicy { get; set; } public string EFFECTIVETIME { get; set; } public string STARTPERIOD { get; set; } public string STOPPERIOD { get; set; } } } `

Further technical details

EF Core version: "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0", "Microsoft.EntityFrameworkCore.Sqlite": "1.1.0", "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", "Microsoft.EntityFrameworkCore.Design": { "type": "build", "version": "1.0.0-preview2-final" }, Database Provider: "MySql.Data.EntityFrameworkCore": "7.0.7-m61" Operating system: windows 10 pro version 1607/ OS 14393.1066 IDE: Visual Studio 2015 update3

ajcvickers commented 7 years ago

@silentrock When you say, "switched to Dapper, untill the bug was reported again after several dotnet restarts." do you mean that you still see this when using Dapper instead of EF Core?

imadyTech commented 7 years ago

@ajcvickers Yes the Dapper also has similar issue. The difference is, there is no incremental number of inotify instances if use "lsof -p dotnetpid |wc -l" command to check the total opened instances. Therefore, asp.net core website works well normally, till I repeated publish-upload-deploy cycle for several times and the error will appears. Restart dotnet will not solve the error, unless you restart the ubuntu system.

ajcvickers commented 7 years ago

@silentrock Based on our initial analysis we believe this is likely an issue with either the MySQL provider, or some layer of MySQL below the provider. You might want to try filing an issue here: https://bugs.mysql.com/