cache(缓存)

为什么要用缓存

CDN

缓存分类

server sideNginx、ApacheNginxnginxSquidclient sideweb browser
iris client side

客户端缓存概述

浏览器缓存机制详解

HTML MetaHTTP
HTTPHTML MetaWebHTML
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
HTMLHTTPHTTP
HTTP
  • 浏览器第一次请求流程图


  • 浏览器再次请求时


  • 状态码的区别

#### 关于缓存的请求头说明

ExpiresExpiresWebhttpExpiresHTTP 1.0HTTP 1.1ExpiresGMTExpires:Thu, 31 Dec 2016 23:55:55 GMTHTTP 1.1Cache-Control: max-age=Cache-controlCache-ControlExpiresCache-ControlExpiresmax-ageCache-Controlpublicprivateno-cacheno- storeno-transformmust-revalidateproxy-revalidatemax-age

| 字段名称 | 表示内容 | | :-------: | :----------------------------------------------------------: | | Public | 指示响应可被任何缓存区缓存 | | Private | 指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当前用户的部分响应消息,此响应消息对于其他用户的请求无效 | | no-cache | 指示请求或响应消息不能缓存,该选项并不是说可以设置”不缓存“,而是需要和服务器确认 | | no-store | 在请求消息中发送将使得请求和响应消息都不使用缓存,完全不存下來 | | max-age | 指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。上次缓存时间(客户端的)+max-age(64200s)<客户端当前时间 | | min-fresh | 指示客户机可以接收响应时间小于当前时间加上指定时间的响应 |

提示:response header中,Expires和Cache-Control同时存在时,Cache-Control优先级高于Expires
Last-Modified/If-Modified-SinceLast-Modified/If-Modified-SinceCache-Control
webCache-Controlmax-ageLast-ModifiewebIf-Modified-SincewebIf-Modified-SinceHTTP 200HTTP 304cache
Etag/If-None-MatchEtag/If-None-MatchCache-Control
webApacheETagINodeSizeMTimeHashCache-Controlmax-ageEtagewebIf-None-MatchEtagwebIf-None-Match200304
Last-ModifiedEtagLast-ModifiedEtagHTTP1.1EtagLast-Modified
Last-ModifiedLast-ModifiedEtagLast-ModifiedETagETag

目录结构

clientSide
—— main.go

代码示例

main.go
//包main显示了如何使用`WriteWithExpiration`
//基于“modtime”,如果If-Modified-Since的时间将于之前的对比,如果超出了refreshEvery的范围
//它会刷新内容,否则会让客户端(99.9%的浏览器) 处理缓存机制,它比iris.Cache更快,因为服务器端
//如果没有任何操作,无需将响应存储在内存中。
package main

import (
    "time"
    "github.com/kataras/iris"
)

const refreshEvery = 10 * time.Second

func main() {
    app := iris.New()
    app.Use(iris.Cache304(refreshEvery))
    // 等同于
    // app.Use(func(ctx iris.Context) {
    //     now := time.Now()
    //     if modified, err := ctx.CheckIfModifiedSince(now.Add(-refresh)); !modified && err == nil {
    //         ctx.WriteNotModified()
    //         return
    //     }
    //     ctx.SetLastModified(now)
    //     ctx.Next()
    // })
    app.Get("/", greet)
    app.Run(iris.Addr(":8080"))
}

func greet(ctx iris.Context) {
    ctx.Header("X-Custom", "my  custom header")
    ctx.Writef("Hello World! %s", time.Now())
}

提示

network200304

IRIS服务端缓存

目录结构

clientSide
—— main.go

代码示例

main.go
package main

import (
    "time"
    "github.com/kataras/iris"
    "github.com/kataras/iris/cache"
)

var markdownContents = []byte(`## Hello Markdown

This is a sample of Markdown contents

Features
--------

All features of Sundown are supported, including:

*   **Compatibility**. The Markdown v1.0.3 test suite passes with
    the --tidy option.  Without --tidy, the differences are
    mostly in whitespace and entity escaping, where blackfriday is
    more consistent and cleaner.

*   **Common extensions**, including table support, fenced code
    blocks, autolinks, strikethroughs, non-strict emphasis, etc.

*   **Safety**. Blackfriday is paranoid when parsing, making it safe
    to feed untrusted user input without fear of bad things
    happening. The test suite stress tests this and there are no
    known inputs that make it crash.  If you find one, please let me
    know and send me the input that does it.

    NOTE: "safety" in this context means *runtime safety only*. In order to
    protect yourself against JavaScript injection in untrusted content, see
    [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content).

*   **Fast processing**. It is fast enough to render on-demand in
    most web applications without having to cache the output.

*   **Routine safety**. You can run multiple parsers in different
    goroutines without ill effect. There is no dependence on global
    shared state.

*   **Minimal dependencies**. Blackfriday only depends on standard
    library packages in Go. The source code is pretty
    self-contained, so it is easy to add to any project, including
    Google App Engine projects.

*   **Standards compliant**. Output successfully validates using the
    W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional.

    [this is a link](https://github.com/kataras/iris) `)

//不应在包含动态数据的处理程序上使用缓存。
//缓存是静态内容的一个好的和必须的功能,即“关于页面”或整个博客网站,静态网站非常适合。
func main() {
    app := iris.New()
    app.Logger().SetLevel("debug")
    app.Get("/", cache.Handler(10*time.Second), writeMarkdown)
    // 将其内容保存在第一个请求中并提供服务而不是重新加载内容。
    // 10秒后,它将被清除并重置。
    app.Run(iris.Addr(":8080"))
}

func writeMarkdown(ctx iris.Context) {
    //点击浏览器的刷新按钮多次,你会每10秒钟只看一次这个println
    println("Handler executed. Content refreshed.")
    ctx.Markdown(markdownContents)
}
/* 请注意,`StaticWeb`默认使用浏览器的磁盘缓存
   因此,在任何StaticWeb调用之后注册缓存处理程序
   为了更快的解决方案,服务器不需要跟踪响应
*/

提示

  1. 第一次访问,服务器会返回所有信息,当在缓存时间之内请求服务器,将得到最缓存的信息。过期以后将从新在服务生成。
  2. 适合于静态页面做缓存