Nginx作为缓存服务

一、缓存类型

1、服务端缓存

Nginx作为缓存服务

2、代理缓存

Nginx作为缓存服务

3、客户端缓存

Nginx作为缓存服务

4、代理缓存的工作流程:

Nginx作为缓存服务

二、代理缓存配置语法

1、代理缓存路径

配置语法

Syntax:    proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Default:    —
Context:    http

定义缓存目录空间大小和名字。

可参考 http_proxy_module中proxy_cache官网文档:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_path

2、配置代理缓存

配置语法:

Syntax:    proxy_cache zone | off;
Default:
proxy_cache off;
Context:    http, server, location

zone : 就是上一步所配置的proxy_cache_path 中 path 的名字。表示缓存存入哪个路径。

3、缓存过期时间

配置语法:

Syntax:    proxy_cache_valid [code ...] time;
Default:    —
Context:    http, server, location

code : http 状态码。

例如配置 proxy_cache_valid 200 12h 意思是状态码为 200 的 缓存 12个小时。

4、缓存的维度

Syntax:    proxy_cache_key string;
Default: proxy_cache_key $scheme$proxy_host$request_uri;
Context: http, server, location
proxy_cache_key $scheme$proxy_host$request_uri : http协议 + 主机名 + uri 把这三个作为一个单独的key来缓存。

如何还需要缓存别的,就按照这种格式来设置。

示例:

a、负载均衡缓存服务配置(/etc/nginx/conf.d/cache_test.conf)如下:

upstream chrdai {
    server 192.168.0.133:8001;
    server 192.168.0.133:8002;
    server 192.168.0.133:8003;
}

proxy_cache_path /opt/app/cache levels=1:2 keys_zone=chrdai_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        proxy_cache chrdai_cache;
        proxy_pass http://chrdai;
        proxy_cache_valid 200 304 12h;
        proxy_cache_valid any 10m;
        proxy_cache_key $host$uri$is_args$args;
        add_header Nginx-Cache "$upstream_cache_status";

        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        include conf.d/proxy_params; //proxy_params请参考我上一章的内容
    }
}

配置说明:

proxy_cache_path /opt/app/cache

存放缓存文件的目录

levels=1:2

目录分级,按照两层目录的方式来进行分级。

keys_zone=chrdai_cache:10m

zone空间的名字,后面配置 proxy_cache 后面配的就是这个名字。10m表示开辟key空间的大小,一般1m大概能存放8000个key。

max_size=10g

表示缓存目录最大是多大,不能让缓存无限增长占满整个磁盘。当缓存空间满了后,Nginx就会触发淘汰规则,把不常访问的就会淘汰掉。

inactive=60m

这个60m是时间单位,表示60分钟,表示如果在60分钟内如果某个缓存没有被访问过,就会把它清理掉。

use_temp_path=off

这个是用来存放临时文件的,建议关闭,如果打开的话,Nginx会另外建立一个目录和cache目录两个目录在更新缓存时容易出现一些性能方面的损耗。

proxy_cache chrdai_cache

表示我们已经开启了代理缓存,该值是proxy_cache_path中的 keys_zone 的值,如果不想使用代理缓存,将该值配置成 off。

proxy_pass http://chrdai

代理的地址

proxy_cache_valid 200 304 12h;

状态码为200,304的响应过期时间为 12h。

proxy_cache_valid any 10m;

除了200和304状态码的其它状态码的缓存时间为10分钟。

proxy_cache_key $host$uri$is_args$args;

设置默认缓存的key。

$is_args表示请求中的URL是否带参数,如果带参数,$is_args值为”?”。如果不带参数,则是空字符串。

$args表示HTTP请求中的参数。

add_header Nginx-Cache “$upstream_cache_status”;

增加一个http响应头信息,Nginx-Cache,告诉客户端是否已经命中代理缓存。

proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

当我们的后端其中一台服务器出现错误,超时,或者500,502,503,504等不正常的头返回时,就跳过这一台,去访问下一台。避免因为单台服务器的异常对前端产生影响。

b、 另外三台真实服务器的配置如下:

第一台(/etc/nginx/conf.d/realserver1.conf):

Nginx作为缓存服务

第二台(/etc/nginx/conf.d/realserver2.conf):

Nginx作为缓存服务

第三台(/etc/nginx/conf.d/realserver3.conf):

Nginx作为缓存服务

c、分别在三台真实服务器(当然我这里是在一台服务器中用三个端口模拟的)的项目目录下建立index.html文件。

