1.頁面緩存
想象一下秒殺的場(chǎng)景,僧多粥少,在秒殺將要開始的半分鐘內(nèi),用戶可能會(huì)不斷刷新秒殺頁面,此時(shí)對(duì)于頁面訪問的流量將達(dá)到頂峰。
解決方案
- 服務(wù)端緩存頁面:
在服務(wù)端手動(dòng)渲染商品詳情頁面,直接返回html給前端
將頁面加入redis緩存,設(shè)置合適的,較短的有效期,比如60s
每次請(qǐng)求都先從redis中取,取不到再渲染并返回 - 客戶端緩存頁面:
同時(shí)可以設(shè)置瀏覽器緩存該頁面60s,這樣在此期間瀏覽器、服務(wù)器就沒有數(shù)據(jù)交互了
@GetMapping(value="/goods2",produces="text/html")
@ResponseBody
public String findAllGoods2(Model model,HttpServletRequest request, HttpServletResponse response){
//TODO 此處想設(shè)置瀏覽器緩存該頁面60s,但是好像不管用啊
response.setHeader("Cache-Control", "max-age:60");
//先從緩存中取,沒有再渲染
String html = redisTemplate.opsForValue().get("goods");
if(!StringUtils.isEmpty(html)) {
return html;
}
List<Goods> goods = goodsService.findAllGoods();
model.addAttribute("goods",goods);
//設(shè)置秒殺開始時(shí)間 為了使用緩存,當(dāng)前時(shí)間使用客戶端自己的時(shí)間
model.addAttribute("targetTime",Constant.BARGAIN_DASH_START_TIME);
//手動(dòng)渲染
WebContext ctx = new WebContext(request,response,
request.getServletContext(),request.getLocale(), model.asMap());
html = thymeleafViewResolver.getTemplateEngine().process("goods", ctx);
//將結(jié)果加入redis,設(shè)置有效期60s
if(!StringUtils.isEmpty(html)) {
redisTemplate.opsForValue().set("goods", html, 60, TimeUnit.SECONDS);
}
return html;
}
由于商品頁面比較固定,客戶端對(duì)于頁面實(shí)時(shí)更新要求不會(huì)很高,所以可以加入redis緩存起來。
由于redis緩存了頁面,所以頁面的倒計(jì)時(shí)效果只能取客戶端的時(shí)間作為當(dāng)前時(shí)間了。在真正秒殺的時(shí)候,服務(wù)端會(huì)對(duì)秒殺是否開始了做一次判斷。其實(shí),即使采用服務(wù)端時(shí)間做當(dāng)前時(shí)間,倒計(jì)時(shí)也不可能完全準(zhǔn)確,最好還是后端再做判斷,所以這里直接采用客戶端的時(shí)間做當(dāng)前時(shí)間,也是合適的。
我想在服務(wù)端指定客戶端緩存該頁面60s,但是實(shí)際測(cè)試好像沒效果,仍然會(huì)每次都發(fā)get請(qǐng)求,可能是哪里沒有設(shè)置對(duì)吧。如果可以在瀏覽器緩存,將會(huì)更進(jìn)一步提高性能。
這里前端頁面倒計(jì)時(shí)效果,使用的是tictac,是從github上搜索來的,這種小組件,直接上github上找,比百度要更快更好。
壓力測(cè)試
優(yōu)化的商品列表
可以看到,該優(yōu)化的效果還是極為明顯的。
2.其他優(yōu)化點(diǎn)
目前代碼主要是從后端進(jìn)行了優(yōu)化,如果有專業(yè)前端支持,前后端共同協(xié)作,效果會(huì)更好。
- 這里thymeleaf的渲染畢竟還是在服務(wù)端完成的,如果有前端人員支持的話,可以考慮下最近流行的angular、veu,實(shí)現(xiàn)徹底的前后端分離。前端發(fā)起請(qǐng)求,后端將商品信息緩存到redis,前端渲染頁面,緩存頁面。將工作量分擔(dān)給無數(shù)個(gè)客戶端,減輕服務(wù)端壓力。
- 靜態(tài)資源壓縮,js css html等進(jìn)行壓縮,降低流量消耗
- nginx靜態(tài)資源緩存
附:所有代碼在github上