1. 程式人生 > >spring非同步請求action以及預設配置坑爹的效能以及對應效能調優

spring非同步請求action以及預設配置坑爹的效能以及對應效能調優

前言

非同步請求----客戶端一旦發起請求,伺服器立刻將請求丟到其他執行緒處理,而當前的接收執行緒就能閒下來繼續接收客戶端請求了,這個看起來效能槓槓的,這篇文章就來入坑非同步請求。

spring非同步請求的配置

預設配置下的非同步請求效能表現

進行這個操作前,請先確認已經配置好了,然後能夠執行起來,還有,順便看一看visual vm的用法,這次要實踐了。
jvm效能監控–visualvm的簡單說明及用法

正式開始:
注意,
在這裡插入圖片描述

mvc:async-support是在mvc:annotation-driven下面配置的,而不是task:annotation-driven,還有,mvc:annotation-driven是在spring-mvc.xml下配置的—即,這些個配置都是mvc上下文下面的,因為controller本來就在mvc上下文下面。。
不要配錯了!

編寫action程式碼,設定sleep為的是模擬耗時操作:
在這裡插入圖片描述

然後啟動伺服器,訪問這個api:
在這裡插入圖片描述

好了,開啟jvisual vm 工具:

在這裡插入圖片描述

可以看到tomcat已經在了,開啟,分別檢視幾個標籤,記住執行緒總數,活動執行緒數量。

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

var Ajax={
  get: function(url, fn) {
    // XMLHttpRequest物件用於在後臺與伺服器交換資料   
    var xhr = new XMLHttpRequest();            
    xhr.open('GET', url, true);
    xhr.onreadystatechange = function() {
      // readyState == 4說明請求已完成
      if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304) { 
        // 從伺服器獲得資料 
        fn.call(this, xhr.responseText);  
      }
    };
    xhr.send();
  },
  // datat應為'a=a1&b=b1'這種字串格式,在jq裡如果data為物件會自動將物件轉成這種字串格式
  post: function (url, data, fn) {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", url, true);
    // 新增http頭,傳送資訊至伺服器時內容編碼型別
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");  
    xhr.onreadystatechange = function() {
      if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
        fn.call(this, xhr.responseText);
      }
    };
    xhr.send(data);
  }
};
var __call_times=0;
var _call_interval=setInterval(function(){ 
__call_times++;
Ajax.get('/api/region/getChildrenByCallable.do',function(){ console.log('呼叫中...');});
if(__call_times>1000){
clearInterval(_call_interval);
}
 }, 10);

然後:

在這裡插入圖片描述

在這裡插入圖片描述

然後,檢視jvisual vm,觀測執行緒情況:

在這裡插入圖片描述

在這裡插入圖片描述

活動執行緒已經有了 MvcAsync等等命名的執行緒了,那麼已經完成的執行緒有:

在這裡插入圖片描述

隔一段時間再看:

在這裡插入圖片描述

活動執行緒有:
在這裡插入圖片描述

已經完成的執行緒有:

在這裡插入圖片描述

可以認為,預設的非同步請求處理方式是不停新建一個新的執行緒,這樣還真的有點坑爹,詳情可以參考下面文章,作者也是深深被坑過的兄dei:

那麼,解決方案是什麼?

非同步請求處理效能優化方案

解決方案是,定義一個專用執行緒池,替換掉spring的預設執行緒池。

在這裡插入圖片描述

注意,在 mvc:async-support 標籤裡設定 task-executor。
然後,重啟伺服器,重複上述步驟:
在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

好了,開動瀏覽器,測試:

第一次觀測:
在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

從這裡起碼可以看出來,已經採用了定製的執行緒池了。。因為。。連執行緒的名字都變了,變成actionAsyncExecutor+編號形式。

隔一段時間來看:
在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

看到這裡已經可以放心了。。
沒有新的執行緒產生,一直都是那幾個執行緒在忙,執行緒也不會變更為完成狀態直接退休。
這是解決方案之一。

總結

這篇非同步請求處理以及效能調休的篇幅雖然不多,然而裡面涉及的東西是相當多的。有興趣的話可以親自動手試試,保證有所收穫的。