目錄
優化策略
- 合併請求
- 數據併發處理
- 數據異步渲染
對於系統首頁的處理數據量不大,可以通過合併請求的方式實現。
後端代碼可以通過併發多線程的方式處理數據訪問,縮短等待時間。
前端html渲染異步化, 可以避免頁面渲染和數據互相等待。
JSON格式模塊化
{
"HNGS_GSWH_GSGS": [
{
"JJ": "額",
"BT": "測試",
"NR": "<p>vd</p>",
"SJ": 1582905600000,
"MZGUID": "202002/d539bbc653c44fa1b194cac4b11486c5.png",
"PK_UID": 2
},
{
"JJ": "好幾款發過火",
"BT": "豆腐花多少",
"NR": "<p>東方國際地方發動機的</p>",
"SJ": 1578931200000,
"MZGUID": "202001/3c1fca05ced647aa902df4a0ffa19e52.jpg",
"PK_UID": 1
}
],
"HNGS_GZDT": [
{
"BT": "工作動態:湖南古樹名木運維繫統就要上線了",
"FBSJ": 1572364800000,
"PK_UID": 3
},
{
"BT": "工作動態:林業工作彙報",
"FBSJ": 1572278400000,
"PK_UID": 1
},
{
"BT": "圖片上傳",
"FBSJ": 1573747200000,
"PK_UID": 52
},
{
"BT": "工作動態:嚴格按照章程作業",
"FBSJ": 1572364800000,
"PK_UID": 2
}
],
"HNGS_GSWH_XCQH": [
{
"BT": "阿斯蒂芬",
"SJ": 1572537600000,
"PK_UID": 1
}
],
"HNGS_GSWH_ZXTC": [
{
"BT": "都發過火鳳凰",
"SJ": 1570982400000,
"MZGUID": "201912/2015年10月木材戰略儲備基地建設珍貴用材樹種培育技術管理培訓班資料彙編(201510).pdf",
"PK_UID": 1
}
],
"HNGS_SWFC": [
{
"BT": "東安古銀杏,樹齡2500年",
"GSZP": "201911/f0576ca5f5cd4fbea1172915dd7dee9e.png",
"PK_UID": 1
},
{
"BT": "茶亭奇樹-惜字塔百年古樸",
"GSZP": "201911/db8d6ad88f2444518cc6516bb65a7e88.jpg",
"PK_UID": 2
},
{
"BT": "黃巢吊馬樟",
"GSZP": "201911/db8d6ad88f2444518cc6516bb65a7e89.jpg",
"PK_UID": 3
},
{
"BT": "龍華山下的綠色明珠-雙江鎮古樟",
"GSZP": "201911/db8d6ad88f2444518cc6516bb65a7e90.jpg",
"PK_UID": 4
},
{
"BT": "中國杉樹王",
"GSZP": "201911/db8d6ad88f2444518cc6516bb65a7e92.jpg",
"PK_UID": 5
},
{
"BT": "瀏陽千年古樟",
"GSZP": "201911/db8d6ad88f2444518cc6516bb65a7e91.png",
"PK_UID": 6
},
{
"BT": "維新鎮千年重陽木",
"GSZP": "201911/db8d6ad88f2444518cc6516bb65a7e93.jpg",
"PK_UID": 7
},
{
"BT": "323",
"GSZP": "202002/a34b609bc3c7437e9a43f1cd1d70ed38.png",
"PK_UID": 16
}
],
"HNGS_SY_GJGSZS_V": [
{
"CODE": "43",
"ZZS": "2476",
"YJZS": "124",
"SJZS": "2114",
"MMZS": "6",
"EJZS": "232"
}
],
"HNGS_XCP": [
{
"JJ": "<p>郴州甦仙區有對千年夫妻銀杏古樹</p>",
"BT": "郴州甦仙區有對千年夫妻銀杏古樹",
"FBSJ": 1573488000000,
"SPDZ": "93fafb19-8a41-46de-aec1-330fef136016",
"FBR": "ysw",
"SFZD": "1",
"MZGUID": "29c5debb-631c-4538-8cde-b8ddd7f92a65",
"PK_UID": 51,
"LY": "網絡"
},
{
"JJ": "<p>郴州資興市東江河畔發現罕見楠木古樹羣</p>",
"BT": "郴州資興市東江河畔發現罕見楠木古樹羣",
"FBSJ": 1573488000000,
"MZGUID_PATH": "202001/947919d204d14be1ac165cdb58997647.png",
"SPDZ": "e7908c79-9bf6-4bc6-8fa1-b63d48e501ef",
"FBR": "ysw",
"SPDZ_PATH": "201911/7296c26dc15f42c0af2a39d1aa700705.mp4",
"SFZD": "1",
"MZGUID": "69555d67-dd67-42fc-906c-612d1478ebed",
"PK_UID": 52,
"LY": "網絡"
},
{
"JJ": "<p>湖南:平江驚現樹齡千年以上紅豆杉</p>",
"BT": "湖南:平江驚現樹齡千年以上紅豆杉",
"FBSJ": 1573488000000,
"MZGUID_PATH": "202001/c793842f23a44dc49e4296b6198fe76d.png",
"SPDZ": "d32b92c2-47ee-4220-b1af-982539d863c4",
"FBR": "ysw",
"SPDZ_PATH": "201911/a95c347f00374bd5872880606c3f9701.mp4",
"SFZD": "1",
"MZGUID": "36d019cc-ea5a-4cf5-af20-f0ca16cd7e81",
"PK_UID": 53,
"LY": "網絡"
},
{
"JJ": "<p>湖南永順千年古樹聚焦的原始森林(2014)</p>",
"BT": "湖南永順千年古樹聚焦的原始森林",
"FBSJ": 1573488000000,
"MZGUID_PATH": "202001/d0696765e8d74656b78d2e808359f14d.png",
"SPDZ": "77e23dd2-f189-42ae-875f-a09d419b1d8b",
"FBR": "ysw",
"SPDZ_PATH": "201911/2ebaa1c019554dbe90c1bfbab6f9109a.mp4",
"SFZD": "1",
"MZGUID": "16072c0e-b8ce-4c92-8cac-56592c1d009a",
"PK_UID": 54,
"LY": "網絡"
},
{
"JJ": "<p>懷化芷江侗塞發現珍稀古樹羣</p>",
"BT": "懷化芷江侗塞發現珍稀古樹羣",
"FBSJ": 1573488000000,
"MZGUID_PATH": "202001/035272c3b3aa4630aaa057d35eb0d0ee.png",
"SPDZ": "61863c28-28e2-4ead-a6f8-0e1dedf599f2",
"FBR": "ysw",
"SPDZ_PATH": "201911/07513323381b432f937915521f6ce40a.mp4",
"SFZD": "1",
"MZGUID": "edee8c4e-0468-43d7-a232-85afd8e3d5f5",
"PK_UID": 55,
"LY": "網絡"
},
{
"JJ": "<p>邵陽城步:千年紫薇樹需6人合抱</p>",
"BT": "邵陽城步:千年紫薇樹需6人合抱",
"FBSJ": 1573488000000,
"MZGUID_PATH": "202001/6caa3c20fbb24d87b6e95aacfa4b298b.png",
"SPDZ": "08aed5a5-d4a6-4629-be53-9be68e093551",
"FBR": "ysw",
"SPDZ_PATH": "201911/70bc1b6325f348548d716c043bd14480.mp4",
"SFZD": "1",
"MZGUID": "114e030c-05a2-4d1c-8c93-c803889caad7",
"PK_UID": 56,
"LY": "網絡"
},
{
"JJ": "<p>湘西瀘溪發現2000多株古樹羣落</p>",
"BT": "湘西瀘溪發現2000多株古樹羣落",
"FBSJ": 1573488000000,
"MZGUID_PATH": "202001/abba3eb846e14a86af902d0543005a2d.png",
"SPDZ": "7def7c5c-8e92-4632-a71d-6442f1857c63",
"FBR": "ysw",
"SPDZ_PATH": "201911/952cbabdff9f4fee887f840da4c4a4e3.mp4",
"SFZD": "1",
"MZGUID": "622c258b-e306-4e81-87a7-6920514d9cee",
"PK_UID": 57,
"LY": "網絡"
},
{
"JJ": "<p>永州東安白竹村定下永不賣古樹村規民約</p>",
"BT": "永州東安白竹村定下永不賣古樹村規民約",
"FBSJ": 1573488000000,
"MZGUID_PATH": "202001/45513d65fadb4157ab425b522f1bff0b.png",
"SPDZ": "f697b858-a324-49d7-8e88-275c46b017a0",
"FBR": "ysw",
"SPDZ_PATH": "201911/8d191e27652748e6a54248b837fece91.mp4",
"SFZD": "1",
"MZGUID": "0fa0bdea-05dd-4e80-851d-33298d527c84",
"PK_UID": 58,
"LY": "網絡"
}
],
"HNGS_TZGG": [
{
"BT": "通知公告:湖南古樹名木移動端APP應用已提測",
"FBSJ": 1572451200000,
"PK_UID": 34
},
{
"BT": "通知公告:湖南古樹名木系統運維信息信息發佈功能即將發佈",
"FBSJ": 1572364800000,
"PK_UID": 33
},
{
"BT": "通知公告:2019年古樹名木研究報告會議",
"FBSJ": 1573747200000,
"PK_UID": 54
},
{
"BT": "通知公告:湖南古樹名木業務系統進入測試階段",
"FBSJ": 1572364800000,
"PK_UID": 32
},
{
"BT": "通知公告:建國70週年安全檢查與消防演練",
"FBSJ": 1572278400000,
"PK_UID": 31
},
{
"BT": "關於開展全省古樹名木資源普查工作的通知 ",
"FBSJ": 1455465600000,
"PK_UID": 52
}
],
"HNGS_ZCFG": [
{
"BT": "政策法規:運維測試記錄",
"FBSJ": 1574092800000,
"PK_UID": 55
},
{
"BT": "古樹名木普查技術規範(試行)",
"FBSJ": 1573488000000,
"PK_UID": 51
},
{
"BT": "古樹名木鑑定標準(試行)",
"FBSJ": 1573488000000,
"PK_UID": 50
},
{
"BT": "中華人民共和國環境保護法",
"FBSJ": 1400860800000,
"PK_UID": 54
},
{
"BT": "中華人民共和國野生植物保護條例",
"FBSJ": 844012800000,
"PK_UID": 53
}
],
"HNGS_KPBK": [
{
"BT": "湖南省關於古樹名木申報的通知",
"FBSJ": 1570982400000,
"PK_UID": 2
},
{
"BT": "湖南省關於古樹名木申報的通知",
"FBSJ": 1570377600000,
"PK_UID": 3
},
{
"BT": "湖南省關於古樹名木申報的通知",
"FBSJ": 1569686400000,
"PK_UID": 1
},
{
"BT": "ssssss",
"FBSJ": 1577376000000,
"PK_UID": 50
}
],
"HNGS_ZTHD": [
{
"BT": "英雄聯盟常規賽",
"HDJSSJ": 1577894400000,
"HDKSSJ": 1577030400000,
"NUM": 5,
"PK_UID": 14
},
{
"BT": "\"親自林\"(小樹苗因你的呵護而茁壯成長)",
"HDJSSJ": 1571846400000,
"HDKSSJ": 1570982400000,
"NUM": 5,
"PK_UID": 7
}
]
}
請求處理併發化
模塊任務拆分
接口併發處理
public Map<String,Object> getIndexData(HttpServletRequest request,HttpServletResponse response){
Map<String, Object> result = new HashMap<String, Object>();
/*String[] tables = new String[]{"HNGS_SWFC","HNGS_SY_GJGSZS_V",
"HNGS_TZGG","HNGS_GZDT","HNGS_ZCFG","HNGS_KPBK","HNGS_GSWH_GSGS",
"HNGS_GSWH_XCQH","HNGS_GSWH_ZXTC","HNGS_XCP","HNGS_ZTHD"};
System.out.println(JSONObject.toJSONString(tables));*/
ExecutorService executorService = Executors.newCachedThreadPool();
// 列舉FutureTask任務
FutureTask<Object> lbtTask = new FutureTask<Object>(new LbtTask(indexDataService));
executorService.execute(lbtTask);
FutureTask<Object> gstjTask = new FutureTask<Object>(new GstjTask(indexDataService));
executorService.execute(gstjTask);
FutureTask<Object> commonTaskTZGG = new FutureTask<Object>(new CommonTask("HNGS_TZGG",indexDataService));
executorService.execute(commonTaskTZGG);
FutureTask<Object> commonTaskGZDT = new FutureTask<Object>(new CommonTask("HNGS_GZDT",indexDataService));
executorService.execute(commonTaskGZDT);
FutureTask<Object> commonTaskZCFG = new FutureTask<Object>(new CommonTask("HNGS_ZCFG",indexDataService));
executorService.execute(commonTaskZCFG);
FutureTask<Object> commonTaskBPBK = new FutureTask<Object>(new CommonTask("HNGS_KPBK",indexDataService));
executorService.execute(commonTaskBPBK);
FutureTask<Object> gsgsTask = new FutureTask<Object>(new GsgsTask(indexDataService));
executorService.execute(gsgsTask);
FutureTask<Object> xcqhTask = new FutureTask<Object>(new XcqhTask(indexDataService));
executorService.execute(xcqhTask);
FutureTask<Object> zxtcTask = new FutureTask<Object>(new ZxtcTask(indexDataService));
executorService.execute(zxtcTask);
FutureTask<Object> xcpTask = new FutureTask<Object>(new XcpTask(indexDataService));
executorService.execute(xcpTask);
FutureTask<Object> zthdTask = new FutureTask<Object>(new ZthdTask(indexDataService));
executorService.execute(zthdTask);
try {
result.put("HNGS_SWFC", lbtTask.get());
result.put("HNGS_SY_GJGSZS_V", gstjTask.get());
result.put("HNGS_TZGG", commonTaskTZGG.get());
result.put("HNGS_GZDT", commonTaskGZDT.get());
result.put("HNGS_ZCFG", commonTaskZCFG.get());
result.put("HNGS_KPBK", commonTaskBPBK.get());
result.put("HNGS_GSWH_GSGS", gsgsTask.get());
result.put("HNGS_GSWH_XCQH", xcqhTask.get());
result.put("HNGS_GSWH_ZXTC", zxtcTask.get());
result.put("HNGS_XCP", xcpTask.get());
result.put("HNGS_ZTHD", zthdTask.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
注意:FutureTask get()方法是同步方法,這裏沒有所謂的CountDownLatch控制。 雖然都是等待,但耗時最短可達到單個模塊最長的數據處理耗時。
請求處理併發化更優的解決方法
下圖參考自:https://blog.csdn.net/u011726984/article/details/79320004
代碼改造:CompletableFuture和CompletionService。
/**
* 首頁數合併請求處理
* @param request
* @param response
* @return
*/
@SuppressWarnings("unchecked")
@RequestMapping({ "/getIndexData.web" })
@ResponseBody
public Map<String,Object> getIndexData(HttpServletRequest request,HttpServletResponse response){
Map<String, Object> result = new HashMap<String, Object>();
/*String[] tables = new String[]{"HNGS_SWFC","HNGS_SY_GJGSZS_V",
"HNGS_TZGG","HNGS_GZDT","HNGS_ZCFG","HNGS_KPBK","HNGS_GSWH_GSGS",
"HNGS_GSWH_XCQH","HNGS_GSWH_ZXTC","HNGS_XCP","HNGS_ZTHD"};
System.out.println(JSONObject.toJSONString(tables));*/
// 是否使用JDK1.8特性
if(ConfigUtil.THREAD_WORKER_USE_JDK8){
// 解決線程先後執行完成順序問題,線程池是一個重量級的資源分配操作,不宜頻繁初始化
//CompletionService<Object> completionService=new ExecutorCompletionService<Object>(executorService);
// 列舉CompletableFuture任務
CompletableFuture<Object> lbtTask = CompletableFuture.supplyAsync(new LbtTask(indexDataService), executorService);
CompletableFuture<Object> gstjTask = CompletableFuture.supplyAsync(new GstjTask(indexDataService), executorService);
CompletableFuture<Object> commonTaskTZGG = CompletableFuture.supplyAsync(new CommonTask("HNGS_TZGG",indexDataService), executorService);
CompletableFuture<Object> commonTaskGZDT = CompletableFuture.supplyAsync(new CommonTask("HNGS_GZDT",indexDataService), executorService);
CompletableFuture<Object> commonTaskZCFG = CompletableFuture.supplyAsync(new CommonTask("HNGS_ZCFG",indexDataService), executorService);
CompletableFuture<Object> commonTaskBPBK = CompletableFuture.supplyAsync(new CommonTask("HNGS_KPBK",indexDataService), executorService);
CompletableFuture<Object> gsgsTask = CompletableFuture.supplyAsync(new GsgsTask(indexDataService), executorService);
CompletableFuture<Object> xcqhTask = CompletableFuture.supplyAsync(new XcqhTask(indexDataService), executorService);
CompletableFuture<Object> zxtcTask = CompletableFuture.supplyAsync(new ZxtcTask(indexDataService), executorService);
CompletableFuture<Object> xcpTask = CompletableFuture.supplyAsync(new XcpTask(indexDataService), executorService);
CompletableFuture<Object> zthdTask = CompletableFuture.supplyAsync(new ZthdTask(indexDataService), executorService);
try {
result.put("HNGS_SWFC", lbtTask.get());
result.put("HNGS_SY_GJGSZS_V", gstjTask.get());
result.put("HNGS_TZGG", commonTaskTZGG.get());
result.put("HNGS_GZDT", commonTaskGZDT.get());
result.put("HNGS_ZCFG", commonTaskZCFG.get());
result.put("HNGS_KPBK", commonTaskBPBK.get());
result.put("HNGS_GSWH_GSGS", gsgsTask.get());
result.put("HNGS_GSWH_XCQH", xcqhTask.get());
result.put("HNGS_GSWH_ZXTC", zxtcTask.get());
result.put("HNGS_XCP", xcpTask.get());
result.put("HNGS_ZTHD", zthdTask.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}else{
// 解決線程先後執行完成順序問題,線程池是一個重量級的資源分配操作,不宜頻繁初始化
CompletionService<Object> completionService=new ExecutorCompletionService<Object>(executorService);
// 列舉FutureTask任務
Future<Object> lbtTask = completionService.submit(new LbtTask(indexDataService));
Future<Object> gstjTask = completionService.submit(new GstjTask(indexDataService));
Future<Object> commonTaskTZGG = completionService.submit(new CommonTask("HNGS_TZGG",indexDataService));
Future<Object> commonTaskGZDT = completionService.submit(new CommonTask("HNGS_GZDT",indexDataService));
Future<Object> commonTaskZCFG = completionService.submit(new CommonTask("HNGS_ZCFG",indexDataService));
Future<Object> commonTaskBPBK = completionService.submit(new CommonTask("HNGS_KPBK",indexDataService));
Future<Object> gsgsTask = completionService.submit(new GsgsTask(indexDataService));
Future<Object> xcqhTask = completionService.submit(new XcqhTask(indexDataService));
Future<Object> zxtcTask = completionService.submit(new ZxtcTask(indexDataService));
Future<Object> xcpTask = completionService.submit(new XcpTask(indexDataService));
Future<Object> zthdTask = completionService.submit(new ZthdTask(indexDataService));
try {
result.put("HNGS_SWFC", lbtTask.get());
result.put("HNGS_SY_GJGSZS_V", gstjTask.get());
result.put("HNGS_TZGG", commonTaskTZGG.get());
result.put("HNGS_GZDT", commonTaskGZDT.get());
result.put("HNGS_ZCFG", commonTaskZCFG.get());
result.put("HNGS_KPBK", commonTaskBPBK.get());
result.put("HNGS_GSWH_GSGS", gsgsTask.get());
result.put("HNGS_GSWH_XCQH", xcqhTask.get());
result.put("HNGS_GSWH_ZXTC", zxtcTask.get());
result.put("HNGS_XCP", xcpTask.get());
result.put("HNGS_ZTHD", zthdTask.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
}
前端渲染異步化
/**
* 初始化表單
*/
function init() {
/**
* 異步Ajax請求
*/
$.ajax({
url : 'data/getIndexData.web',
data : {},
type : 'post',
cache : true,
async:true,
dataType : 'json',
success : function(data) {
queryCallback(data);
},
error : function(evt) {
mini.alert("請求失敗,請重試!");
}
});
}
/**
* 頁面數據查詢回調函數
*/
function queryCallback(data){
//輪播圖
lbtData(data.HNGS_SWFC);
//古樹統計
gstjData(data.HNGS_SY_GJGSZS_V);
//通知公告
index_common_data("HNGS_TZGG",".tzgg-c ul",data.HNGS_TZGG);
//延遲加載
setTimeout(function (){
index_common_data("HNGS_GZDT",".zxkd-c ul",data.HNGS_GZDT);
index_common_data("HNGS_ZCFG",".zcfg-c ul",data.HNGS_ZCFG);
index_common_data("HNGS_KPBK",".kpbk-c ul",data.HNGS_KPBK);
},3000);
//延遲加載
setTimeout(function(){
//鄉愁情懷
xcqhData(data.HNGS_GSWH_XCQH);
//在線圖冊
zxtcData(data.HNGS_GSWH_ZXTC);
//專題活動
zthdData(data.HNGS_ZTHD);
//index_dbsx();
//szjd();
//古樹故事
gsgsData(data.HNGS_GSWH_GSGS);
//宣傳片
xcpData(data.HNGS_XCP);
},1000);
}