linux配置文件的调优


一、limits.conf原理
 
工作原理
 
limits.conf文件实际是Linux PAM(插入式认证模块,Pluggable Authentication Modules)中 pam_limits.so 的配置文件,突破系统的默认限制,对系统访问资源有一定保护作用。 limits.conf 和sysctl.conf区别在于limits.conf是针对用户,而sysctl.conf是针对整个系统参数配置。
 
limits.conf是pam_limits.so的配置文件,然后/etc/pam.d/下的应用程序调用pam_***.so模块。譬如说,当用户访问服务器,服务程序将请求发送到PAM模块,PAM模块根据服务名称在/etc/pam.d目录下选择一个对应的服务文件,然后根据服务文件的内容选择具体的PAM模块进行处理。
 
文件格式
 
username|@groupname   type  resource  limit
1)username|@groupname
 
设置需要被限制的用户名,组名前面加@和用户名区别。也可用通配符*来做所有用户的限制
 
2)type
 
类型有soft,hard 和 -
 
soft 指的是当前系统生效的设置值
hard 表明系统中所能设定的最大值,soft 的限制不能比 hard 限制高
- 就表明同时设置了 soft 和 hard 的值
3)resource: 表示要限制的资源
 
core - 限制内核文件的大小
core file : 当一个程序崩溃时,在进程当前工作目录的core文件中复制了该进程的存储图像。core文件仅仅是一个内存映象(同时加上调试信息),主要是用来调试的。core文件是个二进制文件,需要用相应的工具来分析程序崩溃时的内存映像,系统默认core文件的大小为0,所以没有被创建。可以用ulimit命令查看和修改core文件的大小。 #ulimit -c 0 #ulimit -c 1000 #ulimit -c unlimited 注意:如果想让修改永久生效,则需要修改配置文件,如 .bash_profile、/etc/profile或/etc/security/limits.conf
date - 最大数据大小
fsize - 最大文件大小
memlock - 最大锁定内存地址空间
nofile - 打开文件的最大数目
对于需要做许多套接字连接并使它们处于打开状态的应用程序而言,最好通过使用ulimit -n,或者通过设置nofile参数,为用户把文件描述符的数量设置得比默认值高一些
rss - 最大持久设置大小
stack - 最大栈大小
cpu - 以分钟为单位的最多 CPU 时间
noproc - 进程的最大数目
as - 地址空间限制
maxlogins - 此用户允许登录的最大数目
 
示例
 
限制admin用户登录到sshd的服务不能超 过2个
 
echo session required pam_limits.so >> /etc/pam.d/sshd
echo admin - maxlogins 2 >> /etc/security/limits.conf
查看应用程序能否被PAM支持,用ldd
同理limits.conf要使用就必须保证/etc/pam.d/login 中有下面:session required pam_limits.so
 
设置
 
暂时生效,ulimit 命令
 
永久生效,通过将一个相应的 ulimit 语句添加到由登录 shell 读取的文件之一(例如 ~/.profile),即特定于 shell 的用户资源文件;或者通过编辑 /etc/security/limits.conf
二、ulimit
ulimit 用于限制 shell 启动进程所占用的资源,支持以下各种类型的限制:所创建的内核文件的大小、进程数据块的大小、Shell 进程创建文件的大小、内存锁住的大小、常驻内存集的大小、打开文件描述符的数量、分配堆栈的最大大小、CPU 时间、单个用户的最大线程数、Shell 进程所能使用的最大虚拟内存。同时,它支持硬资源和软资源的限制
 
作为临时限制,ulimit 可以作用于通过使用其命令登录的 shell 会话,在会话终止时便结束限制,并不影响于其他 shell 会话。而对于长期的固定限制,ulimit 命令语句又可以被添加到由登录 shell 读取的文件中,作用于特定的 shell 用户
 
只对当前tty(终端有效),若要每次都生效的话,可以把ulimit参数放到对应用户的.bash_profile里面
 
ulimit命令本身就有分软硬设置,加-H就是硬,加-S就是软
 
默认显示的是软限制,如果运行ulimit命令修改的时候没有加上的话,就是两个参数一起改变生效
 
ulimit命令用来限制系统用户对shell资源的访问,常用参数解释如下
 
ulimit(选项)
 
-a:显示目前资源限制的设定;
-c <core文件上限>:设定core文件的最大值,单位为区块;
-d <数据节区大小>:程序数据节区的最大值,单位为KB;
-f <文件大小>:shell所能建立的最大文件,单位为区块;
-H:设定资源的硬性限制,也就是管理员所设下的限制;
-m <内存大小>:指定可使用内存的上限,单位为KB;
-n <文件数目>:指定同一时间最多可开启的文件数;
-p <缓冲区大小>:指定管道缓冲区的大小,单位512字节;
-s <堆叠大小>:指定堆叠的上限,单位为KB;
-S:设定资源的弹性限制;
-t <CPU时间>:指定CPU使用时间的上限,单位为秒;
-u <程序数目>:用户最多可开启的程序数目;
-v <虚拟内存大小>:指定可使用的虚拟内存上限,单位为KB。
Linux是有文件句柄限制的,而且Linux默认不是很高,一般都是1024,生产服务器用其实很容易就达到这个数量
 
