非同步 Servlet 最佳作法

非同步 Servlet 特性可讓您處理送入的要求和回應,而不需連結至起始要求的原始執行緒。

使用非同步 Servlet 時,請考量下列最佳作法:
  • 應用程式不應針對每一個需要的非同步作業大量產生新的執行緒。 應用程式至少應該使用執行緒儲存區或使用 AsyncContext start (Runnable) 方法。
  • 在用戶端/瀏覽器端,您可以使用 AJAX 來非同步更新頁面的某些部分。
  • Servlet 儲存器可確保在起始 startAsync 指令的 Web 儲存器執行緒存在之前,不會啟動完成或分派的呼叫。 不過, Servlet 儲存器不會同時使用相同的要求和回應來處理多個執行緒。 在此情況下,應用程式可以處理自己的並行或同步化問題,但不建議這樣做,因為它可能很容易發生死鎖或競爭狀況。 如果從客戶建立的執行緒或以 start (Runnable) 啟動的可執行執行緒呼叫分派或完成方法,則分派或完成可以在新執行緒上立即啟動,且從起始這些呼叫的執行緒對要求或回應進行任何進一步修改都是危險的。 兩個執行緒將具有要求及回應的存取權,如果這兩個執行緒都在修改這些物件,則可能會有不確定的結果。 因此,在從呼叫分派的相同執行緒進行分派之後,請勿對要求或回應呼叫任何方法。 在呼叫完成作業之後,請勿對要求或回應呼叫任何方法。
  • 非同步接聽器有一個 onTimeout 方法,當達到非同步作業的時間限制時即會啟動。 不過,非同步作業可能仍在一個執行緒上執行,而 onTimeout 則在另一個執行緒上執行。 此實務範例是多個執行緒不小心同時使用相同要求及回應的最常見方式。 此實務範例的簡單方法是使用 AsyncListener 和非同步作業中的共用 AtomicBoolean 方法,如下所示:
    AtomicBoolean isOkayToRun = (AtomicBoolean) request.getAttribute("isOkayToRun");
    if (isOkayToRun.setAndGet(false)){ 	
    		//do a dispatch 
    }
    使用此方法,只有一個執行緒可以取得寫入回應的存取權。
  • 當達到逾時時時, Web 儲存器會嘗試取消由對 start (Runnable) 方法的呼叫所排入佇列的任何可執行檔。 不過,已啟動的可執行檔無法岔斷,因為岔斷會導致記憶體洩漏。
  • 執行逾時通知的執行緒數目非常小。 不建議嘗試任何密集作業或逾時的任何寫入作業,因為如果用戶端連線緩慢,即使小型寫入作業也可能需要一些時間。 當您停用非同步逾時時時,更容易發生 OutOfMemory 錯誤或耗盡 TCP 通道連線數。 預設逾時為 30 秒。
  • 您可以在管理主控台中按一下 伺服器 > 伺服器類型 > WebSphere 應用程式伺服器 > server_name > Web 儲存器設定 > Web 儲存器,來配置一些非同步 Servlet 選項,例如逾時設定和 AsyncContext 啟動 (可執行) 方法。 請參閱 Web 儲存器設定主題,以瞭解如何配置 Web 儲存器。
重要事項: 當使用非同步 Servlet 時,不支援非同步要求分派器 (ARD) 和遠端要求分派器 (RRD)。
提示: 檢視 Web 應用程式計數器主題,以瞭解非同步 Servlet 的度量值。