Я ожидаю очень неприятную проблему и не могу найти причину.
Существует приложение, размещенное на Azure, которое использует MySQL db. Я использую MySQL.Data nuget из Oracle (6.10.5). Очень часто я получаю ошибку с истечением времени ожидания с помощью Невозможно подключиться к любому из указанных узлов MySQL (дюжина в 24 часа).
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Exception Details: MySql.Data.MySqlClient.MySqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Трассировки стека:
[MySqlException (0x80004005): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.]
MySql.Data.Common.StreamCreator.GetTcpStream(MySqlConnectionStringBuilder settings) +177
MySql.Data.Common.StreamCreator.GetStream(MySqlConnectionStringBuilder settings) +37
MySql.Data.MySqlClient.NativeDriver.Open() +55
[MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts.]
MySql.Data.MySqlClient.NativeDriver.Open() +151
MySql.Data.MySqlClient.Driver.Open() +50
MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings) +225
MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection() +15
MySql.Data.MySqlClient.MySqlPool.GetPooledConnection() +288
MySql.Data.MySqlClient.MySqlPool.TryToGetDriver() +93
MySql.Data.MySqlClient.MySqlPool.GetConnection() +65
MySql.Data.MySqlClient.MySqlConnection.Open() +629
SalesManager.Models.ConnectionClass.QueryExec() in C:\Users\Gabinet\Source\Repos\SalesManager\SalesManager\SalesManager\Models\Data\ConnectionClass.cs:39
SalesManager.Models.ProductDownload.GetStorageQuantity(Int32 id) in C:\Users\Gabinet\Source\Repos\SalesManager\SalesManager\SalesManager\Models\ProductDownload.cs:58
SalesManager.Controllers.SalesController.Index(String sortOrder, String df, String dt) in C:\Users\Gabinet\Source\Repos\SalesManager\SalesManager\SalesManager\Controllers\SalesController.cs:41
lambda_method(Closure , ControllerBase , Object[] ) +194
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +19
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary'2 parameters) +169
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary'2 parameters) +27
System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +24
System.Web.Mvc.Async.WrappedAsyncResult'2.CallEndDelegate(IAsyncResult asyncResult) +31
System.Web.Mvc.Async.WrappedAsyncResultBase'1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +33
System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() +50
System.Web.Mvc.Async.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +228
System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +15
System.Web.Mvc.Async.WrappedAsyncResult'1.CallEndDelegate(IAsyncResult asyncResult) +15
System.Web.Mvc.Async.WrappedAsyncResultBase'1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +35
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult'1.CallEndDelegate(IAsyncResult asyncResult) +15
System.Web.Mvc.Async.WrappedAsyncResultBase'1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +29
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +15
System.Web.Mvc.Async.WrappedAsyncVoid'1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase'1.End() +50
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +14
System.Web.Mvc.Async.WrappedAsyncVoid'1.CallEndDelegate(IAsyncResult asyncResult) +22
System.Web.Mvc.Async.WrappedAsyncResultBase'1.End() +50
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +27
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +12
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
System.Web.Mvc.Async.WrappedAsyncVoid'1.CallEndDelegate(IAsyncResult asyncResult) +29
System.Web.Mvc.Async.WrappedAsyncResultBase'1.End() +50
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +29
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +11
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +577
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +157
Azure App Insights дает только тайм-аут:
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 22/12/2017 14:40:56
Event time (UTC): 22/12/2017 14:40:56
Event ID: 503190c80af54cdb87140fe1f808de22
Event sequence: 16
Event occurrence: 5
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/41351921/ROOT-1-131584264107173868
Trust level: Full
Application Virtual Path: /
Application Path: D:\home\site\wwwroot\
Machine name: RD00155D58C141
Process information:
Process ID: 10784
Process name: w3wp.exe
Account name: IIS APPPOOL\xxxx
Exception information:
Exception type: MySqlException
Exception message: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at MySql.Data.Common.StreamCreator.GetTcpStream(MySqlConnectionStringBuilder settings)
at MySql.Data.Common.StreamCreator.GetStream(MySqlConnectionStringBuilder settings)
at MySql.Data.MySqlClient.NativeDriver.Open()
Request information:
Request URL: http://xxxxx.azurewebsites.net/
Request path: /
User host address: xx.xxx.xxx.xx
User: xxxxx
Is authenticated: True
Authentication Type: ApplicationCookie
Thread account name: IIS APPPOOL\xxxx
Thread information:
Thread ID: 35
Thread account name: IIS APPPOOL\xxxx
Is impersonating: False
Stack trace: at MySql.Data.Common.StreamCreator.GetTcpStream(MySqlConnectionStringBuilder settings)
at MySql.Data.Common.StreamCreator.GetStream(MySqlConnectionStringBuilder settings)
at MySql.Data.MySqlClient.NativeDriver.Open()
Я не могу вызвать эту ошибку на моей локальной машине. Я могу пинговать свой MySql db от Azure. Учетные данные в порядке - он отлично работает на моей локальной машине.
Класс подключения:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using MySql.Data.MySqlClient;
namespace SalesManager.Models
{
public class ConnectionClass : IDisposable
{
private MySqlConnection _con;
private MySqlCommand _cmd;
private MySqlDataAdapter _da;
private DataTable _dt;
private string _constr =
"Server=mysqldb.com; Database=databaseName; Uid=database_user; Pwd=database_pass; Default Command Timeout=300000; ";
public ConnectionClass()
{
_con = new MySqlConnection(_constr);
}
public void MySqlQuery(string sqlquery)
{
_cmd = new MySqlCommand(sqlquery, _con);
}
public void MySqlQueryWithParam(string sqlquery, string paramName, string paramValue)
{
_cmd = new MySqlCommand(sqlquery, _con);
_cmd.Parameters.AddWithValue(paramName, paramValue);
}
public DataTable QueryExec()
{
_con.Open();
_da = new MySqlDataAdapter(_cmd);
_dt = new DataTable();
_da.Fill(_dt);
_con.Dispose();
return _dt;
}
public void NonQueryExec()
{
_con.Open();
_cmd.ExecuteNonQuery();
_con.Dispose();
}
public void Dispose()
{
_con.Close();
_con.Dispose();
}
}
}
Метод, который не выполняется:
public static int GetStorageQuantity(int id)
{
if (id != 9999)
{
connection = new ConnectionClass();
string sql = "select quantity from ps_stock_available where id_product = @pId";
connection.MySqlQueryWithParam(sql, "@pId", id.ToString());
var dr = connection.QueryExec().Rows[0];
var quantity = Convert.ToInt32(dr["quantity"].ToString());
return quantity;
}
return 0;
}
Я предполагаю, что у меня отсутствует что-то, связанное с пулом соединений, с которым я не знаком.
Любая идея, что может быть причиной? Что еще можно проверить?
Ваша помощь будет очень признательна!
В таких случаях всегда стоит начать с использования вашего одноразового материала...
using (var connection = new ConnectionClass()) {
//...
}
Возможно, вы создаете слишком много соединений, которые закрываются только тогда, когда GC вызывает метод dispose. Оператор using будет закрывать соединения раньше, и это может решить проблему.
Также возможно, что проблема вызвана другими факторами, но я обнаружил, что закрывающие соединения намеренно являются решением многих подобных проблем.