系统的限制文件在 /proc/sys/fs/file-max 、/proc/sys/fs/file-nr中
 
/proc/sys/fs/file-max
决定了当前内核可以打开的最大的文件句柄数
 
The value  in  file-max  denotes  the  maximum number of file handles that the Linux kernel will allocate. When you get a lot of error messages about running out of  file handles, you might want to raise this limit. The default value is 10% of  RAM in kilobytes.  To  change it, just  write the new number  into the file
 
意思是file-max一般为内存大小(KB)的10%来计算,如果使用shell,可以这样计算
 
grep -r MemTotal /proc/meminfo | awk '{printf("%d",$2/10)}'
/proc/sys/fs/file-nr
Historically, the three values in file-nr denoted the number of allocated file handles,  the number of  allocated but  unused file  handles, and  the maximum number of file handles. Linux 2.6 always  reports 0 as the number of free file handles -- this  is not an error,  it just means that the  number of allocated file handles exactly matches the number of used file handles.
 
查找文件句柄问题的时候,还有一个很实用的程序lsof.可以很方便看到某个进程开了那些句柄.也可以看到某个文件/目录被什么进程占用了.
 
lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more
 
修改完重新登录就可以见到,使用 ulimit -a 查看确认
 
设置
 
针对所有用户的设置,在/etc/security/limits.conf文件,其是可以对系统用户、组进行cpu、文件数等限制的,通过它可以针对某个用户或全部进行限制。但不能超越系统的限制;
 
(*表示所有用户、soft表示可以超出,但只是警告;hard表示绝对不能超出,unlimited用于表示不限制)如果想对所有用户设置,也可以放在/etc/profile文件里面,下面是该文件里面的默认参数:ulimit -S -c 0 > /dev/null 2>&1
修改ulimit最大限制
 
1)使用命令修改
 
查询当前终端的文件句柄数: ulimit -n 回车,一般的系统默认的1024.
 
修改文件句柄数为65535,ulimit -n 65535.此时系统的文件句柄数为65535.
 
2)将ulimit 值添加到/etc/profile文件中(适用于有root权限登录的系统)
 
为了每次系统重新启动时,都可以获取更大的ulimit值,将ulimit 加入到/etc/profile 文件底部
 
echo ulimit -n 65535 >>/etc/profile
source /etc/profile
ulimit -n
 
3)OK,好多朋友都以为大功告成了,可以突然发现自己再次登录进来的时候,ulimit的值还是1024,这是为什么呢?
 
关键的原因是你登录的用户是什么身份,是不是root用户,由于服务器的root用户权限很大,一般是不能用来登录的,都是通过自己本人的登录权限进行登录,并通过sudo方式切换到root用户下进行工作。 用户登录的时候执行sh脚本的顺序:
 
/etc/profile.d/file
/etc/profile
/etc/bashrc
/home/.admin/.bashrc
/home/.admin/.bash_profile
由于ulimit -n的脚本命令加载在第二部分,用户登录时由于权限原因在第二步还不能完成ulimit的修改,所以ulimit的值还是系统默认的1024
 
解决办法: 修改linux的软硬件限制文件
 
echo '
* soft nproc 11000
* hard nproc 11000
* soft nofile 655350
* hard nofile 655350' >> /etc/security/limits.conf
 
4)经过以上修改,在有些系统中,用一般用户再登陆,仍然没有修改过来,那么需要检查是否有如下文件,如果没有,则要添加如下内容:
 
echo session required /lib/security/pam_limits.so >> /etc/pam.d/sshd
service sshd reload
 
5)如果仍然不行,那么需要修改如下文件
 
echo UsePrivilegeSeparation no >>  /etc/ssh/sshd_config
ulimit -n and /proc/sys/fs/file-max 有什么区别
1、file-max  是内核级别的,所有的进程总和不能超过这个数
 
2、ulimit是进程级别的
 
me@superme:~$ ulimit -n
1024
me@superme:~$ lsof | grep me | wc -l
8145

#!/usr/bin/perl

$count = 0;
@filedescriptors;

while ($count <= 1024) {
    $FILE = ${count};
    open $FILE, ">", "/tmp/example$count" or die "\n\n FDs: $count $!";
    push(@filedescriptors, $FILE);
    $count ++;
}

//FDs: 1021 Too many open files at ./test.pl line 8.
//1021 because there were 3 open file descriptors before reaching the while loop (stdout, stdin and stderr)

 

