这是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 配置后,问题立马解决。