• http缓存之304 last-modified,cache-control:max-age,Etag等


    因最近客户端慢的问题,系统分析了下http协议缓存问题。本文主要记录总结http缓存相关知识。

    1. 讨论涉及的要点

    访问返回类

    > 访问返回200 OK

    > 访问返回200 (from memory cache)

    > 访问返回200 (from disk cache)

    > 访问返回304 Not Modified

    头设置类

    > Cache-Control: max-age=604800

    > Expires: Thu, 05 Jan 2017 12:24:24 GMT

    2. 测试环境1

    机器A作为客户端,IP: 10.0.0.2     chrome  版本 55.0.2883.87 m

    机器B作为服务断, IP: 10.0.0.102  nginx 1.1.19 ubuntu 12.04

    3. 测试1 nginx直接作为后端服务器

    1) 修改nginx的配置文件

    location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to index.html
            try_files $uri $uri/ /index.html;
            # Uncomment to enable naxsi on this location
            # include /etc/nginx/naxsi.rules
                                    expires 7d;
        }

    增加了expires 7d;

    2) 修改index.html

    <html>
    <head>
    <title>Welcome to nginx!</title>
    <script type="text/javascript" src="1.js"></script>
    </head>
    <body bgcolor="white" text="black">
    <center><h1>Welcome to nginx!123456</h1></center>
    <a href="1.txt">1.txt</a>
    </body>
    </html>

    增加一个引入js 1.js

    增加一个超链接1.tx

    4.  第一次访问http://10.0.0.102/index.html (记得清理浏览器缓存)

    bh1tk32v.pld

    uxol2rrt.ua3

    上图为index.html请求包

    ojxmnga3.g41

    上图为index.html响应包

    w1kqhjx2.ied

    z4dcet4v.k2y

    上图为1.js请求包

    avmtuhuw.nji

    上图为1.js响应包

    这是index.html和1.js都返回200 ok的情况

    5. 第二次访问http://10.0.0.102/index.html 在地址栏敲回车键

    tyfuxsv0.rkx

    quopghfd.ioi

    上图为index.html请求包

    3vch334v.e1b

    上图为index.html响应包,此时 回 304 Not Modified ,并且服务器仅仅是回了状态码,没有将index.html数据写回客户端

    kkryocuo.jty

    从整个抓包来看,没有看到1.js的请求包,证明此时针对1.js这个文件 连http请求都没有发

    再通过那个超链接做实验发现和1.js一样的结论,第一次回200 OK   第二次之后就会200  from xxx cache

    cache有memory和disk之分,这个很好理解。

    在已经缓存了的情况下:

    在地址栏敲回车,是回304 。  被别人引用或者点击超链接时,回 200  form xxx cache

    参考 http://guojianxiang.com/posts/2015-09-01-About_HttpStatus200_FromCache_And_304_NotModified.html 弯路2

    6. 关于etag

    nginx默认不支持etag, 可以使用插件完成。

    nginx作者对其解释,参考 http://blog.csdn.net/21aspnet/article/details/6604805 

    Nginx中默认没有添加对Etag标识.Igor Sysoev的观点”在对静态文件处理上看不出如何Etag好于Last-Modified标识。”
    Note:
    Yes, it's addition,and it's easy to add, however, I do not see howETag is better than Last-Modified for static files. -Igor Sysoev
    A nice short description is here:
    http://www.mnot.net/cache_docs/#WORK

    7. expires和cache-control中max-age区别

    nginx是在后台指定expires的间隔(比如7天后超期),然后nginx会自动在http头中转换成max-gae的时间,和头中Expires会变换成具体的超期时刻(不是间隔了)

    参考 https://www.bokeyy.com/post/high-performance-web-sites-rule3.html 

    Max-age:在 HTTP 头中按秒指定失效的时间,如下图。好处是不像方法 1(expries) 一样需要定时检查是否过期,一旦过期就需要指定新的时间,坏处是只有 HTTP/1.1 支持

    8. tomcat对304的处理

    分析了tomcat6  阅读其代码 一目了然

    protected boolean checkIfModifiedSince(HttpServletRequest request,
                                             HttpServletResponse response,
                                             ResourceAttributes resourceAttributes)
            throws IOException {
            try {
                long headerValue = request.getDateHeader("If-Modified-Since");
                long lastModified = resourceAttributes.getLastModified();
                if (headerValue != -1) {
    
                    // If an If-None-Match header has been specified, if modified since
                    // is ignored.
                    if ((request.getHeader("If-None-Match") == null)
                        && (lastModified < headerValue + 1000)) {
                        // The entity has not been modified since the date
                        // specified by the client. This is not an error case.
                        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                        response.setHeader("ETag", resourceAttributes.getETag());
    
                        return false;
                    }
                }
            } catch (IllegalArgumentException illegalArgument) {
                return true;
            }
            return true;
    
        }

    HttpServletResponse.SC_NOT_MODIFIED  就是304状态

    resourceAttributes.getLastModified();  读取文件上次修改时间。

    有兴趣的话可以继续分析tomcat对etag的处理。

    --EOF--

  • 相关阅读:
    一个有关FWT&FMT的东西
    【XSY2762】插线板 分块
    【XSY1905】【XSY2761】新访问计划 二分 树型DP
    【XSY2760】nonintersect 计算几何
    【XSY2787】Mythological VII 贪心
    【XSY2786】Mythological VI 数学
    【XSY2785】模型
    【BZOJ4126】【BZOJ3516】【BZOJ3157】国王奇遇记 线性插值
    【XSY2751】Mythological IV 线性插值
    【XSY2750】Mythological V 2-sat
  • 原文地址:https://www.cnblogs.com/simoncook/p/6234948.html
Copyright © 2020-2023  润新知