连接到远程MySQL数据库的Azure上的间歇性问题EF6

时间:2015-07-09 08:41:00

标签: c# mysql asp.net azure entity-framework-6

我在Azure免费订阅上有一个站点,它是EF6上的C#连接到远程主机上的MySQL数据库。应用程序将运行正常一段时间,但是对于经过身份验证的用户,它将在具有以下内容的ObjectDataSource选择事件中出错:

Inner exception information (level 1):
    Exception type: System.Data.Entity.Core.EntityException
    Exception message: The underlying provider failed on Open.

Inner exception information (level 2):
    Exception type: MySql.Data.MySqlClient.MySqlException
    Exception message: Unable to connect to any of the specified MySQL hosts.

Request information:
    Request URL: https://xxx.azurewebsites.net:443/default.aspx
    Request path: /default.aspx
    User host address: 111.111.111.111
    User: xxx
    Is authenticated: True
    Authentication Type: ApplicationCookie
    Thread account name: IIS APPPOOL\xxx

Thread information:
    Thread ID: 24
    Thread account name: IIS APPPOOL\xxx
    Is impersonating: False
    Stack trace:    at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Web.UI.WebControls.ObjectDataSourceView.InvokeMethod(ObjectDataSourceMethod method, Boolean disposeInstance, Object& instance)
   at System.Web.UI.WebControls.ObjectDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments)
   at System.Web.UI.WebControls.ListControl.OnDataBinding(EventArgs e)
   at System.Web.UI.WebControls.ListControl.PerformSelect()
   at System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
   at System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound()
   at System.Web.UI.WebControls.DropDownList.LoadPostData(String postDataKey, NameValueCollection postCollection)
   at System.Web.UI.WebControls.DropDownList.System.Web.UI.IPostBackDataHandler.LoadPostData(String postDataKey, NameValueCollection postCollection)
   at System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

其他时候,对于未经身份验证的用户,它首先不会加载,但是:

    Inner exception information (level 1):
    Exception type: System.Data.Entity.Core.ProviderIncompatibleException
    Exception message: An error occurred accessing the database. This usually means that the connection to the database failed. Check that the connection string is correct and that the appropriate DbContext constructor is being used to specify it or find it in the application's config file. See the inner exception for details of the failure.

Inner exception information (level 2):
    Exception type: System.Data.Entity.Core.ProviderIncompatibleException
    Exception message: The provider did not return a ProviderManifestToken string.

Request information:
    Request URL: https://xxx.azurewebsites.net:443/
    Request path: /
    User host address: 111.111.111.111
    User: 
    Is authenticated: False
    Authentication Type: 
    Thread account name: IIS APPPOOL\xxx

Thread information:
    Thread ID: 64
    Thread account name: IIS APPPOOL\xxx
    Is impersonating: False
    Stack trace:    at System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app)
   at System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers)
   at System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context)
   at System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context)
   at System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext)

Thread information:
    Thread ID: 27
    Thread account name: IIS APPPOOL\xxx
    Is impersonating: False
    Stack trace:    at System.Data.Entity.Core.EntityClient.EntityConnection.<OpenAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Core.Objects.ObjectContext.<EnsureConnectionAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteInTransactionAsync>d__3d`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Utilities.TaskExtensions.CultureAwaiter`1.GetResult()
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<GetResultsAsync>d__e.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Utilities.TaskExtensions.CultureAwaiter`1.GetResult()
   at System.Data.Entity.Internal.LazyAsyncEnumerator`1.<FirstMoveNextAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Infrastructure.IDbAsyncEnumerableExtensions.<FirstOrDefaultAsync>d__25`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Identity.EntityFramework.UserStore`1.<FindAsync>d__d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Identity.AsyncHelper.RunSync[TResult](Func`1 func)
   at Microsoft.AspNet.Identity.UserManagerExtensions.Find[TUser,TKey](UserManager`2 manager, UserLoginInfo login)
   at TDT.Account.RegisterExternalLogin.Page_Load()
   at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.<LoadRecursiveAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Util.WithinCancellableCallbackTaskAwaitable.WithinCancellableCallbackTaskAwaiter.GetResult()
   at System.Web.UI.Page.<ProcessRequestMainAsync>d__14.MoveNext()

我的连接字符串是这样的:第一个用于标识内容的ApplicationDbContext,第二个用于EF模型:

<add name="IdentityConnection" connectionString="server=xxx.xxx.xx.xxx;user id=xxx;database=xxx;password=Password;persistsecurityinfo=True" providerName="MySql.Data.MySqlClient" /> 
<add name="context" connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyM‌​odel.msl;provider=MySql.Data.MySqlClient;provider connection string=&quot;server=111.111.11.11;user id=xxx;database=MyDB;password=password;persistsecurityinfo=True&quot;" providerName="System.Data.EntityClient" />

由于它位于免费的Azure上,并且您可以免费拥有10个站点,因此我已将该站点的相同版本上载到另一个Azure子域,因此当第一个站点出错时,我会检查第二个站点和该站点完美地连接到DB并且应用程序正常加载。任何想法发生了什么?是一次限制多个用户或有限数量的用户/连接的免费Azure订阅吗?我读到与ClearDB MySQL有4个连接的限制,但是这个MySQL是完全独立的,不应该有这些限制。虽然第二个站点在第一个错误时加载,但第二个站点如果长时间使用也会产生错误。 感谢

1 个答案:

答案 0 :(得分:0)

我的一个Java服务连接到外部MySQL服务器时遇到了类似的问题。我终于在Azure技术人员的帮助下解决了这个问题。

如果问题与我的相关 - 它是由用于在Azure上路由的SNAT表here is a post引起的,详细描述了该问题。

我最终为所有TCP / IP套接字连接发送了keep-alive数据包。另一种解决方案是分配PIP地址,但我不确定您是否可以使用Azure网站执行该操作。

我观察到重新连接到我们的MySQL所需的时间变化很大,因此结论是,当您的远程服务器认为连接仍然打开时,它不会允许来自同一IP的流量(VIP的你的网站在Azure语言中)在TCP级别上。

您可以尝试将保持活动时间设置为数据库连接低于4分钟(我们的应用程序设置为60秒):

server=xxx.xxx.xx.xxx;user id=xxx;database=xxx;password=Password;persistsecurityinfo=True;Keepalive=60;

我几乎没有使用C#的经验,因此请检查KeepAlive选项是否对连接器有效。它似乎是根据this网站。