1. 程式人生 > >ASP.NET Core奇遇記:無用戶訪問,CPU卻一直100%

ASP.NET Core奇遇記:無用戶訪問,CPU卻一直100%

redis ces core default async ima wid 阿裏雲服務器 services

這是5月11日遇到的一個問題,1臺1核1G阿裏雲Linux服務器運行著生產環境中的ASP.NET Core站點,出現CPU 100%問題。

技術分享

開始以為是這臺服務器負載高引起的,於是將這臺服務器從負載均衡上摘下來。這時奇怪的事情發生了,即使沒有負載(無用戶訪問),CPU也在接近100%範圍波動。

用htop命令查看,也沒看到哪個進程占用CPU特別多。

技術分享

以為是阿裏雲服務器的問題,向阿裏雲提交了工單,阿裏雲客服分析後發現其中的一個進程(我們的一個ASP.NET Core站點)占用資源比較多,而且對資源的占用頻繁變動。

看來問題與這個ASP.NET Core站點有關,這時發現另外一個奇怪的地方——雖然監控顯示CPU占用一直接近100%,但這臺服務器上的其他ASP.NET Core站點都能正常運行(有正常的負載),不像以前遇到的各種CPU 100%情況。

於是查看這個ASP.NET Core站點的日誌,發現下面的error log:

---> System.Net.Sockets.SocketException: No such host is known
   at System.Net.Dns.HostResolutionEndHelper(IAsyncResult asyncResult)
   at System.Net.Dns.EndGetHostAddresses(IAsyncResult asyncResult)
   at System.Net.Dns.<>c.<GetHostAddressesAsync>b__14_1(IAsyncResult asyncResult)

查看了對應的代碼(在Startup.cs的ConfigureServices中):

services.AddDistributedServiceStackRedisCache(options =>
{
    configuration.GetSection("redis").Bind(options);
    //Workaround for deadlock when resolving host name
    if (!IPAddress.TryParse(options.Host, out var ip))
    {
        options.Host 
= Dns.GetHostAddressesAsync(options.Host) .Result.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork).ToString(); } });

聯想到出問題之前用 supervisorctl restart 命令重啟了站點,以及我們最近更換了阿裏雲redis實例,終於明白了引發CPU 100%問題的原因。

這個 ASP.NET Core 站點的 appsettings.json 中配置的 redis 實例已經釋放,上面的代碼中通過 redis 實例的網址解析 IP 地址的操作會失敗,由於這個操作是在 Startup 中進行的,所以造成整個站點啟動失敗。本來僅僅是站點啟動失敗並不會造成CPU 100%,但是由於我們在 supervisor 中(我們是用 supervisor 以服務方式運行 ASP.NET Core 站點的)配置了 autorestart=true 。於是,當 DNS 解析失敗造成的 ASP.NET Core 站點啟動失敗後,supervisor 會自動重啟站點,重啟依然失敗,失敗後繼續重啟。。。就這樣不停地重啟,造成了 CPU 100% 。當在 appsettings.json 中修改為正確的 redis 配置後,問題立馬解決。

ASP.NET Core奇遇記:無用戶訪問,CPU卻一直100%