トラフィックがほとんどない私のウェブサイトをホストしているサーバーがあります。
毎日数人(<20)がサイトにアクセスし、数人のRSSリーダーが私たちが出すいくつかのフィードを購読しています。
ほぼ毎晩、RSSリーダーが深夜に私たちを襲い、接続のタイムアウトのためにWebサイトがSQLServerに接続できないという例外が発生します。詳細は非常に奇妙なので、どこから始めればよいのかわからないので、何が問題になるのかについて助けを求めています。
Windows Server2008ではなくASP.NetMVC、Entity Framework、およびSQL Server 2008を使用しています。このマシンは、厳密には一流ではないプロバイダーから入手した専用のボックスであるため、最適に構成されていない可能性があります。そうしないと。
ボックスもかなり小さく、RAMは1Gbしかありませんが、今のところある種の負荷がかかるはずです...
以下の完全な呼び出しスタックをコピーしていますが、最初に、私たちが知っていることのいくつか:
- iTunesが私たちのサイトにクエリを実行しているときは常にエラーが発生します。これは何の関係もないはずだと思いますが、本当はiTunesからしか入手できません。私の推測では、これは、他の誰も私たちを攻撃していない夜のその時間にiTunesだけが私たちに問い合わせをするために起こると思います。
- 私たちの理論の1つは、SQL ServerとIISがメモリをめぐって争っていて、そのうちの1つが使用されていない状態でディスクにページングされており、誰かが「ウェイクアップ」すると、ディスクからすべてを読み取るのに時間がかかりすぎるというものです。メモリに。これは潜在的に起こり得ることですか?(可能であれば、SQL Serverの設計上の問題のように思われるので、これを破棄します)
- また、EFエンティティを適切に処理していない可能性があるため、接続がリークしている可能性についても考えました(ここでの私の質問を参照してください)。これは私が問題をグーグルで検索することによって見つけることができた唯一のものです。負荷が非常に低いため、これを破棄します。
- これは常に一晩で発生するため、しばらくの間何も起こらなかったという事実に関連している可能性が非常に高いです。たとえば、これらのリクエストがヒットすると、Webサーバープロセスがリサイクルされ、すべてが起動/再JITされると確信しています。ただし、再JITはSQLタイムアウトを説明しません。
更新:提案どおりにプロファイラーをアタッチしましたが、新しい例外が発生するまでにかなりの時間がかかりました。これは私たちが知っている新しいものです:
- プロファイラーをアタッチすることで、発生するエラーの数を大幅に減らすことができました。実際、通常は1日に数回摂取した後、これが1回発生するまで3〜4日待たなければなりませんでした。プロファイラーを停止すると、通常のエラー頻度(またはさらに悪い頻度)に戻りました。したがって、プロファイラーには、この問題をある程度隠す効果がありますが、完全ではありません。
- IIS要求ログの横にあるプロファイラートレースを見ると、要求とクエリの間に1対1の対応が予想されます。ただし、IISログとの相関関係がまったくないクエリが実行されているのを時々目にします。実際、実際のバグがログに記録される直前に、3分間で750のクエリが発生しましたが、これらはすべてIISログとはまったく関係がありませんでした。クエリテキストは、EFが生成する読み取り不可能ながらくたのようなもののように見えますが、すべて同じではなく、Webサイトからのクエリ(同じApplicationName、Userなど)のように見えます。これがいかにばかげているかを知るためにつまり、このサイトは2日間で約370のIISリクエストを受け取り、DBにヒットしました。
- これらの説明のつかないクエリは、以前のWebサイトのクエリと同じClientProcessIDからのものではありませんでしたが、その間にプロセスがリサイクルされた場合は、まだWebサイトからのものである可能性があります。最後に説明されたクエリと最初の説明されていないクエリの間に、ほぼ1時間のアクティビティがありませんでした。
- どこから来たのかわからないこれらの長い一連のクエリの1つは、ログに記録されたエラーの直前に発生したため、これが私たちが従うべき手がかりだと思います。
- 当初予想したように、エラーをスローしたクエリが実行されたとき、それは前のクエリとは異なるClientProcessIDからのものでした(前の原因不明のクエリより8分遅れ、前のIISのものよりほぼ正確に1時間遅れています)。これは、私にとって、労働者のプロセスが実際にリサイクルされたことを意味します。
- これは私が絶対に理解していないことです。IISログには、エラー要求の1分前に、4つが完全に処理されたことが示されていますが、それらのクエリはトレースにまったく表示されません。実際、これらの4つがうまくいった後、4つの例外がすばやく連続してスローされ、それらの4つもトレースに表示されません(接続にタイムアウトがあった場合、クエリは実行されないはずなので、これは理にかなっています。しかし、トレースに接続の試行も表示されません)
だから、要するに、私はこれについて完全に無知です。何百ものクエリが連続して実行される理由はわかりませんが、それらは問題と関係があるに違いないと思います。
また、接続の問題を診断する方法もわかりません...
または、IISによると正常に処理されたクエリがプロファイラートレースで欠落している可能性があります...
何か案は?
これは例外情報です:
System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
System.Data.EntityException: The underlying provider failed on Open. ---> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
--- End of inner exception stack trace ---
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
at System.Data.EntityClient.EntityConnection.Open()
at System.Data.Objects.ObjectContext.EnsureConnection()
at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1[TResult](IEnumerable`1 sequence)
at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
at MyProject.Controllers.SitesController.Feed(Int32 id) in C:\...\Controller.cs:line 38
at lambda_method(ExecutionScope , ControllerBase , Object[] )
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
どんなアイデアでも大歓迎です。