执行POST

时间:2016-05-04 15:27:55

标签: xmlhttprequest msxml serverxmlhttp

我有一份工作,定期执行一些涉及ServerXmlHttpRquest的工作来执行HTTP POST。这项工作每60秒运行一次。

通常它没有问题。但是大约有五分之一的机会(每两三个月)它会挂起:

IXMLHttpRequest http = new ServerXmlHttpRequest();

http.open("POST", deleteUrl, false, "", "");
http.send(stuffToDelete); <---hang

当它挂起时,甚至任务计划程序(如果运行时间超过3分钟,启用了杀死作业的选项)都可以结束任务。我必须连接到远程客户的网络,进入服务器,并使用任务管理器来终止进程。

然后再过一个月或三个月。

最终我开始使用任务管理器创建进程转储

enter image description here

所以我可以分析挂起的位置。经过五次崩溃后(过去11个月左右),我得到了一致的图片:

ntdll.dll!_NtWaitForMultipleObjects@20()  
KERNELBASE.dll!_WaitForMultipleObjectsEx@20()
user32.dll!MsgWaitForMultipleObjectsEx()
user32.dll!_MsgWaitForMultipleObjects@20()
urlmon.dll!CTransaction::CompleteOperation(int fNested) Line 2496
urlmon.dll!CTransaction::StartEx(IUri * pIUri, IInternetProtocolSink * pOInetProtSink, IInternetBindInfo * pOInetBindInfo, unsigned long grfOptions, unsigned long dwReserved) Line 4453    C++
urlmon.dll!CTransaction::Start(const wchar_t * pwzURL, IInternetProtocolSink * pOInetProtSink, IInternetBindInfo * pOInetBindInfo, unsigned long grfOptions, unsigned long dwReserved) Line 4515    C++
msxml3.dll!URLMONRequest::send()
msxml3.dll!XMLHttp::send()
Contoso.exe!FrobImporter.TFrobImporter.DeleteFrobs Line 971
Contoso.exe!FrobImporter.TFrobImporter.ImportCore Line 1583
Contoso.exe!FrobImporter.TFrobImporter.RunImport Line 1070
Contoso.exe!CommandLineProcessor.TCommandLineProcessor.HandleFrobImport Line 433
Contoso.exe!CommandLineProcessor.TCommandLineProcessor.CoreExecute Line 71
Contoso.exe!CommandLineProcessor.TCommandLineProcessor.Execute Line 84
Contoso.exe!Contoso.Contoso Line 167
kernel32.dll!@BaseThreadInitThunk@12()
ntdll.dll!__RtlUserThreadStart()
ntdll.dll!__RtlUserThreadStart@8()

所以我做了ServerXmlHttpRequest.send,它永远不会回来。它将在那里呆上几天(导致系统错过金融交易,直到周日晚上我接到一个电话,它已经坏了)。

除非有人知道如何调试代码,否则没有任何帮助,但转储时陷入停顿的线程中的寄存器是:

EAX 00000030
EBX 00000000
ECX 00000000
EDX 00000000
ESI 002CAC08
EDI 00000001
EIP 732A08A7
ESP 0018F684
EBP 0018F6C8
EFL 00000000 
  • Windows Server 2012 R2
  • Microsoft IIS / 8.5

ServerXmlHttpRequest的默认超时

您可以使用serverXmlHttpRequest.setTimeouts(...)配置四类超时:

  • resolveTimeout :该值适用于将主机名(例如“www.microsoft.com”)映射到IP地址;默认值为无限,表示没有超时。
  • connectTimeout :一个长整数。该值适用于与目标服务器建立通信套接字,默认超时值为60秒。
  • sendTimeout :该值适用于将通信套接字上的请求数据(如果有)的单个数据包发送到目标服务器。发送到服务器的大量请求通常会被分解为多个数据包;发送超时适用于单独发送每个数据包。默认值为 30秒
  • receiveTimeout :该值适用于从目标服务器接收响应数据包。大响应将被分解为多个数据包;接收超时适用于从套接字中提取每个数据包。默认值为 30秒

KB305053(决定保持连接打开的服务器将导致serverXmlHttpRequest等待连接关闭)似乎可能是问题。但是30秒的默认超时会解决这个问题。

可能的解决方法 - 将自己添加到作业

Windows任务计划程序无法终止任务;即使该选项已启用即可。

我将研究使用Windows Job API将 self 进程添加到作业,并使用SetInformationJobObject为我的进程设置时间限制:

将我的流程限制为三分钟的执行时间:

  

PerProcessUserTimeLimit
  如果 LimitFlags 指定    JOB_OBJECT_LIMIT_PROCESS_TIME ,此成员是每个进程   用户模式执行时间限制,以100纳秒为单位。除此以外,   该成员被忽略。

     

系统会定期检查以确定   与工作相关的每个流程是否累积得更多   用户模式时间超过设置限制。如果有,那么过程是   终止。

     

如果作业是嵌套的,则有效限制最多   工作链中的限制性限制。

虽然由于Task Scheduler使用Job对象也限制了任务的时间,但我并不希望Job Object可以限制作业。

修改:作业对象无法按处理时间限制流程 - 仅限用户时间。并且当一个进程空闲等待一个对象时,它不会累积任何用户时间 - 当然不会超过三分钟。

奖金阅读

1 个答案:

答案 0 :(得分:1)

考虑切换到更新的受支持API。

不再支持msxml3.dll库,仅出于兼容性原因而保留。另外,msxml4.dll(和更新版本)中包含了许多security and stability improvements,你错过了这些内容。