異步有什麼好處?
從客戶端發出一次請求至tomcat容器大致經過如下過程:
客戶端發出http請求至tomcat的連接監聽端口;
tomcat connector接收線程接收請求,並根據http協議解析該次請求;
tomcat 通過解析的http報文,初始化org.apache.coyote.Request,並實例化org.apache.coyote.Response;
經裝飾模式轉化爲servlet api對應的HttpServletRequest與HttpServletReponse;
經tomcat的層層容器engine,host,context最終到過我們所寫的業務servlet的service方法;
業務方法service,處理相關的業務邏輯,寫入相應的響應的至response,並返回tomat的容器組件;
tomcat該處理線程關閉響應流Response並將響應內容返回客戶端;
tomcat該處理線程被釋放,然後用於下次請求的處理;
servlet3異步化
客戶端發出http請求至tomcat的連接監聽端口;
tomcat connector接收線程接收請求,並根據http協議解析該次請求;
tomcat 通過解析的http報文,實例化org.apache.coyote.Request,並實例化org.apache.coyote.Response;
經裝飾模式轉化爲servlet api對應的HttpServletRequest與HttpServletReponse;
經tomcat的層層容器engine,host,context最終到過我們所寫的業務servlet的service方法;
業務方法開啓異步化上下文AsynContext;釋放tomcat當前處理線程;
tomcat判斷當前請求是否開啓了異步化,如果開啓則不關閉響應流Response,也不進行用戶響應的返回;
tomcat該線程被釋放,然後用於下次請求的處理,提高其吞吐量;
業務方法在AsynContext環境中完成業務方法的處理,調用其complete方法,將響應寫回響應流,並關閉響應流,完成此次請求處理.
所以用一句話總結servlet3的基本原理就是:網絡連接依舊在,提前釋放tomcat處理線程用於提高吞吐量,響應流不關閉,由業務方法自己處理。從這個角度來看基於servlet3的異步化完全有可能實現真正的服務端push。但異步化對響應時間並沒有多大影響,甚至不一定比同步響應時間短。它只是提高了吞吐量。讓線程物盡其用。
怎麼配置呢?
如果什麼都不配置,在使用異步都時候會報錯:!AsyncSupport
那麼怎麼配置呢?
基本上所有鏈都需要配置了。
在xml裏,
對於servlet要這樣配置了。
<servlet>
<servlet-name>AsyncServlet</servlet-name>
<servlet-class>cc.openhome.AsyncServlet</servlet-class>
<async-supported>true</async-supported>
</servlet>
那麼filter依然要配置這個
<async-supported>true</async-supported>
甚至如果你用springmvc.xml,那麼<mvc:annotions/>這個表情裏面也要添加上面那個異步支持。
如果你要是使用註解,不管是@WebServlet還是@WebFiter,都需要加上:,asyncSupported = true,就像下面這個一樣。
@WebServlet(value = "aaa",asyncSupported = true)