客戶端的不當使用或serverobject的設計不良,一次服務會常時間執行或長生不死,這常時間佔據伺服器的cpu和資源,影響伺服器對別的客戶的服務,因此,需要設定乙個服務超時時間,如1分鐘、10分鐘,超過這個時間的呼叫就會被強制終止。
如何終止?當然是終止服務的執行緒,但千萬不要使用terminatethread這個api,它太暴力,使執行緒沒有機會執行清理工作,外面也不知道這個執行緒已經被終止,典型的現象就是客戶端收不到任何錯誤,並一直等下去...
如何完全終止執行緒,有人說要靠執行緒內部檢查某個值,然後滿足條件就自己終止,話需不錯,假設執行緒都是我們在伺服器自己建立的,因此可以加入這樣的**,但是,如果執行緒中的某一條語句本身要很長時間呢,這個執行緒還是要等到這個語句執行完畢才有機會來檢查超時條件,但這個時候可能已經超時好多好多了,所以這個方法也不行。
procedure injectproc_abortthread;
begin
//舉發異常,使正常釋放資源
abort;
// raise exception.create(s_calltimeout);
// finally
// endthread(status_timeout);
// end;
end;
procedure safeabortthread(athreadhandle:thandle);
varvthreadcontext:tcontext;
pstack:pdword;
vwaitresult:cardinal;
vsuspendcount:cardinal;
venjected:boolean;
vwaittime:integer;
begin
//在工作執行緒插入abort指令,可能這個指令恰好被try except攔掉,
//所以不停的測試
//等待其執行完畢,不會馬上停止,有時對資料庫的訪問要等近1分鐘才出現異常
sleep(0);
vwaitresult:=windows.waitforsingleobject(athreadhandle,0);
repeat
case vwaitresult of
wait_failed:
begin
tmerrorlog.errorlog.log(syserrormessage(windows.getlasterror),nil,nil);
break;
end;
wait_object_0:
begin
break;
end;
else
begin
venjected:=false;
windows.suspendthread(athreadhandle);
tryvthreadcontext.contextflags:=context_full;
if windows.getthreadcontext(athreadhandle,vthreadcontext) then
begin
if (cardinal(vthreadcontext.eip)<$70000000) then
begin
pstack:=pointer(vthreadcontext.esp);
dec(pstack);
if not isbadwriteptr(pstack,4) then
begin
vthreadcontext.esp:=dword(pstack);
pstack^:=vthreadcontext.eip;
vthreadcontext.eip:=dword(@injectproc_abortthread);
vthreadcontext.contextflags:=context_control;
venjected:=setthreadcontext(athreadhandle,vthreadcontext);
end;
end;
endelse break;
finally
repeat
vsuspendcount:=windows.resumethread(athreadhandle);
until (vsuspendcount<=1) or (vsuspendcount=$ffffffff);
end;
//交出本執行緒執行時間
sleep(0);
//檢查工作執行緒執**況
if venjected then vwaittime:=100
else vwaittime:=0;
vwaitresult:=windows.waitforsingleobject(athreadhandle,vwaittime);
end;
end;
until false;
end;
Fetch超時設定和終止請求
fetch 是乙個新的端獲取資源的介面,用於替換笨重繁瑣xmlhttprequest.它有了request 和 response 以及headers物件的概念,與後端語言請求資源更接近。在使用xmlhttprequest可以設定請求超時時間,可是轉用fetch後,超時時間設定不見了,在網路不可靠的情...
Android Service 終止服務
被啟動型別的服務必須管理它自己的生命週期。也就是說除非系統要 系統記憶體,否則系統不會終止或銷毀這個服務,在onstartcommand 方法返回後,這個服務會繼續執行。因此而這種型別的服務必須通過呼叫stopself 方法或另乙個元件通過呼叫stopservice 方法才能終止。一旦用stopse...
Spring Cloud feign 服務超時處理
spring cloud中,feign和ribbon在整合了hystrix後,可能會出現首次呼叫失敗的問題 造成該問題的原因 hystrix預設的超時時間是1秒,如果超過這個時間尚未響應,將會進入fallback 而首次請求往往會比較慢 因為spring的懶載入機制,要例項化一些類 這個響應時間可能...