常見的頁面優化技術
頁面的優化技術分為:緩存和,頁面靜态化,靜态資源優化,CDN優化等
其中緩存分為: 頁面緩存+url緩存+對象緩存
頁面緩存
也沒緩存的時間比較短的。比如10秒鐘的緩存時間失效
思路: 擷取頁面緩存,沒有的時候重新擷取頁面然後進行渲染,然後傳回
使用 Thymeleaf 的話,Springboot中有ThymeleafViewResolver可以幫助我們擷取到頁面的模闆
ThymeleafViewResolver
這個方法可以得到一個模闆的引擎,這個類的父類 TemplateEngine,其中的process方法是關鍵
其中的IContext這個類的參數,可以通過 SpringWebContext
SpringWebContext
SpringWebContext ctx = new SpringWebContext(request,response,
request.getServletContext(),request.getLocale(), model.asMap(), applicationContext );
渲染模闆
html = thymeleafViewResolver.getTemplateEngine().process("goods_list", ctx);
Controller方法上加入produces="text/html"
重新我們之前的GoosController的商品清單
此時這個Controller方法傳回的是一個頁面,是以需要 @ResponseBody進行标記
/**
* 使用頁面緩存技術
* @param model
* @param user
* @return
* @throws Exception
*/
@RequestMapping(value="/toListCache", produces="text/html")
@ResponseBody
public String toListWithPageCache(HttpServletRequest request, HttpServletResponse response,Model model , User user) throws Exception {
if(user == null) {
return "login";
}
model.addAttribute("user", user);
//擷取頁面緩存
RedisServiceProxy proxy = new RedisServiceProxy(GoodsKey.GOODS_LIST,redisService);
String html = proxy.getBean("", String.class);
if(!StringUtils.isEmpty(html)) {
return html;
}
//查詢商品資訊
List<GoodsVo> goodsList = goodsService.listGoods();
model.addAttribute("goodsList", goodsList);
//頁面緩存的核心東西,渲染頁面
SpringWebContext ctx = new SpringWebContext(request,response,
request.getServletContext(),request.getLocale(), model.asMap(), applicationContext );
//手動渲染
html = thymeleafViewResolver.getTemplateEngine().process("goods_list", ctx);
if(!StringUtils.isEmpty(html)) {
proxy.setBean("", html);
}
return html;
}
檢視redis
注意點
頁面的緩存呢其實呢是user不一樣而已,其他的對大部分使用者來說是一樣的。
但是呢如果是一個詳情頁面,那麼就有問題了。
是以這也就是url緩存的概念了
也就是将使用者在url中的參數作為頁面緩存key的一部分。
這樣不同的使用者看到的詳情頁是不一樣的
Url緩存
這個是對頁面緩存的進一步利用,參數作為key的一部分。
比如我們的商品詳情頁面,url中有一個參數 商品id
/**
* 使用緩存的例子
* @param model
* @param user
* @param goodsId
* @return
* @throws Exception
*/
@RequestMapping(value="/to_detailCache/{goodsId}",produces="text/html")
@ResponseBody
public String detailWithCache(HttpServletRequest request, HttpServletResponse response, Model model,User user,
@PathVariable("goodsId")Long goodsId) throws Exception {
model.addAttribute("user", user);
//擷取頁面緩存
RedisServiceProxy proxy = new RedisServiceProxy(GoodsKey.GOODS_DETAIL,redisService);
String html = proxy.getBean(""+goodsId, String.class);
if(!StringUtils.isEmpty(html)) {
return html;
}
GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
model.addAttribute("goods", goods);
long startAt = goods.getStartDate().getTime();
long endAt = goods.getEndDate().getTime();
long now = System.currentTimeMillis();
int miaoshaStatus = 0;
int remainSeconds = 0;
if(now < startAt ) {//秒殺還沒開始,倒計時
miaoshaStatus = 0;
//機關是毫秒
remainSeconds = (int)((startAt - now )/1000);
}else if(now > endAt){//秒殺已經結束
miaoshaStatus = 2;
remainSeconds = -1;
}else {//秒殺進行中
miaoshaStatus = 1;
remainSeconds = 0;
}
model.addAttribute("miaoshaStatus", miaoshaStatus);
model.addAttribute("remainSeconds", remainSeconds);
SpringWebContext ctx = new SpringWebContext(request,response,
request.getServletContext(),request.getLocale(), model.asMap(), applicationContext );
html = thymeleafViewResolver.getTemplateEngine().process("goods_detail", ctx);
if(!StringUtils.isEmpty(html)) {
proxy.setBean(""+goodsId, html);
}
return html;
}
對象緩存
将對象化成json然後存入到redis中再從redis中擷取到就是對象緩存。
緩存中沒有的時候才會查詢資料庫.
之前的User對象的擷取就是這種形式的
更新注意緩存的更新
是以對于頁面上的一些表示對象可以進行緩存。
但是呢如果遇到了更新的話,我們更新完資料庫之後,要處理緩存的。
先更新資料庫,然後更新緩存,保證緩存的一緻性。
注意一定要更新資料庫,之後再進行緩存的更新。
因為如果調用順序之後呢,就會先加載緩存,然後更新,資料庫的資料被更新了,是最新的,造成了資料不一緻
注意了調用呢,一定要調用Service
service中可能是使用了緩存的,直接使用dao就可能造成這個緩存的不一緻。
緩存的目的
減少對資料庫的通路。
基本上保證在60秒内可以不通路 mysql資料庫,直接從redis中擷取的。
這樣系統的負載就隻展現在 java 和redis程序上面。
消滅掉mysql的負載