上周五下午,我们在博客中部署了推荐系统,在博文下方显示“最新IT新闻”的地方显示自动推荐的关联博文。我们用的推荐系统是第四范式的推荐服务,我们自己只是搭建了一个推荐系统中转站(基于 ASP.NET Core),接收来自博客前端的请求,然后将请求转发给第四范式的推荐服务,并将响应内容转发给博客前端。
这个中转站的功能非常简单,就是一个 http 请求/响应搬运工,简单到让我们忽视了它会给服务器带来的潜在压力 —— 一边与博客前端的请求/响应会产生大量 TCP 连接,一边与推荐服务的请求/响应会产生大量 TCP 连接,而且由于推荐数据的动态变化特点而无法使用缓存。在同样的负载下,这个搬运工会比其他应用消耗更多的 TCP 连接。
从上周五发布到昨天,由于访问量没有达到特别高的高峰,所以问题没有暴露。今天上午访问量达到更高峰时,问题出现了。部署在 docker swarm 集群上的很多站点时不时地出现 500 错误,日志中频繁出数据库或 memcached 服务器网络连接失败的错误。开始我们还以为是之前多次遇到过的节点服务器不稳定问题引起的,于是将集群中的服务器一台一台下线、重启、上线,但这样操作之后问题依旧。接着把怀疑对象放到了 memcached 服务器,是不是 memcached 服务器不稳定引起,于是重启 memcached 服务器,但问题依然。
在用完之前的招式、百思不得其解之时突然想到可能是集群中某些服务器的 TCP 连接过多达到了限制(Linux 的限制或者阿里云的限制),如果站在这个角度分析,不管故障的表现还是日志中的错误都可以得到合理的诠释。于是立马锁定了原因,然后自然就想到了我们上周五部署的推荐系统中转站,赶紧将其下线,500 错误即刻消失,集群上的所有应用都会恢复正常。
非常抱歉,这次故障给大家带来麻烦了,请大家谅解。我们会吸取这次上线推荐系统时不够深思熟虑、过于轻敌的教训,认真反思,努力改进自己的工作。
更新:后来升级至 .NET Core 2.2 Preview 3 ,并将 System.Net.Http 升级至 4.3.4 之后没出现这个问题,问题与 https://github.com/dotnet/corefx/pull/32568 有关。