前提
WindowsServer2016 Standard
VisualStudio2015Pro(C#)
実現したいこと
ASP.NETでWebAPIを作成しております。
発生している問題・エラーメッセージ
レスポンスが不定期で15秒程度かかることがあります。通常時は1秒以内です。
原因を知りたいです。
いくつかAPI関数がありますが、15秒かかるのは1つ関数のみです。
処理自体は1秒以内で終了することは確認済みです。
クライアント側はブラウザやC#のHttpClientの両方で発生します。
Fidderで見るとサーバからレスポンスが15秒かえってきていません。
該当のソースコード
C#
1public class WorkResultController : ApiController 2{ 3 public object GetWorkResultsByDate(string div, string datefrom, string dateto) 4 { 5 try 6 { 7 var sw = new System.Diagnostics.Stopwatch(); 8 sw.Start(); 9 string connectionString = AccessConnection.GetConnection(div); 10 using (OleDbConnection cn = new OleDbConnection(connectionString)) 11 { 12 cn.Open(); 13 string sql = "SELECT * FROM testテーブル WHERE 日付 >= ? AND 日付 <= ?"; 14 OleDbCommand cmd = new OleDbCommand(sql, cn); 15 cmd.Parameters.Add("@開始", OleDbType.Date).Value = datefrom; 16 cmd.Parameters.Add("@終了", OleDbType.Date).Value = dateto; 17 DataTable dt = new DataTable(); 18 OleDbDataAdapter ada = new OleDbDataAdapter(cmd); 19 ada.Fill(dt); 20 var rtn = Newtonsoft.Json.JsonConvert.DeserializeObject(Newtonsoft.Json.JsonConvert.SerializeObject(dt)); 21 sw.Stop(); 22 //$"{sw.Elapsed.TotalSeconds}秒"); 23 // 1秒以内で終了していることを確認済 24 return rtn; 25 } 26 } 27 catch (Exception ex) 28 { 29 //err.ErrorMessage = ex.Message; 30 return 31 } 32 } 33 34}
試したこと
IISのアプリケーションプールは、下記サイトを参考に開始モードをAlwaysRunning、
アイドル状態のタイムアウトを1440、
有効化されたプリロードをTrueに設定しました。
https://thwack.solarwinds.com/resources/japan/f/forum/973/orion-web
補足情報(FW/ツールのバージョンなど)
[追記]
関数内でAccessのデーベースにアクセスしています。
データベースは別サーバの共有フォルダにあります。
2022/12/12 追記
下記コードのreturn response;の1行が、時々非常に遅い(15秒)ことがあることがわかりました。
C#
1 public HttpResponseMessage GetWorkResultsByDate(string div, string datefrom, string dateto) 2 { 3 var sw = new System.Diagnostics.Stopwatch(); 4 sw.Start(); 5 6 try 7 { 8 DBType dbtype = DBType.Access; 9 string connectionString = DBConnectionString.GetConnection(div, ref dbtype); 10 using (OleDbConnection cn = new OleDbConnection(connectionString)) 11 { 12 cn.Open(); 13 string sql = "SELECT * FROM testテーブル WHERE 日付 >= ? AND 日付 <= ?"; 14 OleDbCommand cmd = new OleDbCommand(sql, cn); 15 cmd.Parameters.Add("@開始", OleDbType.Date).Value = datefrom; 16 cmd.Parameters.Add("@終了", OleDbType.Date).Value = dateto; 17 DataTable dt = new DataTable(); 18 OleDbDataAdapter ada = new OleDbDataAdapter(cmd); 19 ada.Fill(dt); 20 21 //↓速度改善試行 22 IEnumerable<WorkResult> rtnList = dt.AsEnumerable().Select(row => new WorkResult 23 { 24 xxxxx= Convert.ToInt32(row["ID"]), 25 26 }).ToList(); 27 //↑速度改善試行 28 29 sw.Stop(); 30 Logger.WriteLog(MethodBase.GetCurrentMethod().Name, $"{sw.Elapsed.TotalSeconds}秒"); 31 sw.Reset(); 32 sw.Start(); 33 34 //return Request.CreateResponse(HttpStatusCode.OK, rtnList); //速度改善試行 35 var response = Request.CreateResponse(HttpStatusCode.OK); 36 response.Content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(rtnList, Newtonsoft.Json.Formatting.Indented), System.Text.Encoding.UTF8, "application/json"); 37 38 sw.Stop(); 39 Logger.WriteLog(MethodBase.GetCurrentMethod().Name, $"CheckPoint {sw.Elapsed.TotalSeconds}秒"); 40 sw.Reset(); 41 sw.Start(); 42 43 return response; 44 } 45 } 46 catch (Exception ex) 47 { 48 Logger.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message); 49 MyApiError err = new MyApiError(); 50 err.ErrorMessage = ex.Message; 51 return Request.CreateResponse(HttpStatusCode.OK, err); 52 } 53 finally 54 { 55 sw.Stop(); 56 Logger.WriteLog(MethodBase.GetCurrentMethod().Name, $"finally {sw.Elapsed.TotalSeconds}秒"); 57 } 58 }
渡はJava専門なので役に立たないかもですが少し思うところがあります。
バッファなどが使われる関係でストリームに流し込んだデータがクライアントへの転送待機状態になっているかもしれません。
バッファが貯まるか一定時間経過するとサーバー側のデータが実際にクライアントに送信されます。
もう送信すべきデータが無いなど明示的にデータ送信を完了させたい場合は一般的に Flush と呼ばれる
転送待機データを実際にクライアントに流す操作が必要です。
https://stackoverflow.com/questions/29793308/asp-net-web-api-pushstreamcontent-flush-does-not-flush
> レスポンスが不定期で15秒程度かかることがあります。
どのぐらいの頻度なのですか。
> いくつかAPI関数がありますが、15秒かかるのは1つ関数のみです。
それはどうやって確認しましたか。ログを取るとかして「1つ関数のみ」なのは絶対間違いないことは確認しましたか。
ログが取ってあればもっと原因を絞れると思うのですがそういうことはしてないのですか。
ご回答ありがとうございます。
クライアント側でログを取っており、1つの関数以外は今のところ遅延は発生しておりません。
数十回リクエストしたうちに1回程度の頻度で発生しております。
不定期で時間が空いたり、間隔が詰まったりしており、発生条件がわかっておりません。
> クライアント側でログを取っており、
クライアント側では何に時間がかかっているのか特定する情報を得るのは無理ではないのですか? サーバー側でログを取ることをお勧めします。IIS にログを取る機能があります。それに加えてsw.Elapsed.TotalSeconds もログに残すとかして。
今提供されている情報から Q&A を通じて原因特定のお手伝いをする気力が自分にはありません。お役に立てずすみませんが、他の回答者の出現をお待ちください。
回答1件
あなたの回答
tips
プレビュー