SpringBoot电商秒杀项目优化知识点总结(第六章)

这里写目录标题

  • 6-1 静态资源cdn引入(上)
  • 6-2 静态资源cdn引入(下)
  • 6-3 静态资源cdn深入讲解---Cache Control响应头
  • 6-4 静态资源cdn深入讲解---浏览器三种刷新方式
  • 6-5 静态资源cdn深入讲解---CDN自定义缓存策略
  • 6-6 静态资源cdn深入讲解---静态资源部署策略
  • 6-7 全页面静态化技术引入
  • 6-8 商品详情页全页面静态化(上)

6-1 静态资源cdn引入(上)

dns服务器将静态资源的请求路由到对应的cdn(内容分发网络 即无限大的内容磁盘缓存) 当用户要访问静态资源文件时 cdn只需要根据路由规则查看本地是否有此文件 有则直接返回 没有则回源到源站 取得静态资源文件后 一边将其返回 一边按照http指定的生命周期缓存起来

6-2 静态资源cdn引入(下)

1.注册域名
2.根据域名和服务器ip新建cdn
3.将得到的cname配置到域名的解析规则

6-3 静态资源cdn深入讲解—Cache Control响应头

private:客户端可以缓存
public:客户端和代理服务器都可以缓存
max-age=xxX∶缓存的内容将在xxx秒后失效
no-cache:强制向服务端再验证一次(会将数据缓存在客户端 但在下次使用时会像服务端验证此缓存是否能使用)
no-store :不缓存请求的任何返回内容

有效性判断
ETag :资源唯─标识
If-None-Match :客户端发送的匹配Etag标识符
Last-modified :资源最后被修改的时间多多改日
If-Modified-Since:客户端发送的匹配资源最的标识符

6-4 静态资源cdn深入讲解—浏览器三种刷新方式

回车刷新或a链接:看cache-control对应的max-age是否仍然有效,有效则直接from cache,若cache-control中为no-cache,则进入缓存协商逻辑
F5刷新或command+R刷新:去掉cache-control中的max-age或直接设置max-age为0,然后进入缓存协商逻辑
ctrl+F5或commond+shift+R刷新:去掉cache-control和协商头,强制刷新

6-5 静态资源cdn深入讲解—CDN自定义缓存策略

可自定义目录过期时间
可自定义后缀名过期时间
可自定义对应权重
可通过界面或api强制cdn对应目录刷新(非保成功)

6-6 静态资源cdn深入讲解—静态资源部署策略

1.1css,js,img等元素使用带版本号部署,例如a.js?v=1.0
缺点:基于文件级别的更新不便利 且维护困难 若只更新了一部分文件 那没有变动的文件的版本号是否需要也改变?
浏览器如果不强制清除缓存 则缓存时长以max-age为准 由于css js img都内嵌在html中
第一种方式:html文件必须设置为no-cache 即每次访问必须向服务器验证 所以处于性能考虑 html中的内容不能有太多
第二种方式:html会采取强推策略 html可以设置max-age为较短时间 并在更新时强制让所有cdn失效
第三种方式:让html文件尽可能小 减少发生变化的次数

1.2css,js,img等元素使用带摘要部署,例如a.js?v=45edw
缺点:存在先部署html还是先部署资源的覆盖问题
js会覆盖 html也会覆盖 性能html不能访问原js 原html也不一定能访问新js

1.3css,js,img等元素使用摘要做文件名部署,例如45edw.js
优点(采用此策略):新老版本并存且可回滚,资源部署完后再部署html

2.1对应静态资源保持生命周期内不会变,max-age可设置的很长,无视失效更新周期

2.2html文件设置no-cache或较短max age,以便于更新

2.3html文件仍然设置较长的max age,依靠动态的获取版本号请求发送到后端,异步下载最新的版本号的html后展示渲染在前端:html启动的时候都有一个ajax请求头带着版本号请求服务端调用动态接口 从而得知是否为最新版 若不是则重新渲染一遍 完成之后再推到前端 即异步更新策略(采用此策略)

3.1动态请求也可以静态化成json资源推送到cdn上

3.2依靠异步请求获取后端节点对应资源状态做紧急下架处理

3.3可通过跑批紧急推送cdn内容以使其下架等操作

6-7 全页面静态化技术引入

定义︰在服务端完成html , css,甚至js的load渲染成纯html文件后直接以静态资源的方式部署到cdn上

phantomjs的应用:
修改需要全页面静态化的实现,采用initView和hasInit方式防止多次初始化
编写对应轮讯生成内容方式
将全静态化页面生成后推送到cdn

6-8 商品详情页全页面静态化(上)

修改getitem.html

<html>
<head>
    <meta charset="UTF-8">
    <link href="static/assets/global/plugins/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
    <link href="static/assets/global/css/components.css" rel="stylesheet" type="text/css"/>
    <link href="static/assets/admin/pages/css/login.css" rel="stylesheet" type="text/css"/>
    <script src="static/assets/global/plugins/jquery-1.11.0.min.js" type="text/javascript">script>
    <script src="./gethost.js" type="text/javascript">script>
    <title>Titletitle>
