1. 使用示例
    nginx声明共享内存的指令为:

proxy_cache_path /Users/Mike/nginx-cache levels=1:2 keys_zone=one:10m max_size=10g inactive=60m use_temp_path=off;
这里只是声明的一个名称为one,最大可用内存为10g的共享内存。这里面各个参数的含义如下:

/Users/Mike/nginx-cache:这是一个路径参数,指定了将共享内存所缓存的文件的存储位置。这里为什么会生成文件的原因在于,对于上游服务发出的响应,是可以将其生成一个文件存储在nginx上的,后续如果有同样的请求,就可以直接读取该文件或者读取共享内存中的缓存以响应客户端;
levels:在linux操作系统中,如果所有文件都放在一个文件夹中,那么当文件数量非常多的时候,可能一个磁盘驱动就无法读取这么多文件了,如果放置在多个文件夹中,那么就能够利用多个驱动并且读取的优点。这里的levels参数指定的就是如何生成文件夹。假设nginx为上游服务的某个响应数据生成的文件名为e0bd86606797639426a92306b1b98ad9,那么对于上面的levels=1:2,其就会从文件名的最后开始取值,先取1位(也即9)作为一级子目录名,然后取2位(也即ad)作为二级子目录名;
keys_zone:该参数指定了当前共享内存的名称,这里为one,后面的10m表示当前共享内存用于存储key的内存大小为10m;
max_size:该参数指定了当前共享内存可用的最大内存;
inactive:该参数指定了当前共享内存的最长存活时间,如果在这段时间内都没有任何请求访问该内存数据,那么其就会被LRU算法淘汰掉;
use_temp_path:该参数指定了是否先将生成的文件放入临时文件夹,后续再移动到指定文件夹下;
2. 工作原理
共享内存的管理工作主要分为如下图所示的几个部分:

nginx使用oss中存储 nginx 内存_共享内存

可以看到,其主要分为初始化、共享内存的管理、共享内存的加载和共享内存的使用等几个方面。在初始化的过程中,首先会解析proxy_cache_path指令,然后分别启动cache manager和cache loader进程;这里cache manager进程主要是进行共享内存的管理的,其主要是通过LRU算法清除过期数据,或者当资源紧张时强制删除部分未被引用的内存数据;而cache loader进程的主要工作是在nginx启动之后,读取文件存储目录中已有的文件,将其加载到共享内存中;而共享内存的使用主要是在处理请求完成之后对响应数据的缓存,这一部分的内容将在后面的文章中进行讲解,本文主要讲解前面三部分的工作原理。

    按照上面的划分,共享内存的管理主要可以分为三个部分(共享内存的使用将在后面进行讲解)。如下是这三个部分的处理流程的示意图:

nginx使用oss中存储 nginx 内存_nginx_02


从上面的流程图中可以看出,在主流程中,主要进行了解析proxy_cache_path指令、启动cache manager进程和启动cache loader进程的工作。而在cache manager进程中,主要工作则分为两部分:1. 检查队列尾部元素是否过期,如果过期并且引用数为0,则删除该元素和该元素对应的文件;2. 检查当前共享内存是否资源紧张,如果资源紧张,则删除所有引用数为0的元素及其文件,无论其是否过期。在cache loader进程的处理流程中,主要是通过递归的方式遍历存储文件的目录及其子目录中的文件,然后将这些文件加载到共享内存中。需要注意的是,cache manager进程在每次遍历完所有的共享内存块之后会进入下一次循环,而cache loader进程在nginx启动之后60s的时刻执行一次,然后就会退出该进程。