第一台(/opt/app/code1):

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>proxy_cache testtitle>
head>
<body>
    <p>Test proxy_cache1p>
body>
html>

第二台(/opt/app/code2):

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>proxy_cache testtitle>
head>
<body>
    <p>Test proxy_cache2p>
body>
html>

第三台(/opt/app/code3):

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>proxy_cache testtitle>
head>
<body>
    <p>Test proxy_cache3p>
body>
html>

c、先在代理服务器中将缓存关闭 (proxy_cache off),刷新页面,发现页面可以在三个站点间轮询显示。’

Nginx作为缓存服务

Nginx作为缓存服务

Nginx作为缓存服务

d、然后在把代理缓存打开,发现页面不在轮询了,请求头多了缓存头(这是头我们配置的)。

Nginx作为缓存服务

刷新第一遍的时候,请求头 Nginx-Cache : MISS

第二遍刷新的时候就命中了代理缓存。

Nginx作为缓存服务

同时也会在我们配置的缓存目录(/opt/app/cache)生成缓存目录

Nginx作为缓存服务

三、清理指定缓存

方法一

m -rf 缓存目录内容

这样会把所有的缓存都给清空掉。

方法二

第三方拓展模块ngx_cache_purge

四、如何让部分页面不缓存

配置语法

Syntax:proxy_no_cache string...;
Default:-;
Context:http,server,location;

配置示例:

upstream chrdai {
    server 192.168.0.133:8001;
    server 192.168.0.133:8002;
    server 192.168.0.133:8003;
}

proxy_cache_path /opt/app/cache levels=1:2 keys_zone=chrdai_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    if ($request_uri ~ ^/(index.html|login|register|password|\/reset)) {
        set $cookie_nocache 1;
    }

    location / {
        proxy_cache chrdai_cache;
        proxy_pass http://chrdai;
        proxy_cache_valid 200 304 12h;
        proxy_cache_valid any 10m;
        proxy_cache_key $host$uri$is_args$args;
        proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;
        proxy_no_cache $http_pragma $http_authorization;
        add_header Nginx-Cache "$upstream_cache_status";

        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        include conf.d/proxy_params;
    }
}

这里配置的意思就是当url中匹配到了 index.html , login, register, password 和 reset 时,不缓存该url所对应的页面。

五、缓存命中分析

方式一

通过设置 response 的头信息 Nginx-Cache

add_header Nginx-Cache "$upstream_cache_status";

方式二

通过设置 log_format,打印日志进行分析。(打印 $upstream_cache_status这个Nginx默认的变量)

$upstream_cache_status 这个变量有以下几种值:

状态 含义 MISS 未命中,请求被传送到后台处理
HIT 缓存命中

EXPIRED 缓存已经过期,请求被传送到后台处理 UPDATING 正在更新缓存,将使用旧的应答 STALE 后端得到过期的应答

缓存命中率 = HIT次数 / 总请求次数。

示例:

首先在 /etc/nginx/nginx.conf 中的 logformat 中加入$upstream_cache_status 这个变量。

Nginx作为缓存服务

然后配置缓存代理的 access_log 的路径

Nginx作为缓存服务

然后使用linux 的 awk 命分析日志 。

awk '{if($NF=="\"HIT\""){hit++}}END{printf "%.2f", hit/NR}' /var/log/nginx/proxy_cache_access.log

命令解释:

$NF : 日志每行的最后一个参数。

hit我们自定义的一个变量,用来记录被命中的次数。

NR:AWK的内置变量,表示本次分析所扫描日志的总行数。

命令执行结果:

Nginx作为缓存服务

说明我们的缓存命中率为 58%。

六、大文件的分片请求

http_slice_module

配置语法

Syntax:slice size;
Default:slice 0;
Context:http,server,location;

size 是一个大小,表示是大文件被分割后,小文件的大小。

实现原理

Nginx作为缓存服务

会根据 Range 的值分割成小的请求去请求后端,返回回来的就是一个一个小的缓存文件,

优势:

每个子请求收到的数据都会形成一个独立文件,一个请求断了,其它请求不受影响。

缺点:

当文件很大或者 slice 很小的时候,可能会导致文件描述符耗尽等情况。

本文为袋鼠学习中的总结,如有转载请注明出处:https://www.cnblogs.com/chrdai/protected/p/11355423.html

