一、內核參數調優
默認的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攻擊,不用過分依靠這個限制甚至認為的減小這個值,更多的情況是增加這個值
二、一鍵安裝Nginx
#! /bin/bashversion=1.15.4#判斷函數是否執行成功
function show_result(){if [ "$1" -eq 0 ]thenecho -e "\e[32m$2 is Success . [ OK ] \e[0m"elseecho -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 ];thenecho -e "\e[31mUser and Group exist! \e[0m"elsegroupadd -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.gzshow_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 ];thenecho -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 fishow_result $? "${item}"
}#軟連接建立
function nginx_softlink(){local item="Nginx Softlink"test -d /etc/nginx/ || ln -s /usr/local/nginx/conf/ /etc/nginxtest -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.servicesystemctl 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>&1arch_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.confadd_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.confadd_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.confadd_config_tofile "kernel.msgmax = 65536" /etc/sysctl.conf#修改最大內存共享段大小bytesadd_config_tofile "kernel.shmmax = 68719476736" /etc/sysctl.confadd_config_tofile "kernel.shmall = 4294967296" /etc/sysctl.conf#timewait數量默認18000add_config_tofile "net.ipv4.tcp_max_tw_buckets = 600" /etc/sysctl.confadd_config_tofile "net.ipv4.tcp_sack = 1" /etc/sysctl.confadd_config_tofile "net.ipv4.tcp_window_scaling = 1" /etc/sysctl.confadd_config_tofile "net.ipv4.tcp_rmem = 4096 87380 16777216" /etc/sysctl.confadd_config_tofile "net.ipv4.tcp_wmem = 4096 65536 16777216" /etc/sysctl.confadd_config_tofile "net.core.rmem_default = 8388608" /etc/sysctl.confadd_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.confadd_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消息的頻度,默認2hadd_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 #修改防火墻連接跟蹤表大小,默認65535add_config_tofile "net.netfilter.nf_conntrack_max = ${nf_conntrack_size}" /etc/sysctl.confadd_config_tofile "net.nf_conntrack_max = ${nf_conntrack_size}" /etc/sysctl.conf#解禁pingadd_config_tofile "net.ipv4.icmp_echo_ignore_all = 0" /etc/sysctl.confmodprobe bridgesysctl -p > /dev/null 2>&1show_result $? "${item}"
}#啟動 nginx
function nginx_start(){local item="Nginx start"systemctl enable nginx --now > /dev/null 2>&1show_result $? "${item}"
}#負責寫入配置的函數
function add_config_tofile(){local keywords=`echo $1| awk -F "[= ]+" '{print $1}'`local SearchResult=`grep "^${keywords}" "$2"`if [ -z "${SearchResult}" ]thenecho $1 >> $2elsesed -i "s/^${keywords}.*/$1/" $2fi
}
#主函數
function main(){user_createnginx_pkgnginx_downloadnginx_compilenginx_softlinknginx_servicenginx_kernelnginx_start
}main
三、Tomcat應用程序調優
關于 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"/>