1.問題
最近在寫一個熔斷的 SDK,其中一種策略是根據慢請求來進行熔斷。
我們在測試的時候,在對應 API 裡面採用了 Thread.Sleep(ms) 來模擬慢請求。
設定的慢請求閾值是 RT 100ms,我們設定了 Thread.Sleep(90ms),但是發現竟然觸發了熔斷。最近分析發現是 Thread.Sleep 並不精準,在測試機器(Windows 10)上偏差最大超過了 10ms,在我自己的電腦上(Mac)偏差最大 5ms。
為什麼會這樣呢?“因為Thread.Sleep保證的是至少休眠指定的值”(來自時總的解答 https://www.cnblogs.com/InCerry)
這不是 C# 的問題,JAVA 也一樣。
編寫了 JAVA 程式碼,發現結果在我的機器上和 C# 是一樣的,最大偏差 5ms。
這個偏差和機器CPU、負載、Sleep 時間、作業系統有關。
2.解決
如何解決這個問題?我嘗試降低 Sleep 時間,通過迴圈計時,發現這個方法的精準度挺高的。
static void Sleep(int ms)
{
var sw = Stopwatch.StartNew();
var sleepMs = ms - 16;
if (sleepMs > 0)
{
Thread.Sleep(sleepMs);
}
while (sw.ElapsedMilliseconds < ms)
{
Thread.Sleep(0);
}
}
經過了時總的優化
上面的程式碼執行測試: