Redis Timeout問題解決
之前遇到在壓測2秒內達100個請求,持續10分鐘,當短時間請求過於龐大,Redis會Timeout的訊息,會顯示下列錯誤訊息。
如目前的Busy Threads = MinThreads時,ThreadPool就會開始建立並注入新的可用thread到ThreadPool裡。
運行的時候,假設需要一個IOCP thread,而ThreadPool內有可用的thread,就會立刻配出去使用。但如果目前的Busy Threads = Min Threads,就會讓這個請求進入排隊等候,等待500ms後依然沒有可用的thread,就會注入一條新的thread給目前排隊的第一順位請求。
由於預設的最小Worker/IOCP threads不足以服務大量湧入的請求,就會需要等待500ms才能在ThreadPool拿到可用的thread,在這個狀況下很有機會因等待建立新thread而發生Timeout exception。
Redis Timeout解法:
Program.cs註冊Redis時,設定SetMinThreads
。
//註冊Redis
builder.SetupRedisConnection();
public static void SetupRedisConnection(this WebApplicationBuilder applicationBuilder)
{
if (applicationBuilder == null)
throw new ArgumentNullException(nameof(applicationBuilder));
string envName = applicationBuilder.Environment.EnvironmentName;
RegisterRedisConnection(applicationBuilder.Services, applicationBuilder.Configuration);
applicationBuilder.Configuration.AddJsonFileByEnvironmentName(envName, "cacheManager");
//設定IOCP及WORKER最小Thread
ThreadPool.SetMinThreads(200, 200);
}
可以觀察IOCP及WORKER裡的Busy與Min,如果Busy>Min就表示有可能是ThreadPool的設定值並沒有為流量做最佳化。SetMinThreads
的設定值取決於伺服器的承載量及流量,並沒有一定的設定值。
參考資料:
https://jed1978.github.io/2018/05/20/Redis-Programming-CSharp-Basic-3.html