iris:缓存使用

为什么要用缓存

  • 请求更快:通过将内容缓存在本地浏览器或者距离最近的缓存服务器(如CDN),在不影响网站交互的前提下可以大大加快网站加载速度。
  • 节省带宽:对于已经缓存的文件,可以减少请求带宽甚至无需请求网络。
  • 降低服务器压力:在大量用户并发请求的情况下,服务器的性能受到限制,此时将一些静态资源放置在网络的多个节点,可以起到负载均衡的占用,降低服务器压力。

缓存分类

1、缓存分为服务端侧(server side,比如 Nginx、Apache)。服务端缓存又分为代理服务器缓存和反向代理服务器缓存 (也叫网关缓存,比如 Nginx反向代理、nginx缓存、Squid等)
2、客户端侧(client side,比如web browser)。 例如 浏览器缓存

客户端缓存

概述

浏览器缓存机制详解

HTML Meta标签控制缓存(非http协议定义)
非http协议定义的缓存机制,如使用html meta标签,web开发者可以在html页面的节点中加入meta标签,代码如下:

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

上述代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。使用上很简单,但只有部分浏览器可以支持,而且所有缓存代理服务器都不支持,因为代码不解析html内容本身。而广泛应用的还是http头信息来控制缓存,下面我主要介绍httl协议定义的缓存机制。

HTTP头信息控制缓存

  • 浏览器第一次请求流程图
    在这里插入图片描述

  • 浏览器再次请求时

在这里插入图片描述

  • 状态码的区别
    在这里插入图片描述
    关于缓存的请求头说明
  • Expires策略:Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再 次请求。不过Expires是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。Expires的一个缺点就是,返回的到期时 间是服务器端的时间,,用GMT格式的字符串表示,如:Expires:Thu, 31 Dec 2016 23:55:55 GMT。这样存在一个问题,如果客户端的时间与服 务器的时间相差很大(比如时钟不同步,或者跨时区),那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。
  • Cache-control策略(重点关注):Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数 据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。读取缓存数据条件: 上次缓存时间(客户端的)+max-age< 当前时间(客户端的)。Cache-Control值可以是public、private、no-cache、no- store、 no-transform、must-revalidate、proxy-revalidate、max-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-Since:Last-Modified/If-Modified-Since要配合Cache-Control使用
字段名称表示内容
Last-Modified标示这个响应资源的最后修改时间.web服务器在响应请求时,告诉浏览器资源的最后修改时间
If-None-Match当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头If-Modified-Since,表示请求时间.web服务器收到请求后发现有头If-Modified-Since则与被请求资源的最后修改时间进行比对.若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304(无需包体,节省浏览),告知浏览器继续使用所保存的cache
  • Etag/If-None-Match:Etag/If-None-Match也要配合Cache-Control使用
字段名称表示内容
Etagweb服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定).Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的
If-None-Match当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match(Etag的值).web服务器收到请求后发现有头If-None-Match则与被请求资源的相应校验串进行比对,决定返回200或304

既生Last-Modified何生Etag?你可能会觉得使用Last-Modified已经足以让客户端知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

  • Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
  • 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
  • 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形 Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存.Last-Modified与ETag一起使用时,服务器会优先验证ETag
代码
目录结构

主目录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())
}
提示
  • 运行上面代码,打开浏览器调试network工具,查看状态,status列,你会发现有时候是200有时候是304这就告诉你,何时是重新获取,何时是缓存
  • 也可以尝试在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别,注意观察其中的状态

iris服务端缓存

目录结构

主目录serverSide

    —— 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调用之后注册缓存处理程序
   为了更快的解决方案,服务器不需要跟踪响应
*/
提示
  • 第一次访问,服务器会返回所有信息,当在缓存时间之内请求服务器,将得到最缓存的信息。过期以后将从新在服务生成。
  • 适合于静态页面做缓存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值