在上次關於AF架構的事件模型的隨筆中介紹了AF的事件分發機制,這個事件分發機制比較好的解決了如果通過Web Services來讓用戶端得到伺服器端事件的問題,讓Web Service和Remoting的事件處理模型看上去完全一致,為在AF上開發事件驅動的應用程式帶來極大的便捷。
但是由於這個模型在Web Service模式下是採用的輪詢機制,這種機制會產生這樣的問題:
- 效能問題。每個用戶端都頻繁的輪詢伺服器,在工作站比較多的情況下會給伺服器的負載帶來巨大的壓力。
- 響應延遲。在這種事件分發機制下。事件的響應時延取決於輪詢的頻率,輪詢頻率越高則延遲越小,而頻率越低則延遲越大。
這兩個問題互相矛盾:為了提高事件的響應速度,就必須提高輪詢頻率;而提高了輪詢頻率又會加大伺服器的負載。所以造成了事件響應速度和伺服器負載兩者不可兼得的局面。
為瞭解決這個問題,AF改良了事件分發機制,將事件探測器移到伺服器端,結構如所示:
從結構上來看,沒有太大的變化,主要的改變是將事件探測器從用戶端移動到了伺服器端。用戶端照樣也輪詢事件,但是如果沒有事件,伺服器的這個線程就進入睡眠狀態,不讓它返回。同時該線程每隔一定時間就醒來檢查一下有沒有事件發生。如果有事件就馬上返回。
因為這種輪詢不佔用網路資源,所以可以將伺服器的輪詢間隔時間設定得很短(目前預設值是100ms)。同時因為伺服器Hold了線程,所以用戶端的事件輪詢也可以設定得很短,甚至可以無延遲。
這樣一來,由於是伺服器內部的線程處理,並且擷取事件的操作代價並不高,所以這個事件探測器大部分時間都會是在休眠狀態,因此伺服器並沒有被消耗多少資源。同時由於輪詢不需要遠程傳遞結果,因此可以將輪詢時間設定得非常短,因此也極大的提高了事件的響應速度(原來的事件的最長回應時間是1s,現在是100ms,提高了十倍)。
另外,為了防止用戶端意外的中斷和請求逾時,可以設定一個最長輪詢次數。假如超過了最長輪詢次數,伺服器線程也返回,假如用戶端仍然是活躍的,它馬上會發出一個新的擷取事件請求。然後伺服器又開始進入新的輪詢。