我期待非常令人沮丧的问题,找不到理由。
有一个托管在Azure上的应用程序,它使用MySQL数据库。我正在使用Oracle的MySQL.Data nuget(6.10.5)。 我经常遇到Timeout过期错误,无法连接到任何指定的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()
我无法在本地计算机上触发此错误。 我可以从Azure ping我的MySql数据库。 证书是可以的 - 它在我的本地计算机上运行良好。
连接类:
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;
}
我的猜测是我错过了一些我不熟悉的连接池相关内容。
任何想法可能是什么原因?还有什么可以检查?
非常感谢您的帮助!
答案 0 :(得分:0)
在这些情况下,总是值得开始使用你的一次性用品......
using (var connection = new ConnectionClass()) {
//...
}
您可能正在进行太多连接,只有在GC调用dispose方法时才会关闭这些连接。 using语句将提前关闭连接,这可能会解决问题。
这个问题也可能是由其他因素引起的,但我发现故意关闭连接是许多类似问题的解决方案。