2. 秒殺-頁面優(yōu)化

1.頁面緩存

想象一下秒殺的場(chǎng)景,僧多粥少,在秒殺將要開始的半分鐘內(nèi),用戶可能會(huì)不斷刷新秒殺頁面,此時(shí)對(duì)于頁面訪問的流量將達(dá)到頂峰。

解決方案

  1. 服務(wù)端緩存頁面:
    在服務(wù)端手動(dòng)渲染商品詳情頁面,直接返回html給前端
    將頁面加入redis緩存,設(shè)置合適的,較短的有效期,比如60s
    每次請(qǐng)求都先從redis中取,取不到再渲染并返回
  2. 客戶端緩存頁面:
    同時(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ì)更好。

  1. 這里thymeleaf的渲染畢竟還是在服務(wù)端完成的,如果有前端人員支持的話,可以考慮下最近流行的angular、veu,實(shí)現(xiàn)徹底的前后端分離。前端發(fā)起請(qǐng)求,后端將商品信息緩存到redis,前端渲染頁面,緩存頁面。將工作量分擔(dān)給無數(shù)個(gè)客戶端,減輕服務(wù)端壓力。
  2. 靜態(tài)資源壓縮,js css html等進(jìn)行壓縮,降低流量消耗
  3. nginx靜態(tài)資源緩存

附:所有代碼在github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容