1. 程式人生 > >天天寫同步,5種SpringMvc非同步請求瞭解下!

天天寫同步,5種SpringMvc非同步請求瞭解下!

### 引言 說到非同步大家肯定首先會先想到同步。我們先來看看什麼是同步? 所謂**同步**,就是發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回或繼續執行後續操作。 簡單來說,同步就是必須一件一件事做,等前一件做完了才能做下一件事。 **非同步**:非同步就相反,呼叫在發出之後,這個呼叫就直接返回了,不需要等結果。 #### 瀏覽器同步 **瀏覽器發起一個request然後會一直待一個響應response,在這期間裡面它是阻塞的。**比如早期我們在我們在逛電商平臺的時候買東西我們開啟一個商品的頁面,大致流程是不是可能是這樣,每次開啟一個頁面都是由一個執行緒從頭到尾來處理,這個請求需要進行資料庫的訪問需要把商品價格庫存啥的返回頁面,還需要去呼叫第三方介面,比如優惠券介面等我們只有等到這些都處理完成後這個執行緒才會把結果響應給瀏覽器,在這等結果期間這個執行緒只能一直在乾等著啥事情也不能幹。這樣的話是不是會有有一定的效能問題。大致的流程如下: ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201216202852715.png) ### 瀏覽器非同步 為了解決上面同步阻塞的問題,再**Servlet3.0**釋出後,提供了一個新特性:**非同步處理請求**。比如我們還是進入商品詳情頁面,這時候這個前端發起一個請求,然後會有一個執行緒來執行這個請求,這個請求需要去資料庫查詢庫存、呼叫第三方介面查詢優惠券等。這時候這個執行緒就不用幹等著呢。它的任務到這就完成了,又可以執行下一個任務了。等查詢資料庫和第三方介面查詢優惠券有結果了,這時候會有一個新的執行緒來把處理結果返回給前端。這樣的話執行緒的工作量是不超級飽和,需要不停的幹活,連休息的機會都不給了。 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201216203919855.png) - 這個非同步是純後端的非同步,對前端是無感的,非同步也並不會帶來響應時間上的優化,原來該執行多久照樣還是需要執行多久。但是我們的請求執行緒(Tomcat 執行緒)為非同步servlet之後,我們可以立即返回,依賴於業務的任務用業務執行緒來執行,也就是說,Tomcat的執行緒可以立即回收,預設情況下,Tomcat的核心執行緒是10,最大執行緒數是200,我們能及時回收執行緒,也就意味著我們能處理更多的請求,能夠增加我們的吞吐量,這也是非同步Servlet的主要作用。 下面我們就來看看Spring mvc 的幾種非同步方式吧 https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201217004215462.png) 在這個之前我們還是先簡單的回顧下Servlet 3.1的非同步: - 客戶端(瀏覽器、app)傳送一個請求 - Servlet容器分配一個執行緒來處理容器中的一個servlet - servlet呼叫request.startAsync()開啟非同步模式,儲存AsyncContext, 然後返回。 - 這個servlet請求執行緒以及所有的過濾器都可以結束,但其響應(response)會等待非同步執行緒處理結束後再返回。 - 其他執行緒使用儲存的AsyncContext來完成響應 - 客戶端收到響應 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201220001050948.png?) #### Callable ```java /** 公眾號:java金融 * 使用Callable * @return */ @GetMapping("callable") public Callable