web服务器出现大量CLOSE_WAIT连接的前因后果

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web服务器出现大量CLOSE_WAIT连接的前因后果相关的知识,希望对你有一定的参考价值。

  公司网站一直很稳定,前段时间开始偶尔出现网站无法打开,提示504的错误,运维有怀疑是程序更新引起的,但是仔细看过代码并没有获取数据量过大的地方,而且数据库表现也一直很平稳。所以一直也无从下手,不知道问题出在哪里,每一次出现这个问题重启下iis可以解决,或者有的时候是过段时间自己就解决了,所以这个问题一直悬而未决。

  直到昨天晚上网站再次更新,在进行功能验证的时候频繁出现这个问题。后来测试出来是一个管理身份的用户登陆就会引发这个错误,并且运维在查看服务器情况的时候发现有大量的http请求,并且状态为CLOSE_WAIT。看了下请求的ip地址,正是我们的图片服务器的ip。上网查了下这个问题,发现大都是说这个问题是socket程序中出现的,怎么我们的web程序也出现了这样的问题呢?

、 技术分享

  先不去纠结这个,还是从代码入手吧。于是看了下管理身份的用户登陆的代码,重要去关注跟图片服务器相关的地方。最终发现这个账号登陆后会获取很多图片用于在首页轮转显示,关键的问题是在显示这些图片的时候会先执行一个方法判断这个图片路径是否存在,如果不存在则返回一个默认的本地图片地址。

  

 public static string GetTrueImgPath(string url)
        {
            HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
            try
            {
                HttpWebResponse myRes = (HttpWebResponse)myReq.GetResponse();
                if (myRes.ContentLength > 0)
                {
                    return url; //存在   
                }
                else
                {
                    return "/Contents/Images/img_fload.gif";
                }
            }
            catch
            {
                return "/Contents/Images/img_fload.gif";
            }
           
        }

  看到这个代码估计大家一下子就知道问题出在哪里了,HttpWebResponse的请求最后没有被关闭!所以才会产生那么多CLOSE_WAIT的http连接,正是这些没有及时关闭的http连接占用了服务器的正常http请求,导致了不能正常访问。根据我查到的资料,CLOSE_WAIT状态的连接在2个小时后也会自己关闭的,所以网站才会过段时间自己恢复正常。至此问题的根源已经找到,就差修改代码然后进行验证了,代码修改如下:

  

 public static string GetTrueImgPath(string url)
        {
            var myReq = (HttpWebRequest)WebRequest.Create(url);
            myReq.KeepAlive = false;
            HttpWebResponse myRes;
            try
            {
                myRes = (HttpWebResponse)myReq.GetResponse();
                if (myRes.ContentLength <= 0)
                {
                    url = "/Contents/Images/img_fload.gif";
                }
                myRes.Close();
            }
            catch
            {
                url = "/Contents/Images/img_fload.gif";
            }
            return url;
        }

  更新到服务器后进行验证也通过了,没有再出现CLOSE_WAIT的连接,至此问题解决。

以上是关于web服务器出现大量CLOSE_WAIT连接的前因后果的主要内容,如果未能解决你的问题,请参考以下文章

Linux网络tcp连接大量CLOSE_WAIT和TIME_WAIT状态的出现和解决方法

HttpClient当HTTP连接的时候出现大量CLOSE_WAIT连接(转)

Java相关

java httpclient4.3连接池怎么解决大量close_wait的问题

Java相关问题整理

对卡在 CLOSE_WAIT 状态的连接进行故障排除