首页 > 解决方案 > Hangfire - Asp.Net Core 3.1 - 错误日志应用程序启动异常

问题描述

最近我注意到生产中(在线)的 Web 应用程序通常会出错,我不得不手动重新启动它。

为了尝试理解 web.config 文件中的错误,我启用了以下条目:- stdoutLogEnabled = "true"

就在今天,我(随机)注意到应用程序已关闭并打开日志文件,这是它的内容:

crit: Microsoft.AspNetCore.Hosting.Diagnostics[6]

      Application startup exception

MySql.Data.MySqlClient.MySqlException (0x80004005): User 'nome_database' has exceeded the 'max_user_connections' resource (current value: 10)

   at MySqlConnector.Core.ServerSession.SwitchAuthenticationAsync(ConnectionSettings cs, PayloadData payload, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ServerSession.cs:line 535

   at MySqlConnector.Core.ServerSession.TryResetConnectionAsync(ConnectionSettings cs, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ServerSession.cs:line 498

   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ConnectionPool.cs:line 72

   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ConnectionPool.cs:line 141

   at MySql.Data.MySqlClient.MySqlConnection.CreateSessionAsync(ConnectionPool pool, Nullable`1 ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 645

   at MySql.Data.MySqlClient.MySqlConnection.OpenAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 312

   at MySql.Data.MySqlClient.MySqlConnection.Open() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 280

   at Hangfire.MySql.MySqlStorage.CreateAndOpenConnection()

   at Hangfire.MySql.MySqlStorage.UseTransaction[T](Func`2 func, Nullable`1 isolationLevel)

   at Hangfire.MySql.MySqlStorage.UseTransaction(Action`1 action)

   at Hangfire.MySql.MySqlWriteOnlyTransaction.Commit()

   at Hangfire.RecurringJobManager.AddOrUpdate(String recurringJobId, Job job, String cronExpression, RecurringJobOptions options)

   at Hangfire.RecurringJobManagerExtensions.AddOrUpdate(IRecurringJobManager manager, String recurringJobId, Job job, String cronExpression, TimeZoneInfo timeZone, String queue)

   at Hangfire.RecurringJob.AddOrUpdate[T](String recurringJobId, Expression`1 methodCall, String cronExpression, TimeZoneInfo timeZone, String queue)

   at FFM3._1.Utility.HangfireJobScheduler.ScheduleRecurringJobs(IWebHostEnvironment env) in C:\Users\Xxxx\Xxxx\XXX\XXX\XXX\Utility\HangfireJobScheduler.cs:line 23

   at FFM3._1.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider) in C:\Users\Xxxx\Xxxx\XXX\XXX\XXX\Startup.cs:line 170

   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)

   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)

   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)

   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.<Build>b__0(IApplicationBuilder builder)

   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass13_0.<UseStartup>b__2(IApplicationBuilder app)

   at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)

   at Microsoft.AspNetCore.Server.IIS.Core.IISServerSetupFilter.<>c__DisplayClass2_0.<Configure>b__0(IApplicationBuilder app)

   at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)

   at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)

Unhandled exception. MySql.Data.MySqlClient.MySqlException (0x80004005): User 'nome_database' has exceeded the 'max_user_connections' resource (current value: 10)

   at MySqlConnector.Core.ServerSession.SwitchAuthenticationAsync(ConnectionSettings cs, PayloadData payload, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ServerSession.cs:line 535

   at MySqlConnector.Core.ServerSession.TryResetConnectionAsync(ConnectionSettings cs, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ServerSession.cs:line 498

   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ConnectionPool.cs:line 72

   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ConnectionPool.cs:line 141

   at MySql.Data.MySqlClient.MySqlConnection.CreateSessionAsync(ConnectionPool pool, Nullable`1 ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 645

   at MySql.Data.MySqlClient.MySqlConnection.OpenAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 312

   at MySql.Data.MySqlClient.MySqlConnection.Open() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 280

   at Hangfire.MySql.MySqlStorage.CreateAndOpenConnection()

   at Hangfire.MySql.MySqlStorage.UseTransaction[T](Func`2 func, Nullable`1 isolationLevel)

   at Hangfire.MySql.MySqlStorage.UseTransaction(Action`1 action)

   at Hangfire.MySql.MySqlWriteOnlyTransaction.Commit()

   at Hangfire.RecurringJobManager.AddOrUpdate(String recurringJobId, Job job, String cronExpression, RecurringJobOptions options)

   at Hangfire.RecurringJobManagerExtensions.AddOrUpdate(IRecurringJobManager manager, String recurringJobId, Job job, String cronExpression, TimeZoneInfo timeZone, String queue)

   at Hangfire.RecurringJob.AddOrUpdate[T](String recurringJobId, Expression`1 methodCall, String cronExpression, TimeZoneInfo timeZone, String queue)

   at FFM3._1.Utility.HangfireJobScheduler.ScheduleRecurringJobs(IWebHostEnvironment env) in C:\Users\Xxxx\Xxxx\XXX\XXX\XXX\Utility\HangfireJobScheduler.cs:line 23

   at FFM3._1.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider) in C:\Users\Xxxx\Xxxx\XXX\XXX\XXX\Startup.cs:line 170

   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)

   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)

   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)

   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.<Build>b__0(IApplicationBuilder builder)

   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass13_0.<UseStartup>b__2(IApplicationBuilder app)

   at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)

   at Microsoft.AspNetCore.Server.IIS.Core.IISServerSetupFilter.<>c__DisplayClass2_0.<Configure>b__0(IApplicationBuilder app)

   at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)

   at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)

   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)

   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)

   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)

   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)

   at FFM3._1.Program.Main(String[] args) in C:\Users\Xxxx\Xxxx\XXX\XXX\XXX\Program.cs:line 16

