• 分析案例:应用服务无响应,任务管理器中发现大量w3wp僵尸进程----等待异构系统WebService返回值


    问题描述:

          某二次开发的项目反馈,不定期出现应用服务器无响应的情况,登录服务器发现任务管理器中有大量的w3wp僵尸进程。

    分析过程:

          针对同一进程每隔15秒抓取dump,连续抓取3个,对比发现线程信息没有变化,并且每个线程的CPU时间和堆栈都没有变化,奇怪???

    以其中一个僵尸进程的dump日志为例,总计61个工作线程,其中正在运行的为15个,但我们仅能查看其中3个线程的信息。

    0:000> .load d:dumpssos.dll
    0:000> !tp
    CPU utilization: 3%
    Worker Thread: Total: 61 Running: 15 Idle: 46 MaxLimit: 5600 MinLimit: 56
    Work Request in Queue: 0
    --------------------------------------
    Number of Timers: 263
    --------------------------------------
    Completion Port Thread:Total: 1 Free: 1 MaxFree: 112 CurrentLimit: 0 MaxLimit: 5600 MinLimit: 56
    0:000> !runaway
    User Mode Time
      Thread       Time
       1:259e4      0 days 0:02:57.107
       2:1fa68      0 days 0:01:45.706
       0:1bc54      0 days 0:00:49.561

    进一步对比这三个可见线程的堆栈显示,都在等待异构系统Webservice的网络返回。调用异构系统的具体实现为同步的HttpSoap方式,经过ESB调用第三方的认证接口。。。,按照常理来说,该WebService服务应该很简单,什么原因呢?不超时吗?

    根据堆栈我们能够看到SoapHttpClientProtocol ---》HttpWebClientProtocol ---》WebClientProtocol ---》HttpWebRequest 依次的调用关系,最终的实现是HttpWebRequest。

    按照msdn上官方的文档显示,HttpWebRequest 类有三个关于Timeout的设置:Timeout、ContinueTimeout、ReadWriteTimeout

    https://msdn.microsoft.com/zh-cn/library/system.net.httpwebrequest(v=vs.110).aspx 

    根据进程现象和活动线程的堆栈信息,推测是“远程异构系统”先响应返回HttpHeader信息后,使得Timeout超时属性失效; 之后每5分钟内都有flush回一些信息,ReadWriteTimeout也会失效;当应用程序池在设定的空闲超时限内没有接到新的request请求,触发应用程序池的回收事件;但关闭进程时发现当前进程仍有未处理完的工作进程,当前进程在等待所有工作线程执行完毕然后再退出。当应用收到新的web请求时,应用程序池创建新的w3wp进程接收处理,依次推理,长时间后便出现了很多的僵尸进程。。。。

    为什么“第三方系统能够持续的反馈数据,却没有执行完成呢”? 这基本上也是不可能的,个人感觉应该是中间网络设备(防火墙、路由器、交换机)或ESB出现问题导致的,但是如果正向的联调测试话,难度太大,需要协调很多不同的外协单位。。。。

    image

    解决办法:

          将同步的WebService调用改为异步调用,对超过指定的时限仍未获得返回结果的请求,提示响应超时并对异步请求做Abort处理。

    参考:https://msdn.microsoft.com/en-us/library/system.web.services.protocols.soaphttpclientprotocol(v=vs.110).aspx

    核心的示例代码如下:

       TestSoapHttpClient webClient = new TestSoapHttpClient();
       Console.WriteLine("testing webservice: " + webClient.HelloWorld1());  // 同步调用示例 
    
       object asyState = new object();
       var asyResult = webClient.BeginHelloWorld2((x) => { }, asyState);
    
       // 设置超时时限,超时后主动终止web请求
       for (int i = 0; !asyResult.IsCompleted && i <= 5000; i += 50)
       {
           Thread.Sleep(50);
       }
       if (asyResult.IsCompleted)
       {
           string result = webClient.EndHelloWorld2(asyResult);
    
           // 根据远程Webservice返回的结果,继续业务处理
           Console.WriteLine("request succeed: " + result);
       }
       else
       {
           webClient.Abort();
           webClient.Dispose();
    
           // 记录必要的日志,根据情况决定是否抛出异常
           Console.WriteLine("web request is aborted after timeout");
           // log ......
           // throw new Exception("远程Webservice请求超时");
       }

    完整的Demo:http://files.cnblogs.com/files/zhaoguan_wang/ConsoleApplication1_%E5%BC%82%E6%AD%A5%E8%B0%83%E7%94%A8WebService%E8%B6%85%E6%97%B6%E7%BB%88%E6%AD%A2%E8%AF%B7%E6%B1%82.zip

  • 相关阅读:
    请朋友做事,须以名誉为限,为朋友做事,亦须以名誉为限
    这世上总有一些人记得你,关注着你,牵挂着你
    杏花春雨已不再,牧童遥指已不再,剑门细雨渭城轻尘也都已不再
    如果要你做鲁滨逊,你会选第三型还是第二型的朋友做“礼拜五”呢
    人类最不能伤害的就是自尊
    单靠理论和教训是无济于事的
    交真朋友已是件比较奢侈的事儿
    他一定是一个懂生活、懂人生,爱自己、爱别人的人
    国子监,就是从前的大学
    只有把理想和现实有机结合起来,才有可能成为一个成功之人
  • 原文地址:https://www.cnblogs.com/zhaoguan_wang/p/5849541.html
Copyright © 2020-2023  润新知