head>
<body class="login">
<div class="content">
    <h3 class="form-title">product detailsh3>
    <div id="promoStartDateContainer" class="form-group">
        <label style="color:blue" id="promoStatus" class="control-label">label>
        <div>
            <label style="color:red" class="control-label" id="promoStartDate" />
        div>
    div>
    <div class="form-group">
        <div>
            <label class="control-label" id="title" />
        div>
    div>
    <div class="form-group">
        <div>
            <img style="width:200px;height:auto;" id="imgUrl">
        div>
    div>
    <div class="form-group">
        <label class="control-label">descriptionlabel>
        <div>
            <label class="control-label" id="description" />
        div>
    div>
    <div id="normalPriceContainer" class="form-group">
        <label class="control-label">pricelabel>
        <div>
            <label class="control-label" id="price" />
        div>
    div>
    <div id="promoPriceContainer" class="form-group">
        <label style="color:red" class="control-label">Promotional pricelabel>
        <div>
            <label style="color:red" class="control-label" id="promoPrice" />
        div>
    div>
    <div class="form-group">
        <label class="control-label">stocklabel>
        <div>
            <label class="control-label" id="stock" />
        div>
    div>
    <div class="form-group">
        <label class="control-label">saleslabel>
        <div>
            <label class="control-label" id="sales" />
        div>
    div>
    <div class="form-actions">
        <button class="btn blue" id="createOrder" type="submit">
            Buy now
        button>
    div>

    <input type="hidden" id="isInit" value="0">
div>
body>

<script>
    var g_itemVO = {};

    function hasInit() {
        var isInit = $("#isInit").val();
        return isInit;
    }

    function setHasInit() {
        $("#isInit").val("1");
    }

    function initView() {
        var isInit = hasInit();
        if (isInit == "1") {
            return;
        }
        // 获取商品详情
        $.ajax({
            type: "GET",
            url: "http://"+g_host+"/item/get",
            data: {
                "id": getParam("id"),
            },
            xhrFields:{
                withCredentials:true
            },
            success: function(data) {
                if (data.status == "success") {
                    g_itemVO = data.data;
                    reloadDom();
                    setInterval(reloadDom, 1000);
                    setHasInit();
                } else {
                    alert("Failed to get information due to " + data.data.errMsg);
                }
            },
            error: function(data) {
                alert("Failed to get information due to " + data.responseText);
            }
        });
    }

    $(document).ready(function() {
        // 获取商品详情
        initView();

        $("#createOrder").on("click", function() {
            var token = window.localStorage["token"];
            if (token == null) {
                alert("Not logged in, can't place an order.");
                window.location,href="login.html";
                return false;
            }
            $.ajax({
                type: "POST",
                url: "http://"+g_host+"/order/createorder?token="+token,
                contentType: "application/x-www-form-urlencoded",
                data: {
                    "itemId": g_itemVO.id,
                    "promoId": g_itemVO.promoId,
                    "amount": 1,//暂时写死为一件
                },
                xhrFields:{
                    withCredentials:true
                },
                success: function(data) {
                    if (data.status == "success") {
                        alert("successfully ordered");
                        window.location.reload();
                    } else {
                        alert("The order failed, the reason is " + data.data.errMsg);
                        if (data.data.errCode == 20003) {
                            window.location.href="login.html";
                        }
                    }
                },
                error: function(data) {
                    alert("The order failed, the reason is " + data.responseText);
                }
            });
        });
    });
    function reloadDom() {
        $("#title").text(g_itemVO.title);
        $("#imgUrl").attr("src", g_itemVO.imgUrl);
        $("#description").text(g_itemVO.description);
        $("#price").text(g_itemVO.price);
        $("#stock").text(g_itemVO.stock);
        $("#sales").text(g_itemVO.sales);
        if (g_itemVO.promoStatus == 1) {
            // 秒杀活动还未开始
            console.log(g_itemVO.startDate);
            var startTime = g_itemVO.startDate.replace(new RegExp("-", "gm"), "/");
            startTime = (new Date(startTime)).getTime();
            var nowTime = Date.parse(new Date());
            var delta = (startTime - nowTime) / 1000;
            if (delta <= 0) {
                // 活动开始了
                g_itemVO.promoStatus = 2;
                reloadDom();
            }
            $("#promoStartDate").text("The seckill event will be sold on the "+g_itemVO.startDate+"with a "+delta+"-second countdown");
            $("#promoPrice").text(g_itemVO.promoPrice);
            $("#createOrder").attr("disabled", true);
        } else if (g_itemVO.promoStatus == 2) {
            // 秒杀活动进行中
            $("#promoStartDate").text("The promotion is in progress");
            $("#promoPrice").text(g_itemVO.promoPrice);
            $("#createOrder").attr("disabled", false);
            $("#normalPriceContainer").hide();
        }
    }
    function getParam(paramName) {
        paramValue = "", isFound = !1;
        if (this.location.search.indexOf("?") == 0 && this.location.search.indexOf("=") > 1) {
            arrSource = unescape(this.location.search).substring(1, this.location.search.length).split("&"), i = 0;
            while (i < arrSource.length && !isFound)
                arrSource[i].indexOf("=") > 0 && arrSource[i].split("=")[0].toLowerCase() == paramName.toLowerCase() && (paramValue = arrSource[i].split("=")[1], isFound = !0), i++
        }
        return paramValue == "" && (paramValue = null), paramValue
    }
script>
html>

在phantomjs/js/getitem.js中写入

var page = require("webpage").create();
var fs = require("fs");
page.open("http://seckillserver.psj14.com/resources/getitem.html?id=1",function(status) {
	console.log("status = " + status);
	var isInit = "0";
	setInterval(function(){
		if (isInit != "1") {
			page.evaluate(function(){
				initView();
			});
			isInit = page.evaluate(function(){
				return hasInit();
			});
		}else{
			fs.write("getitemphantom.html",page.content,"w");
			phantom.exit();
		}
	},1000);
});

setInterval为定时器 设置每隔一秒执行一次
page.evaluate用于调用前端js中的initView()方法

你可能感兴趣的:(SpringBoot项目,java,服务器,开发语言)