• 关于Nginx mmap(MAP_ANON|MAP_SHARED, 314572800)报错


    mmap 报错解决

    今天修改了一下测试环境的Nginx的nginx.conf,然后做检测的时候报了一个错误

    /usr/local/bin/nginx -c /usr/local/etc/openresty/conf/nginx.conf -t
    
    nginx: [alert] mmap(MAP_ANON|MAP_SHARED, 314572800) failed (12: Cannot allocate memory)
    nginx: configuration file /usr/local/etc/openresty/conf/nginx.conf test failed
    

    报错提示很清楚,不能分配内存了。为什么不能分配内存了?基本上就是物理内存不够使用了,先查了下内存

    free -m
                  total        used        free      shared  buff/cache   available
    Mem:            990         568          75          54         347         224
    Swap:             0           0           0
    

    可以看到,真正可以被使用的内存大概就是224M。那就是Nginx此次检查的配置需要使用大于224M的内存。按理说,Nginx自身不需要多少内存。我们系统中大量使用openresty,首先怀疑可能openresty的某个引用申请内存过多了,然后查找了下配置,果然发现openresty的共享内存的使用。

    lua_shared_dict xxx 300m;
    lua_shared_dict yyy 100m;
    

    总共需要400M内存,这两个共享内存该小点应该就可以了。改为

    lua_shared_dict xxx 100m;
    lua_shared_dict yyy 30m;
    

    然后检查通过

    /usr/local/bin/nginx -c /usr/local/etc/openresty/conf/nginx.conf -t
    nginx: the configuration file /usr/local/etc/openresty/conf/nginx.conf syntax is ok
    nginx: configuration file /usr/local/etc/openresty/conf/nginx.conf test is successful
    

    检测是成功,reload Nginx成功生效。

    Nginx 申请内存的模块

    可能有的不一定是openresty共享内存的锅。Nginx配置需要配置内存的地方其实不多,一个个排查就可以做到。

    openresty lua_shared_dict

    lua_shared_dict 定义在http模块。
    声明共享内存区,共享内存区始终由当前Nginx服务器实例中的所有Nginx进程共享。
    参数接受大小单位,比如K 和M 等等。

    http {
         lua_shared_dict dogs 10m;
         ...
     }
    

    proxy_cache_path

    proxy_cache_path path [levels=levels] keys_zone=name:size
    path 设置缓存的路径
    levels 设置缓存文件的层级,当levels=1:2时,表示是两级目录,1和2表示用1位和2位16进制来命名目录名称。
    keys_zone 设置共享内存的名称和大小,keys_zone=one:10m,表示共享内存名称是one,大小是10M,这里设置内存过高,就会出现开头的报警,mmap(MAP_ANON|MAP_SHARED, 314572800)
    配置设置成这样
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;
    路径和层级就是下面的
    /data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
    

    limit_req_zone

    limit_req_zone key zone=name:size rate=rate
    设置共享内存的限流参数
    主要看下应用
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    

    使用客户端的IP作为限流的key,共享内存分配了10M,共享内存的名称是one,速度是每个客户端IP每秒1个请求,超过1个请求可能会延迟或者直接拒绝,要看limit_req的配置。
    $binary_remote_addr变量的大小为4个字节。在64位平台上始终占据128字节。 一个1M的区域可以保留约约8000个客户端IP。所以10M大概可以准确存储8万个客户端IP。如果限流的客户端IP超过了8万个,就应该扩大共享内存。

    limit_conn_zone

    limit_conn_zone key zone=name:size;
    设置连接数限流的参数
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    

    连接数限流的参数跟请求数参数类似。
    使用客户端的IP作为限流的key,共享内存分配了10M,共享内存的名称是addr。10M可以存储8万个客户端IP。限流的具体数量限制是由limit_conn配置
    比如

    limit_conn addr 1;
    

    就表示每个客户端IP同时只能有一个连接存在。

    总结Nginx mmap

    所以,如果以后遇到关于Nginx mmap(MAP_ANON|MAP_SHARED, 314572800)报错,首先应该检查可能分配大内存的配置,首要检查的就是这两个
    lua_shared_dict
    proxy_cache_path
    修改这两个参数就可以解决问题。

    一般
    limit_req_zone
    limit_conn_zone
    分配的内存很小,至多几十M,不会直接导致系统没有内存可分配。

  • 相关阅读:
    文件夹隐藏加密
    hive日期函数
    MySql创建、查看、删除索引
    Vulnhub实战靶场:DC-3
    Vulnhub实战靶场:DC-2
    Vulnhub实战靶场:DC-1
    Vulnhub靶场练习:CHERRY: 1
    Vulnhub靶场练习:Chili:1
    Vulnhub靶场练习:Breach 3.0
    Vulnhub实战靶场练习:Breach 2.0
  • 原文地址:https://www.cnblogs.com/feixiangmanon/p/13655721.html
Copyright © 2020-2023  润新知