You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<li>In App Service, go to <strong>Diagnose and solve problems</strong></li>
897
-
<li>Search for "Profiler"</li>
896
+
<li>In the dashboard, set execution time long enough that the total simulation easily exceeds 60 seconds (e.g., 25s execution, 10s interval, 6 max requests)</li>
897
+
<li>Click <strong>🐌 Start Slow Requests</strong> to begin the simulation</li>
898
+
<li>Wait for the first slow request to appear in the event log — this confirms health probe rate has been reduced</li>
899
+
<li>In App Service, go to <strong>Diagnose and solve problems</strong> → search for "Profiler"</li>
898
900
<li>Start a <strong>CPU Profiler</strong> trace (60-120 seconds recommended)</li>
899
-
<li>Trigger the slow request simulation</li>
900
-
<li>Download and analyze the trace</li>
901
+
<li>Wait for the trace to complete, then download and analyze</li>
901
902
</ol>
903
+
<p><strong>Why start the simulation first?</strong> The app automatically slows health probes while slow request simulations are active. Starting the simulation before the profiler keeps health probe noise out of the trace, giving you a cleaner profile focused on the blocking patterns.</p>
902
904
903
905
<h3>What to Look For in CLR Profiler</h3>
904
906
<p>The service uses three different sync-over-async patterns with <strong>intentionally descriptive method names</strong>:</p>
<!-- Using the Request Latency Monitor Section -->
1212
-
<sectionid="latency" class="doc-section">
1213
-
<h2>⏱️ Using the Request Latency Monitor</h2>
1214
-
<p>The dashboard includes a <strong>Request Latency Monitor</strong> that demonstrates how thread pool starvation affects request processing time.</p>
1215
-
1216
-
<h3>How It Works</h3>
1217
-
<ol>
1218
-
<li>A dedicated background thread (not from the thread pool) continuously sends probe requests to <code>/api/health/probe</code></li>
1219
-
<li>The probe endpoint is lightweight - it simply returns a timestamp</li>
1220
-
<li>Latency is measured from request start to response received</li>
1221
-
<li>Results are broadcast via SignalR to the dashboard</li>
1222
-
</ol>
1223
-
1224
-
<h3>What to Observe</h3>
1225
-
<tableclass="latency-table">
1226
-
<thead>
1227
-
<tr>
1228
-
<th>Scenario</th>
1229
-
<th>Latency (Total)</th>
1230
-
<th>Status</th>
1231
-
<th>What's Happening</th>
1232
-
</tr>
1233
-
</thead>
1234
-
<tbody>
1235
-
<tr>
1236
-
<td>Normal operation</td>
1237
-
<td>< 150ms</td>
1238
-
<td>✅ Good</td>
1239
-
<td>Thread pool threads are available</td>
1240
-
</tr>
1241
-
<tr>
1242
-
<td>Mild starvation</td>
1243
-
<td>150ms - 1s</td>
1244
-
<td>⚠️ Degraded</td>
1245
-
<td>Requests queued waiting for threads</td>
1246
-
</tr>
1247
-
<tr>
1248
-
<td>Severe starvation</td>
1249
-
<td>> 1s</td>
1250
-
<td>❌ Severe</td>
1251
-
<td>Significant queuing delay</td>
1252
-
</tr>
1253
-
<tr>
1254
-
<td>Timeout</td>
1255
-
<td>30s</td>
1256
-
<td>❌ Critical</td>
1257
-
<td>No thread available within timeout</td>
1258
-
</tr>
1259
-
</tbody>
1260
-
</table>
1261
-
1262
-
<divclass="info-box">
1263
-
<h4>Key Insight</h4>
1264
-
<p>The probe runs on a <strong>dedicated thread</strong> (not from the thread pool), so it can always send requests. However, the ASP.NET Core server uses the thread pool to process incoming requests. During starvation:</p>
1265
-
<ol>
1266
-
<li>The probe request is sent immediately</li>
1267
-
<li>The request sits in the ASP.NET Core queue</li>
1268
-
<li>It waits for a thread pool thread to become available</li>
1269
-
<li>Latency = time spent waiting + processing time</li>
1270
-
</ol>
1271
-
<p>This directly demonstrates how sync-over-async anti-patterns impact end-user response times.</p>
1272
-
</div>
1273
-
1274
-
<h3>Correlating with Azure Metrics</h3>
1275
-
<p>Compare the dashboard's latency chart with:</p>
1276
-
<ul>
1277
-
<li><strong>Application Insights</strong> > Live Metrics > Request Duration</li>
1278
-
<li><strong>App Service Metrics</strong> > Response Time</li>
0 commit comments