Delphi TIDHTTP服务器冻结;呼吁「;OnCommandGet“;开始但永不结束
我有一个基于Delphi2007TNtService的web服务,使用IndyTIdHttpServer组件。服务器工作正常,可以稳定运行数小时。但每隔一段时间(通常3-6小时),它就会结冰 根据我在服务中内置的日志,OnCommandGet调用正在启动,但尚未完成。我在OnCommandGet处理程序的开头和结尾都有线程安全计数器变量。当冻结开始时,可以看到“开始”变量增量,而“结束”计数保持不变 我让服务器保持这样的状态几分钟。有时,一切都“恢复正常”,所有线程都完成了(尽管需要很多分钟)。如果超过几分钟,我会让服务停止。然后我有另一个辅助服务来重新启动它 我的一些OnCommandGet处理程序生成TThread线程。最初我没有设置优先级,而是采用默认值。我能够将冻结与这些线程工作时的时间关联起来。之后我设置优先级:=tpLowest,这似乎在某种程度上缓解了问题 但我还是觉得冷,不知道是什么 它可能是Windows中消耗资源的其他东西吗?(我已经检查了eventvwr日志,没有看到任何内容) 是否有某种方法可以检测哪些线程/上下文正在使用所有内存 下面是我用来创建服务器的代码。不确定这是否会有帮助,因为服务器在启动时似乎工作正常 更新1 @Jerrydoge和@remylebeau指出,需要包括onCommand中的代码。问题是:if…then..else有很多案例和对其他函数的调用。我有返回js和css文件的函数,还有大约50个对其他处理程序的调用。不确定它能提供多少。我真的认为,如果有什么问题的话,可能是这些电话中的某个。我想方法可能是尝试找出谁是罪魁祸首。我写这个问题的一部分可能是为了给你一些建议,让你知道哪些进程在消耗资源。有没有办法获取特定上下文的CPUDelphi TIDHTTP服务器冻结;呼吁「;OnCommandGet“;开始但永不结束,delphi,indy,Delphi,Indy,我有一个基于Delphi2007TNtService的web服务,使用IndyTIdHttpServer组件。服务器工作正常,可以稳定运行数小时。但每隔一段时间(通常3-6小时),它就会结冰 根据我在服务中内置的日志,OnCommandGet调用正在启动,但尚未完成。我在OnCommandGet处理程序的开头和结尾都有线程安全计数器变量。当冻结开始时,可以看到“开始”变量增量,而“结束”计数保持不变 我让服务器保持这样的状态几分钟。有时,一切都“恢复正常”,所有线程都完成了(尽管需要很多分钟)。
ServerIOHandler := TIdServerIOHandlerSSLOpenSSL.Create(self);
ServerIOHandler.SSLOptions.CertFile := 'C:\web\vaut\embeddedanalytics.com.crt';
ServerIOHandler.SSLOptions.KeyFile := 'C:\web\vaut\embeddedanalyticsout.key';
ServerIOHandler.SSLOptions.RootCertFile := 'C:\web\vaut\gd_bundle.crt';
ServerIOHandler.SSLOptions.Method := sslvSSLv23;
ServerIOHandler.SSLOptions.Mode := sslmServer;
IdHTTPServer1 := TIdHTTPServer.Create;
IdHTTPServer1.MaxConnections := FMaxConnections;
IdHTTPServer1.AutoStartSession := True;
IdHTTPServer1.KeepAlive := FGlobalKeepAlive;
IdHTTPServer1.SessionState := True;
IdHTTPServer1.OnCommandGet := MainGet;
IdHTTPServer1.onexception := IdHttpServerexception;
IdHTTPServer1.onlistenexception := IdHttpServerlistenexception;
with idHttpServer1 do begin
onconnect := IdHttpServerConnect;
oncreatesession := IdHttpServerCreateSession;
ondisconnect := IdHttpServerDisconnect;
onsessionend := IdHttpServersessionend;
onsessionstart := IdHttpServersessoinstart;
end;
idHttpServer1.ParseParams := True;
try
CoInitialize(nil);
// Connect to database... Do other initialization stuff
finally
CoUninitialize;
end;
idHttpServer1.OnQuerySSLPort := QuerySSLPort;
idHttpServer1.IOHandler := ServerIOHandler;
idHttpServer1.Bindings.Add.Port := FPort;
idHttpServer1.Bindings.Add.Port := 443;
IdHTTPServer1.Active := True;
更新2
我的代码中有一个过程,使用下面的函数报告当前内存使用情况。我知道这可能是一个单独的问题。但是GetProcessMemoryInfo线程安全吗?因为我没有把它包装在关键部分
function CurrentMemoryUsage: Cardinal;
var
pmc: TProcessMemoryCounters;
begin
pmc.cb := SizeOf(pmc) ;
result := 0;
if GetProcessMemoryInfo(GetCurrentProcess, @pmc, SizeOf(pmc)) then
Result := pmc.WorkingSetSize
else
RaiseLastOSError;
end;
IdHTTPServer1:=TIdHTTPServer.Create代码>对我来说似乎不合适。您是否正在创建已在服务模块上创建的组件的多个实例?然而,问题似乎不在上面的代码中,而是在我们看不到的代码中。很可能,你的一个线程正在做一些不太线程安全的事情。同意。你说你的OnCommandGet
代码冻结了,但你没有显示它的实际代码。@jerrydoge和Remy见Update1。很难做到这一点。但我会考虑如何推广它。当它冻结时,使用调试器进入并找出冻结的位置。该函数可能不是问题的根源。但不要满足于使用调试器获得“肯定”时的“可能”。