技术积淀----NGINX缓存

整洁的代码,合理的架构是一个性能卓越的应用不可或缺的优点 。同时在很多案例中,开发者投入一些精力在一些最基本的技术上,也可以带来非常大的性能提升 。这些基础的技术包括就包括缓存技术 。本文主要介绍下如何利用Nginx缓存提升系统性能 。
nginx常常被当做反向代理、负载均衡器 。同时nginx还具备强大的缓存特性,接下来我们将介绍如何配置nginx缓存 。
 
如何配置最基础的缓存 。使用最基本的缓存功能,只需要两个NGINX指令:proxy_cache_path 和 proxy_cache 。proxy_cache_path 指令设置缓存路径和一些缓存配置,proxy_cache 指令用来使用NGINX缓存 。

技术积淀----NGINX缓存

文章插图
 
proxy_cache_path 指令包含下面这些配置:
/path/to/cache/ 指定缓存存放的磁盘目录 。
levels=1:2 设置缓存存放的目录结构为两级,这个也是官方推荐的设置 。设置默认是一级目录结构,实验表明在大量缓存文件被频繁读取的场景,文件读取性能会降低 。
keys_zone 设置一个共享的区域,用来存放缓存的key以及元数据,用来计算定时,缓存是不是命中等信息 。1M的共享区域可以存储大约8000个key,本例子设置的10M,大约可以存储8万个key 。
max_size 设置允许nginx缓存使用的最大磁盘空间,比如本例子中允许使用的最大空间是10G,如果不设置,表示允许使用所有的磁盘空间 。如果缓存占用达到了设置的上限,缓存管理器会自动移除最近最少使用的数据 。
inactive 指定一个缓存项最大多长时间,不被使用将被删除 。本例子中设置的是60m,表示如果一个缓存项,超过60分钟没有被再次请求,那么缓存管理器会自动删除此缓存,不管缓存是不是过期 。inactive 内容和缓存过期(Expired)是两个不同的概念 。Nginx不会自动删除缓存过期的内容,Expired (stale)内容只会在Inactive时间到了后,才会被缓存管理器删除 。
use_temp_path 官方推荐设置为off,用来改变nginx默认首次缓存文件被写入临时文件 。设置为off后,缓存文件将不会先写入临时文件,然后后续移动到缓存目录,避免缓存文件被copy带来的系统开销 。
最后proxy_cache 指令用来控制如何使用nginx缓存,如上面例子,请求满足配置规则进入location,请求到的内容将会被缓存 。
【技术积淀----NGINX缓存】proxy_cache 也可以在直接在server指令的作用域设置,如果location没有设置proxy_cache,那么将直接使用server的缓存设置 。
 
NGINX中缓存的key是什么格式?nginx默认的缓存key 是$scheme$proxy_host$request_uri,然后做MD5 hash 。$schema是nginx内置的变量,表示http 或者https 。$proxy_host,$request_uri如何理解,请看下面的例子 。
技术积淀----NGINX缓存

文章插图
 
http://www.example.org/my_image.jpg请求对于上面的配置,缓存key就应该是md5(“http://my_upstream:80/my_image.jpg”) 。
大家注意到$proxy_host被用在了生成缓存key 。$proxy_host如何理解呢?location中proxy_pass指令指定的名字和端口,端口默认是80 。
同时nginx缓存也支持,用户自定义缓存的key,可以通过proxy_cache_key 进行设置,比如proxy_cache_key $uri$is_args$args;
ps: $is_args 代表请求中的 ?
 
如何指定缓存过期时间?要理清楚此问题,首先需要了解http请求,是如何控制缓存的以及如何校验缓存是不是失效 。
缓存控制大家最常见到的是Pragma,Cache-Control,Expires关键字 。
http不同的版本控制缓存方式是不一样的,我们先讲http1.0,1.0时代控制比较简单:Pragma: no-cache时,表示禁用缓存,Expires的值是一个GMT时间,表示该缓存的有效时间,但是实际使用的时候,本地时间和服务器时间可能不一致 。
http1.1通过Cache-Control来控制缓存 。使用Last-Modified,或者etag来校验缓存 。
首先讲一下Last-Modified 。服务端在返回资源时,会将该资源的最后更改时间通过Last-Modified字段返回给客户端 。客户端下次请求时通过If-Modified-Since或者If-Unmodified-Since带上Last-Modified,服务端检查该时间是否与服务器的最后修改时间一致:如果一致,则返回304状态码,不返回资源;如果不一致则返回200和修改后的资源,并带上新的时间,如下图:
技术积淀----NGINX缓存

文章插图
 
单纯的以修改时间来判断还是有缺陷,比如文件的最后修改时间变了,但内容没变 。对于这样的情况,我们可以使用etag来处理 。


推荐阅读