專案上提出了乙個需求,說是需要做乙個簡單大氣的頁面,上方一排方塊顯示各個市區的當日業務數量,下方是乙個柱狀圖表,動態的顯示當日的業務數量。所謂動態就是要實時的顯示業務數量,如果有業務的增加,數字會跳動,而且柱狀圖也會增長。
按照正常的想法,可以通過非同步載入不斷的向後台發起請求,對業務數量進行查詢,將查詢結果返回到前台後重新整理資料。但是如果採用這種方式,就會有以下幾個問題:
a、間斷的持續非同步訪問後台會對伺服器造成壓力,占用過多的資源。
b、結合業務情況,資料量並不是每分每秒都在變化。如果在一段時間內業務量並沒有變化,前台卻做了多次查詢請求,那麼這些請求相當於是無
意義的請求,進而也浪費了伺服器資源。
其實這個方案的優點在於,實現方式簡單。缺點是會對伺服器造成壓力,消耗不必要的資源。
經過討論之後,部門的大神提出這樣的方案。在後台定時查詢資料庫得到業務數量的統計結果,並將結果儲存在乙個變數裡。前台通過ajax向後台輪詢請求,保持乙個長連線。如果變數中的資料有了變化,則向前臺返回結果,前台重新整理資料,之後發起下乙個長連線請求。這樣,對於後台的訪問次數會減小,幾乎是只有資料變動的時候才會發起新的請求(之所以說是幾乎是因為長連線盡量不要真的一直保持下去,所以在業務量沒有變化的情況下,也會定時的關閉長連線並發起下一次鏈結)。我們將查詢業務量的訪問壓力放在後台與資料庫之間。而這部分壓力對於伺服器來說要比前台多次發起請求要小得多。
就算是查詢資料庫的壓力完全放到了後台和資料庫之間的互動,但是,還是會存在資料量沒有變化的多餘查詢。如果是在業務辦理的同時向後台的變數寫入記錄,就可以讓資料從之前的主動查詢變成被動接受,由拉變推,這樣可以真正的保證資料是實時變化的。但是問題又來了,我們要改造業務生成的方法,同時要做乙個整體的變數以便於獲取。但是這樣實現的工作量太大,而且這個頁面的資料展示只不過是乙個簡單的功能而已,因此我們沒有考慮這種方法。所以最終選擇使用第二種方案來實現這個功能。
a、資料展示
資料展示使用了echarts的柱狀圖顯示。echarts是個很常用的前端圖表外掛程式。不過作為乙個非專業前端碼農,會用就行了。具體怎麼用就直接看官方的文件吧,官方文件就已經很詳細了。
b、長連線發起
我們通過ajax向後台發起非同步請求,並保持長連線。**如下:
//區劃統計長連線查詢
function longpolling() /accept/statistics/wisdomdata/regionquerylongpolling?regioncode=" + regioncode,
data: ,
datatype: "json",
type: "post",
timeout: 20000,//設定為20s後斷開連線
長連線成功返回資料後,我們根據獲取的資料對頁面資料進行重新整理。因為使用的是echarts的柱狀圖,所以只需要重新封裝echarts的資料,然後呼叫mychart的setoption方法將資料重新裝載,就可以完成圖表的重新整理了。其實因為只是資料在變化,我們只需要將後台返回的資料放到乙個陣列裡,然後修改series的data值即可。**如下:
function refresh(data)
後台邏輯實現氛圍兩部分。一部分是響應前台請求,返回改變後的資料。另一部分是單獨的乙個執行緒,不斷的對資料庫進行查詢獲取最新的資料。
a、資料查詢
我們先來看看後台與資料庫互動的部分,這部分需要實現下面的功能:
要把實時查詢出來的資料儲存在後台以供前台隨時獲取。解決方法是使用乙個內部類對資料進行儲存。
**如下:
class regionquery;
string regionnamearray = ;
regioncodelist = arrays.aslist(regionarray);
regionnamelist = arrays.aslist(regionnamearray);
this.isopen= false;
}public boolean isopen()
public void setopen(boolean open)
}
要不間斷的對資料庫中的資料進行查詢。解決方法是在第一次訪問這個頁面時,啟動乙個執行緒對資料庫進行迴圈查詢,並將資料儲存在後台內部類。
**片段如下:
//開啟乙個執行緒來獲取regionquery類的資料,這個執行緒是寫在剛進入展示頁面的方法中
if (!regionquery.isopen())
jsonobject result = new jsonobject();
result.put("code", system_error);
try
thread.sleep(1000);//等待一秒鐘保持連線
}} catch (exception e)
this.renderjson(response, result.tostring());// 返回資料
}
這個案例的核心在於兩點,第一點,是使用長連線保持前台與後台之間的連線,只有資料改變時再返回資料。第二點,是在後台丟擲乙個執行緒不斷的對資料庫進行查詢,並將結果儲存到乙個內部類裡。整體實現了查詢資料和展示動態資料的分離,減少前台頁面對伺服器的訪問壓力。畢竟自己的技術不夠成熟,對於方案的實現,依舊會有考慮欠缺的地方,希望有大神能夠指正。
同時,這個案例也有很多需要改進的地方,比如,丟擲的用來查詢資料的執行緒沒有結束的時候,就會一直跑下去,這一點應該會造成隱患。也許我們可以根據,是否還有人保留這個資料展示頁面,來控制這個執行緒的狀態。這就等以後有時間的時候,再去研究啦。
長連線與短連線
通常短連線是這樣 連線 傳輸資料 關閉連線 那什麼是長連線?一般長連線相對短連線而言的,長連線在傳輸完數後不關閉連線,而不斷的傳送包保持連線等待處理下乙個資料報。such as 連線 傳輸資料 保持連線 傳輸資料 關閉連線。那什麼時候用短連線呢?一般長連線用於少數client end to serv...
長連線與短連線
短連線是指通訊雙方有資料互動時,就建立乙個tcp連線,資料傳送完成後,則斷開此tcp連線,一般銀行都使用短連線。比如http的,只是連線 請求 關閉,過程時間較短,伺服器若是一段時間內沒有收到請求即可關閉連線。其實長連線是相對於通常的短連線而說的,也就是長時間保持客戶端與服務端的連線狀態。通常的短連...
長連線與短連線
其實長連線是相對於通常的短連線而說的,也就是長時間保持客戶端與服務端的連線狀態。連線 資料傳輸 關閉連線 這就要求長連線在沒有資料通訊時,定時傳送資料報 心跳 以維持連線狀態,短連線在沒有資料傳輸時直接關閉就行了 長連線多用於操作頻繁,點對點的通訊,而且連線數不能太多情況,每個tcp連線都需要三步握...