我相信问题出在使用hangfire(或者可能在其不正确的配置中)。

我正在使用 Asp.Net Core 3.1,我正在使用 MySql 作为数据库。

下面我报告我在 Startup.cs 文件的 ConfigureServices 方法中输入的内容

services.AddHangfire(configuration => configuration.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
                                                               .UseSimpleAssemblyNameTypeSerializer()
                                                               .UseRecommendedSerializerSettings()
                                                               .UseStorage(new MySqlStorage(Configuration.GetConnectionString("DefaultConnection"), new MySqlStorageOptions()
                                                               {
                                                                   TablesPrefix = "Hangfire"
                                                               })));
            services.AddHangfireServer();

下面我报告我在 Startup.cs 文件的 Configure 方法中输入的内容

app.UseHangfireDashboard("/hangfire", new DashboardOptions
            {
                Authorization = new[] { new HangfireAuthorizationFilter() }
            });
            HangfireJobScheduler.ScheduleRecurringJobs(env);

从日志中我希望你能给我一些指示来帮助我解决这个问题。

我提前谢谢你。

标签: mysqlasp.net-corehangfirepomelo-entityframeworkcore-mysql

解决方案


检查连接池相关的连接字符串选项

默认情况下,连接池在 MySqlConnector(这是 Pomelo 使用的底层库)中启用并打开直到 100 个连接(maxpoolsize连接字符串选项)。

如果您的 MySQL 数据库以某种方式配置,它无法处理那么多连接,并且您最近发现了这些异常,那么您最近可能会获得比以前更多的流量,并且超过了配置的值(比 更多的并发连接数max_connections)。

要解决此问题,只需以不超过 MySQLmax_connections值的方式配置连接池,或以某种方式配置 MySQL,以允许更多连接(请参阅max_connections)或(作为最后手段)强制关闭在一定时间后打开(并且可能是陈旧的)连接(请参阅wait_timeoutinteractive_timeout)。


推荐阅读