三、关闭IPV6
 
目前为止我们还不需要IPv6,系统安装完之后是自带并且开启了的,需要我们关闭
 
1
ifconfig | grep inet6  || lsmod | grep ipv6
1、如果出现inet6 addr…的字样,说明就是安装了
 
2、显示内核加载的ipv6相关模块
 
通过以下命令禁用 
 
sed -i 's/^NETWORKING_IPV6=yes/NETWORKING_IPV6=no/' /etc/sysconfig/network
 
echo '
alias net-pf-10 off
alias ipv6 off ' >> /etc/modprobe.d/dist.conf
 
chkconfig ip6tables off
 
四、sysctl.conf工作原理
 
sysctl命令被用于在内核运行时动态地修改内核的运行参数,可用的内核参数在目录/proc/sys中。它包含一些TCP/IP堆栈和虚拟内存系统的高级选项, 这可以让有经验的管理员提高引人注目的系统性能。用sysctl可以读取设置超过五百个系统变量
 
sysctl.conf设置
 
这是一个在网络上流传依旧的sysctl.conf优化配置sysctl.conf设置
 
#禁用包过滤功能
net.ipv4.ip_forward = 0
#启用源路由核查功能
net.ipv4.conf.default.rp_filter = 1
#禁用所有IP源路由
net.ipv4.conf.default.accept_source_route = 0
#使用sysrq组合键是了解系统目前运行情况,为安全起见设为0关闭
kernel.sysrq = 0
#控制core文件的文件名是否添加pid作为扩展
kernel.core_uses_pid = 1
#开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理
net.ipv4.tcp_syncookies = 1
#每个消息队列的大小(单位:字节)限制
kernel.msgmnb = 65536
#整个系统最大消息队列数量限制
kernel.msgmax = 65536
#单个共享内存段的大小(单位:字节)限制,计算公式64G*1024*1024*1024(字节)
kernel.shmmax = 68719476736
#所有内存大小(单位:页,1页 = 4Kb),计算公式16G*1024*1024*1024/4KB(页)
kernel.shmall = 4294967296
#timewait的数量,默认是180000
net.ipv4.tcp_max_tw_buckets = 6000
#开启有选择的应答
net.ipv4.tcp_sack = 1
#支持更大的TCP窗口. 如果TCP窗口最大超过65535(64K), 必须设置该数值为1
net.ipv4.tcp_window_scaling = 1
#TCP读buffer
net.ipv4.tcp_rmem = 4096 131072 1048576
#TCP写buffer
net.ipv4.tcp_wmem = 4096 131072 1048576
#为TCP socket预留用于发送缓冲的内存默认值(单位:字节)
net.core.wmem_default = 8388608
#为TCP socket预留用于发送缓冲的内存最大值(单位:字节)
net.core.wmem_max = 16777216
#为TCP socket预留用于接收缓冲的内存默认值(单位:字节)
net.core.rmem_default = 8388608
#为TCP socket预留用于接收缓冲的内存最大值(单位:字节)
net.core.rmem_max = 16777216
#每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目
net.core.netdev_max_backlog = 262144
#web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值
net.core.somaxconn = 262144
#系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)
net.ipv4.tcp_max_orphans = 3276800
#记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128
net.ipv4.tcp_max_syn_backlog = 262144
#时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉
net.ipv4.tcp_timestamps = 0
#为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量
net.ipv4.tcp_synack_retries = 1
#在内核放弃建立连接之前发送SYN包的数量
net.ipv4.tcp_syn_retries = 1
#开启TCP连接中time_wait sockets的快速回收
net.ipv4.tcp_tw_recycle = 1
#开启TCP连接复用功能,允许将time_wait sockets重新用于新的TCP连接(主要针对time_wait连接)
net.ipv4.tcp_tw_reuse = 1
#1st低于此值,TCP没有内存压力,2nd进入内存压力阶段,3rdTCP拒绝分配socket(单位:内存页)
net.ipv4.tcp_mem = 94500000 915000000 927000000
#如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60 秒。2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。
net.ipv4.tcp_fin_timeout = 15
#表示当keepalive起用的时候,TCP发送keepalive消息的频度(单位:秒)
net.ipv4.tcp_keepalive_time = 30
#对外连接端口范围
net.ipv4.ip_local_port_range = 2048 65000
#表示文件句柄的最大数量
fs.file-max = 102400
 
这是我在实际生产系统自动化部署中用的配置
 
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_wmem = 8192 4336600 873200
net.ipv4.tcp_rmem = 32768 4336600 873200
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 786432 1048576 1572864
net.ipv4.tcp_fin_timeout = 30
#net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.ip_local_port_range = 1024 65000
/sbin/sysctl -p最后记得刷新立即生效

 


相关内容