默认的Linux内核参数考虑的是最通用场景,不符合用于支持高并发访问的Web服务器的定义,根据业务特点来进行调整,当Nginx作为静态web内容服务器、反向代理或者提供压缩服务器的服务器时,内核参数的调整都是不同的,此处针对最通用的、使Nginx支持更多并发请求的TCP网络参数做简单的配置
修改配置文件/etc/sysctl.conf
- fs.file-max = 1000000
- #表示单个进程较大可以打开的句柄数
-
- net.ipv4.tcp_tw_reuse = 1
- #参数设置为 1 ,表示允许将TIME_WAIT状态的socket重新用于新的TCP链接,这对于服务器来说意义重大,因为总有大量TIME_WAIT状态的链接存在
-
- net.ipv4.tcp_keepalive_time = 600
- #当keepalive启动时,TCP发送keepalive消息的频度;默认是2小时,将其设置为10分钟,可更快的清理无效链接
-
- net.ipv4.tcp_fin_timeout = 30
- #当服务器主动关闭链接时,socket保持在FIN_WAIT_2状态的较大时间
-
-
- net.ipv4.tcp_max_tw_buckets = 5000
- #表示操作系统允许TIME_WAIT套接字数量的较大值,如超过此值,TIME_WAIT套接字将立刻被清除并打印警告信息,默认为8000,过多的TIME_WAIT套接字会使Web服务器变慢
-
- net.ipv4.ip_local_port_range = 1024 65000
- #定义UDP和TCP链接的本地端口的取值范围
-
- net.ipv4.tcp_rmem = 10240 87380 12582912
- #定义了TCP接受缓存的最小值、默认值、较大值
-
- net.ipv4.tcp_wmem = 10240 87380 12582912
- #定义TCP发送缓存的最小值、默认值、较大值
-
- net.core.netdev_max_backlog = 8096
- #当网卡接收数据包的速度大于内核处理速度时,会有一个列队保存这些数据包。这个参数表示该列队的较大值
-
- net.core.rmem_default = 6291456
- #表示内核套接字接受缓存区默认大小
-
- net.core.wmem_default = 6291456
- #表示内核套接字发送缓存区默认大小
-
- net.core.rmem_max = 12582912
- #表示内核套接字接受缓存区较大大小
-
- net.core.wmem_max = 12582912
- #表示内核套接字发送缓存区较大大小
- 注意:以上的四个参数,需要根据业务逻辑和实际的硬件成本来综合考虑
-
- net.ipv4.tcp_syncookies = 1
- #与性能无关。用于解决TCP的SYN攻击
-
- net.ipv4.tcp_max_syn_backlog = 8192
- #这个参数表示TCP三次握手建立阶段接受SYN请求列队的较大长度,默认1024,将其设置的大一些可使出现Nginx繁忙来不及accept新连接时,Linux不至于丢失客户端发起的链接请求
-
- net.ipv4.tcp_tw_recycle = 1
- #这个参数用于设置启用timewait快速回收
-
- net.core.somaxconn=262114
- #选项默认值是128,这个参数用于调节系统同时发起的TCP连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此需要结合高并发请求数来调节此值。
-
- net.ipv4.tcp_max_orphans=262114
- #选项用于设定系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤立链接将立即被复位并输出警告信息。这个限制指示为了防止简单的DOS攻击,不用过分依靠这个限制甚至认为的减小这个值,更多的情况是增加这个值
- #! /bin/bash
-
- version=1.15.4
-
- #判断函数是否执行成功
- function show_result(){
- if [ "$1" -eq 0 ]
- then
- echo -e "\e[32m$2 is Success . [ OK ] \e[0m"
- else
- echo -e "\e[31m$2 is Fail . [ FAIL ] \e[0m"
- fi
- }
-
- #创建 nginx 用户和用户组
- function user_create(){
- local item="Create User and Group"
- if [ `cat /etc/{passwd,group} | grep nginx | wc -l ` -ge 2 ];
- then
- echo -e "\e[31mUser and Group exist! \e[0m"
- else
- groupadd -g 1004 nginx && \
- useradd -u 1004 -g 1004 -M -s /sbin/nologin nginx
- show_result $? "${item}"
- fi
- }
-
- #下载一些拓展包
- function nginx_pkg(){
- local item="Packages Install"
- yum -y install gcc openssl-devel pcre-devel zlib-devel > /dev/null 2>&1
- show_result $? "${item}"
- }
-
-
- #下载nginx
- function nginx_download(){
- local item="Nginx Download"
- cd /usr/local/src && \
- wget http://nginx.org/download/nginx-${version}.tar.gz > /dev/null 2>&1
- test -e /usr/local/src/nginx-${version} || tar zxf nginx-${version}.tar.gz
- rm -rf /usr/local/src/nginx-${version}.tar.gz
- show_result $? "${item}"
- }
-
-
- #编译安装
- function nginx_compile(){
- local item="Nginx Compile"
- cd /usr/local/src/nginx-${version}
- if [ `ls -l /usr/local/ | grep 'nginx' | wc -l` -ge 1 ];
- then
- echo -e "\e[31mNginx exist! \e[0m"
- else
- ./configure --prefix=/usr/local/nginx > /dev/null 2>&1 && make > /dev/null 2>&1 && make install > /dev/null 2>&1
- fi
- show_result $? "${item}"
- }
-
- #软连接建立
- function nginx_softlink(){
- local item="Nginx Softlink"
- test -d /etc/nginx/ || ln -s /usr/local/nginx/conf/ /etc/nginx
- test -e /usr/sbin/nginx || ln -s /usr/local/nginx/sbin/nginx /usr/sbin/
- show_result $? "${item}"
- }
-
-
- #注册服务
- function nginx_service(){
- local item="Nginx Service"
- test -e /usr/lib/systemd/system/nginx.service || \
- echo '
- [Unit]
- Description=The nginx HTTP and reverse proxy server
- After=network-online.target remote-fs.target nss-lookup.target
- Wants=network-online.target
- [Service]
- Type=forking
- PIDFile=/usr/local/nginx/logs/nginx.pid
- # Nginx will fail to start if /run/nginx.pid already exists but has the wrong
- # SELinux context. This might happen when running `nginx -t` from the cmdline.
- # https://bugzilla.redhat.com/show_bug.cgi?id=1268621ExecStartPre=/usr/bin/rm-f /usr/local/nginx/logs/nginx.pid
- ExecStartPre=/usr/local/nginx/sbin/nginx -t
- ExecStart=/usr/local/nginx/sbin/nginx
- ExecReload=/usr/local/nginx/sbin/nginx -s reload
- KillSignal=SIGQUIT
- TimeoutStopSec=5
- KillMode=process
- PrivateTmp=true
- ' > /usr/lib/systemd/system/nginx.service
- systemctl daemon-reload
- show_result $? "${item}"
- }
-
-
- #内核优化
- function nginx_kernel(){
- local item="Optimize Kernel Arguments"
- cp /etc/sysctl.conf /etc/sysctl.conf.${current_time} > /dev/null 2>&1
- arch_ratio=$([[ ! -z $(uname -a | grep x86_64) ]] && expr 64 / 32 || expr 32 / 32)
- memory_size=$(free -b| awk 'NR==2{print $2}')
- nf_conntrack_size=$(expr ${memory_size} / 16384 / ${arch_ratio})
- #开启反向路径过滤
- add_config_tofile "net.ipv4.conf.default.rp_filter = 1" /etc/sysctl.conf
- add_config_tofile "net.ipv4.conf.all.rp_filter = 1" /etc/sysctl.conf
- #处理无源路由包
- add_config_tofile "net.ipv4.conf.all.accept_source_route = 0" /etc/sysctl.conf
- add_config_tofile "net.ipv4.conf.default.accept_source_route = 0" /etc/sysctl.conf
- #core文件名中添加pid作为扩展名
- add_config_tofile "kernel.core_uses_pid = 1" /etc/sysctl.conf
- #开启syn洪水攻击保护
- add_config_tofile "net.ipv4.tcp_syncookies = 1" /etc/sysctl.conf
- #修改消息队列长度
- add_config_tofile "kernel.msgmnb = 65536" /etc/sysctl.conf
- add_config_tofile "kernel.msgmax = 65536" /etc/sysctl.conf
- #修改最大内存共享段大小bytes
- add_config_tofile "kernel.shmmax = 68719476736" /etc/sysctl.conf
- add_config_tofile "kernel.shmall = 4294967296" /etc/sysctl.conf
- #timewait数量默认18000
- add_config_tofile "net.ipv4.tcp_max_tw_buckets = 600" /etc/sysctl.conf
- add_config_tofile "net.ipv4.tcp_sack = 1" /etc/sysctl.conf
- add_config_tofile "net.ipv4.tcp_window_scaling = 1" /etc/sysctl.conf
- add_config_tofile "net.ipv4.tcp_rmem = 4096 87380 16777216" /etc/sysctl.conf
- add_config_tofile "net.ipv4.tcp_wmem = 4096 65536 16777216" /etc/sysctl.conf
- add_config_tofile "net.core.rmem_default = 8388608" /etc/sysctl.conf
- add_config_tofile "net.core.wmem_max = 16777216" /etc/sysctl.conf
- #未收到客户端确认信息连接请求的最大值
- add_config_tofile "net.ipv4.tcp_max_syn_backlog = 262144" /etc/sysctl.conf
- #放弃建立连接之前发送的synack包
- add_config_tofile "net.ipv4.tcp_syn_retries = 2" /etc/sysctl.conf
- #开启重用,允许time—wait socket 重新用语新的tcp连接
- add_config_tofile "net.ipv4.tcp_tw_reuse = 1" /etc/sysctl.conf
- add_config_tofile "net.ipv4.tcp_fin_timeout = 1" /etc/sysctl.conf
- #防止简单的ddos攻击
- add_config_tofile "net.ipv4.tcp_max_orphans = 3276800" /etc/sysctl.conf
- #启用timewait快速收回
- add_config_tofile "net.ipv4.tcp_tw_recycle = 0" /etc/sysctl.conf
- #keeptime启用时tcp发送keepalive消息的频度,默认2h
- add_config_tofile "net.ipv4.tcp_keepalive_time = 600" /etc/sysctl.conf
- #允许系统打开的端口范围
- add_config_tofile "net.ipv4.ip_local_port_range = 1024 65535" /etc/sysctl.conf
- #资源回收
- add_config_tofile "net.ipv4.tcp_tw_recycle = 0" /etc/sysctl.conf
- #路由转发
- add_config_tofile "net.ipv4.ip_forward = 1" /etc/sysctl.conf
- #修改防火墙连接跟踪表大小,默认65535
- add_config_tofile "net.netfilter.nf_conntrack_max = ${nf_conntrack_size}" /etc/sysctl.conf
- add_config_tofile "net.nf_conntrack_max = ${nf_conntrack_size}" /etc/sysctl.conf
- #解禁ping
- add_config_tofile "net.ipv4.icmp_echo_ignore_all = 0" /etc/sysctl.conf
- modprobe bridge
- sysctl -p > /dev/null 2>&1
- show_result $? "${item}"
- }
-
-
-
- #启动 nginx
- function nginx_start(){
- local item="Nginx start"
- systemctl enable nginx --now > /dev/null 2>&1
- show_result $? "${item}"
- }
-
-
- #负责写入配置的函数
- function add_config_tofile(){
- local keywords=`echo $1| awk -F "[= ]+" '{print $1}'`
- local SearchResult=`grep "^${keywords}" "$2"`
- if [ -z "${SearchResult}" ]
- then
- echo $1 >> $2
- else
- sed -i "s/^${keywords}.*/$1/" $2
- fi
- }
- #主函数
- function main(){
- user_create
- nginx_pkg
- nginx_download
- nginx_compile
- nginx_softlink
- nginx_service
- nginx_kernel
- nginx_start
- }
-
- main
关于 Tomcat 主配置文件 server.xml 里面很多默认的配置项,但并不能满足业务需求, 常用的优化相关参数如下
- 【maxThreads】Tomcat 使用线程来处理接收的每个请求,这个值表示 Tomcat 可创建的最 大的线程数,默认值是 200。
- 【minSpareThreads】最小空闲线程数,Tomcat 启动时的初始化的线程数,表示即使没有 人使用也开这么多空线程等待,默认值是 10
- 【maxSpareThreads】最大备用线程数,一旦创建的线程超过这个值,Tomcat 就会关闭不 再需要的 socket 线程。默认值是-1(无限制)。一般不需要指定
- 【URIEncoding】指定 Tomcat 容器的 URL 编码格式,语言编码格式这块倒不如其它 Web 服务器软件配置方便,需要分别指定utf-8
- 【connnectionTimeout】网络连接超时,单位:毫秒,设置为 0 表示永不超时,这样设置 有隐患的。通常默认 20000 毫秒(20秒)就可以
- 【enableLookups】是否反查域名,以返回远程主机的主机名,取值为:true 或 false, 如果设置为 false,则直接返回 IP 地址,为了提高处理能力,应设置为 false。
- 【disableUploadTimeout】上传时是否使用超时机制。应设置为 true。
- 【connectionUploadTimeout】上传超时时间,毕竟文件上传可能需要消耗更多的时间, 这个根据你自己的业务需要自己调,以使 Servlet 有较长的时间来完成它的执行,需要 与上一个参数一起配合使用才会生效
- 【acceptCount】指定当所有可以使用的处理请求的线程数都被使用时,可传入连接请求 的最大队列长度,超过这个数的请求将不予处理,默认为 100 个。
- 【compression】是否对响应的数据进行 GZIP 压缩,off:表示禁止压缩;on:表示允许 压缩(文本将被压缩)、force:表示所有情况下都进行压缩,默认值为 off,压缩数据 后可以有效的减少页面的大小,一般可以减小 1/3 左右,节省带宽。
- 【compressionMinSize】表示压缩响应的最小值,只有当响应报文大小大于这个值的时候 才会对报文进行压缩,如果开启了压缩功能,默认值就是 2048
- 【compressableMimeType】压缩类型,指定对哪些类型的文件进行数据压缩。
- 【noCompressionUserAgents="gozilla, traviata"】对于以下的浏览器,不启用压缩
如果已经对代码进行了动静分离,静态页面和图片等数据就不需要 Tomcat 处理了,那 么也就不需要在 Tomcat 中配置压缩了。因为这里只有一台 Tomcat 服务器,而且压测的是 Tomcat 首页,会有图片和静态资源文件,所以这里启用压缩。
以上是一些常用的配置参数,还有好多其它的参数设置,还可以继续深入的优化
HTTP Connector 与 AJP Connector 的参数属性值,可以参考官方文档的详细说明进行学习。链 接 地 址 Apache Tomcat 9 Configuration Reference (9.0.86) - The HTTP Connector
下 面 开 始 对 Tomcat 配置文件优化进行前后的对比
- <Connector port="8080" protocol="HTTP/11.1"
- connectionTimeout="20000"
- redirectPort="8443"
- minSpareThreads="50"
- enableLookups="false"
- disableUploadTimeout="true"
- acceptCount="300"
- maxThreads="500"
- processorCache="500"
- URIEncoding="UTF-8"
- compression="on"
- compressionMinSize="2048"
- compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image /jpg,image/png"/>