nginx共享内存机制详解

  

nginx共享内存机制详解

什么是共享内存

共享内存在不同进程间共享数据的时候非常有用。在一个进程共享它的内存数据给另一个进程时,共享内存是最快的方式。共享内存可以让多个进程同时访问同一块内存区域,因此,可以避免不必要的进程间的通信,从而提高效率。

nginx的共享内存

nginx使用共享内存作为进程间通信机制,其中包括两种共享内存:共享内存区域和共享内存字典。

共享内存区域:nginx的共享内存区域是由一系列的共享内存块组成的,每个块都被分配一个唯一的名称。每个进程都可以通过这个名称来访问到共享内存区域的特定块。共享内存块的大小是固定不变的,一旦分配,大小就不能更改。共享内存区域通常用于存储只读数据,如nginx配置信息或共享缓存。

共享内存字典:即NGX_SHM_DICT。nginx共享内存字典是一个支持key-value存储的结构。这个字典可以由任何一个worker进程写入,其他进程都可以读取其中的值。可以在nginx.conf的http块中配置共享内存字典的大小和名称。共享内存字典通常用于存储只读、不变的数据,如SSL证书信息。

示例1:nginx使用共享内存缓存

在nginx中,使用共享内存来做缓存非常方便和高效。使用ngx_shared_memory结构体来描述共享内存区域。每个ngx_shared_memory结构体里面有一个名字、大小和数据指针。下面的示例是定义一个共享内存区域,并将一个值存储到共享内存中:

http {
    ... ...
    # 定义共享内存区域
    # zone名称为my_cache, 大小为10m(注意:大小必须在worker进程初始化时分配好,不能改变)
    # 共享内存里可以选一块区域用来存储缓存内容
    # keys_zone=zone name:size,shared memory size
    # 用于锁定请求时的一些公共变量,二级缓存,即先读取本地cache,如果没有则再读取共享内存cache
    # zone my_cache
    # 用$my_cache作为共享内存区域的别名
    # keys_zone=cache_zone:10m inactive=60s
    # $shared_zone使用了前面定义的my_cache区域
    map $request_uri $shared_zone {
        default ""; # Use default value if the request URI does not match any of the following patterns
        ~^/(example1|example2)/cache/(.*)$ "my_cache $2"; # Cache example1.com/cache/{url} and example2.com/cache/{url} hits in the "my_cache" shared memory zone.
    }
    # 以下为location设置项
    location / {
        # 我们使用一个变量名$cache_key来构建cache key。
        set $cache_key $shared_zone:$request_uri;
        #使用缓存
        proxy_cache_bypass  $http_pragma;
        proxy_cache_revalidate on;
        add_header Cache-Control public, max-age=60;
        #使用共享的缓存
        proxy_cache_shm_zone $shared_zone;
        #cache 内置对象
        proxy_cache cache_zone;
        proxy_cache_key "$scheme$request_method$host$request_uri";
        # 缓存配置
        proxy_cache_valid  60m;
        proxy_cache_bypass $http_cache_control;
        proxy_cache_bypass $http_pragma;
        proxy_cache_bypass $http_authorization;
    }
}

示例2:nginx创建共享内存字典

快速创建共享内存字典需要使用ngx_shm_zone_t结构体。这个结构体可以描述共享内存的名称、共享内存大小和一些回调函数。

http {
    ... ...
    # 定义共享内存字典zone名称为my_dict
    # zone名称为my_dict, 大小为10m
    # 定义了一个处理"init my_dict $binary_remote_addr"在每个worker进程开始之前调用的回调函数。
    # ngx_http_map_module 指令,将$binary_remote_addr 置为1,用于存储client ip
    # map指令,使用共享内存字典"$my_dict",并存储客户端IP地址
    map $binary_remote_addr $my_dict {
        init my_dict 10m;
        # 共享内存字典使用ngx_http_variable_value结构体表示
        # set语句的结果只改变这个值在本地的值,而不会将值写入共享内存字典中
        # $binary_remote_addr存储着客户端IP地址,且在启动时会初始化到10.0.5.1
        # 每次客户IP变化都会初始化到最新IP
        set $value "10.0.5.1";
        # 可以使用DictSet去设置字典中的值,而不会修改本地的变量
        # DictSet的第一个参数是需要将值存储的共享内存字典,第二个参数是key,第三个参数是value
        DictSet $my_dict $binary_remote_addr "$value";
        # 返回共享内存字典中的值
        DictGet $my_dict $binary_remote_addr;
    }
    # location配置
    location /test {
        return 200 $my_dict;
    }
}

以上是nginx共享内存机制的详细攻略,包含了nginx共享内存的概念和两个示例,其中示例1讲解了利用共享内存实现缓存,示例2讲解了如何创建共享内存字典。通过对这些内容的了解,可以更好地掌握nginx的高效内存使用技巧。

相关文章