Original: https://www.cnblogs.com/chrdai/p/11355423.html
Author: Chrdai
Title: Nginx作为缓存服务

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/543831/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • [nginx] nginx源码分析–内存管理

    nginx的内存,都是内存池管理,创建一个内存池就malloc一块内存出来. 两个重要的地方会新建内存池, 一个新连接建立的时候, 一个是request创建的时候. 在内存池里申请…

    Java 2023年5月30日
    066
  • 中国DevOps平台市场,华为云再次位居领导者位置

    摘要:华为云软件开发生产线DevCloud在市场份额和发展战略两大维度均排名第一,再次位居领导者位置。 9月21日 ,国际权威分析师机构IDC发布《IDC MarketScape:…

    Java 2023年6月15日
    067
  • Mac下多版本JDK安装

    1.下载 &#x94FE;&#x63A5;: <span class="hljs-symbol">http:/<span cl…

    Java 2023年5月30日
    070
  • 图解定时任务线程池

    线程池概念 我们上篇文章分析了ThreadPoolExecutor,如果要用一句话说明它的主要优势,就是线程置换。还有Executors工具类,极大的简化了研发人员工作。 我用一个…

    Java 2023年6月8日
    070
  • [免费的win7 娘]WES7SP1 测试心得

    简介:Windows Embedded Standard 7,就是微软官方出品的Win7的定制版,2进制代码和桌面版完全相同,因此功能也基本一样,主要区别在于,WES7可以精简(桌…

    Java 2023年5月29日
    073
  • springboot读取resources下文件方式

    之前使用读取resources下的json文件,后来发现不通用,在这里做一些记录。 打成jar包之后,没有办法读取里面的路径。使用流的方式进行 一:实践 1.说明 使用了org.s…

    Java 2023年5月30日
    060
  • Spring Boot入门系列(十七)整合Mybatis,创建自定义mapper 实现多表关联查询!

    之前讲了Springboot整合Mybatis,介绍了如何自动生成pojo实体类、mapper类和对应的mapper.xml 文件,并实现最基本的增删改查功能。mybatis 插件…

    Java 2023年5月30日
    085
  • 策略模式、策略模式与Spring的碰撞

    策略模式是GoF23种设计模式中比较简单的了,也是常用的设计模式之一,今天我们就来看看策略模式。 实际案例 我工作第三年的时候,重构旅游路线的机票查询模块,旅游路线分为四种情况: …

    Java 2023年6月5日
    078
  • volatile关键字理解

    volatile是一个轻量级的同步机制,相比传统的锁(如synchronized),在性能上面是有优势的,但是虚拟机对锁有过优化,所以很难确切的说volatile比synchron…

    Java 2023年6月5日
    082
  • 聊一聊Redis事务

    没错,Redis也有事务管理,但是功能很简单,在正式开发中也并不推荐使用。但是面试中有可能会问到,所以本文简单谈一谈Redis的事务。 通过这篇文章,你会了解 Redis为什么要提…

    Java 2023年6月7日
    077
  • 讲透JAVA Stream的collect用法与原理,远比你想象的更强大

    大家好,又见面了。 在我前面的文章《吃透JAVA的Stream流操作,多年实践总结》中呢,对Stream的整体情况进行了细致全面的讲解,也大概介绍了下结果收集器 Collector…

    Java 2023年6月7日
    071
  • 二叉树查找和删除指定结点

    二叉树查找指定的节点 前序查找的思路 1.先判断当前节点的no是否等于要查找的2.如果是相等,则返回当前节点3.如果不等,则判断当前节点的左子节点是否为空,如果不为空,则递归前序查…

    Java 2023年6月15日
    070
  • 面试必问之 CopyOnWriteArrayList,你了解多少?

    一、摘要 在介绍 CopyOnWriteArrayList 之前,我们一起先来看看如下方法执行结果,代码内容如下: public static void main(String[]…

    Java 2023年6月9日
    088
  • Java-IO中的节点流和处理流

    理解好Java-IO中的节点流和处理流是理解Java输入、输出的关键基础,因此,了解节点流和处理流相关的知识点尤为重要。 1.定义 (1)节点流:可以从或向一个特定的地方(节点)读…

    Java 2023年5月29日
    082
  • 【笔试】2、勾股数元祖或者素勾股数

    package y2020.interview.huawei.gougushu; import java.util.ArrayList; import java.util.List…

    Java 2023年6月5日
    0100
  • knn算法详解

    1.什么是knn算法 俗话说:物以类聚,人以群分。看一个人什么样,看他身边的朋友什么样就知道了(这里并没歧视谁,只是大概率是这样) 对于判断下图绿色的球是哪种数据类型的方法就是根据…

    Java 2023年6月13日
    0128
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球