1. 优化内核参数

cat /etc/sysctl.conf
net.ipv4.ip_forward = 0
表示开启路由功能,0是关闭,1是开启

net.ipv4.conf.default.rp_filter = 1
开启反向路径过滤

net.ipv4.conf.default.accept_source_route = 0
处理无源路由的包

net.ipv4.tcp_max_tw_buckets = 6000
表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改为 5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量。此项参数可以控制TIME_WAIT套接字的最大数量.

net.ipv4.ip_local_port_range = 1024 65000
表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。

net.ipv4.tcp_tw_recycle = 1
启用timewait 快速回收。

net.ipv4.tcp_tw_reuse = 1
开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接。

net.ipv4.tcp_syncookies = 1
开启SYN Cookies,当出现SYN 等待队列溢出时,启用cookies 来处理。

net.ipv4.tcp_max_orphans = 262144
系统中最多有多少个TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS ***,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。

net.ipv4.tcp_keepalive_time = 1200
当keepalive 起用的时候,TCP 发送keepalive 消息的频度。缺省是2小时。

net.ipv4.tcp_keepalive_intvl = 30
当探测没有确认时,重新发送探测的频度。缺省是75秒

net.ipv4.tcp_keepalive_probes = 3
在认定连接失效之前,发送多少个TCP的keepalive探测包。缺省值是9。这个值乘以tcp_keepalive_intvl之后决定了,一个连接发送了keepalive之后可以有多少时间没有回应

net.ipv4.tcp_synack_retries = 1
为了打开对端的连接,内核需要发送一个SYN 并附带一个回应前面一个SYN 的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。
syn-ack握手状态重试次数,默认5,遭受syn-flood***时改为1或2 

net.ipv4.tcp_syn_retries = 2
外向syn握手重试次数,默认4

net.ipv4.tcp_max_syn_backlog = 262144
记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M 内存的系统而言,缺省值是1024,小内存的系统则是128。

net.ipv4.tcp_timestamps = 0
时间戳可以避免序列号的卷绕。一个1Gbps 的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。

net.core.rmem_max = 16777216
最大socket读buffer

net.core.wmem_max = 16777216
最大socket写buffer

net.ipv4.tcp_rmem = 4096 87380 4194304
TCP读buffer

net.ipv4.tcp_wmem = 4096 16384 4194304
TCP写buffer

net.core.wmem_default = 8388608
该文件指定了发送套接字缓冲区大小的缺省值(以字节为单位)。

net.core.rmem_default = 8388608
该文件指定了接收套接字缓冲区大小的默认值(以字节为单位)。

net.core.rmem_max = 16777216
指定了接收套接字缓冲区(接收窗口)大小的最大值(以字节为单位);最大的TCP数据接收缓冲

net.core.wmem_max = 16777216
指定了发送套接字缓冲区(接收窗口)大小的最大值(以字节为单位);最大的TCP数据发送缓冲

kernel.sysrq = 0
控制系统调试内核的功能要求

kernel.core_uses_pid = 1
用于调试多线程应用程序

kernel.msgmnb = 65536
每个消息队列的最大字节限制

kernel.msgmax = 65536
每个消息的最大size.

kernel.shmmax = 68719476736
内核参数定义单个共享内存段的最大值

kernel.shmall = 4294967296
控制共享内存页数

net.core.somaxconn = 262144
listen()的默认参数,挂起请求的最大数量.默认是128.对繁忙的服务器,增加该值有助于网络性能.

1.1.示例

# sysctl  -p
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.somaxconn = 262144
kernel.sysrq = 0
kernel.core_uses_pid = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
vm.swappiness = 0
fs.file-max = 409600

2.nginx 优化配置

配置文件说明:

user  nginx;
指定nginx运行的用户

worker_processes  8;
nginx 进程数,建议按照cpu 数目来指定,查看此结果:# cat /proc/cpuinfo  | grep processor  | wc -l

worker_cpu_affinity
为每个进程分配cpu,上例中将8 个进程分配到8 个cpu,当然可以写多个,或者将一个进程分配到多个cpu。

worker_rlimit_nofile  409600
一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数,目前与ulimit -n一致

error_log  /app/local/log/nginx/error.log warn;
定义错误日志路径及日志级别

use epoll;
使用epoll模型

worker_connections  51200;
每个进程允许的最多连接数, 理论上每台nginx 服务器的最大连接数为worker_processes*worker_connections。

server_names_hash_bucket_size 64;
保存服务器名字的hash表是由指令 server_names_hash_max_size 和 server_names_hash_bucket_size所控制的。参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。如果 hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大 hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小.

proxy_headers_hash_max_size 51200;
设置头部哈希表的最大值,不能小于你后端服务器设置的头部总数。

proxy_headers_hash_bucket_size 6400;
这将限制头部字段名称的长度大小,如果你使用超过64个字符的头部名可以加大这个值。

server_tokens off;
关闭版本号显示

include       /app/local/nginx/conf/mime.types;
nginx允许的文件格式

tcp_nopush  on;
告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送

tcp_nodelay on;
告诉nginx不要缓存数据,而是一段一段的发送–当需要及时发送数据时,就应该给应用设置这个属性,这样发送一小块数据信息时就不能立即得到返回值。

keepalive_timeout 
client_header_timeout 20;
client_body_timeout 20;
给客户端分配keep-alive链接超时时间。服务器将在这个超时时间过后关闭链接。我们将它设置低些可以让ngnix持续工作的时间更长。client_header_timeout 和client_body_timeout 设置请求头和请求体(各自)的超时时间。我们也可以把这个设置低些。

reset_timedout_connection
告诉nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。

send_timeout 10;
指定客户端的响应超时时间。这个设置不会用于整个转发器,而是在两次客户端读取操作之间。如果在这段时间内,客户端没有读取任何数据,nginx就会关闭连接。

sendfile    on;
sendfile可以让sendfile()发挥作用。sendfile()可以在磁盘和TCP socket之间互相拷贝数据(或任意两个文件描述符)。Pre-sendfile是传送数据之前在用户空间申请数据缓冲区。之后用read()将数据从文件拷贝到这个缓冲区,write()将缓冲区数据写入网络。sendfile()是立即将数据从磁盘读到OS缓存。因为这种拷贝是在内核完成的,sendfile()要比组合read()和write()以及打开关闭丢弃缓冲更加有效(更多有关于sendfile)


reset_timedout_connection on;
nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。

send_timeout 30;
指定客户端的响应超时时间。这个设置不会用于整个转发器,而是在两次客户端读取操作之间。如果在这段时间内,客户端没有读取任何数据,nginx就会关闭连接。

gzip on;
打开GZIP压缩,实时压缩输出数据流

gzip_min_length 1k;
从Content-Length中数值获取验证,小于1K会越压越大

gzip_buffers 4 16k;
以16K为单位4倍的申请内存做压缩结果流缓存,默认值是申请跟原始数据相同大小的内存空间去存储gzip压缩结果。

gzip_http_version 1.0;
默认1.1,大部分浏览器已经支持gzip解压

gzip_comp_level 4;
压缩比率1-9,1压缩比最小处理速度最快,9压缩比最大但处理最慢且耗CPU

gzip_types text/plain application/x-javascript text/css application/xml;
压缩类型,无论是否指定text/html总是会压缩

gzip_vary on;
此选项可让前端的缓存服务

#以下优化参数导致一些问题,谨慎使用
open_file_cache
打开缓存的同时也指定了缓存最大数目,以及缓存的时间。我们可以设置一个相对高的最大时间,这样我们可以在它们不活动超过20秒后清除掉。

open_file_cache_valid 
在open_file_cache中指定检测正确信息的间隔时间。

open_file_cache_min_uses 
定义了open_file_cache中指令参数不活动时间期间里最小的文件数。

open_file_cache_errors
指定了当搜索一个文件时是否缓存错误信息,也包括再次给配置中添加文件。我们也包括了服务器模块,这些是在不同文件中定义的。如果你的服务器模块不在这些位置,你就得修改这一行来指定正确的位置。

2.2.示例说明

user  nginx;
worker_processes  8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
worker_rlimit_nofile 409600;


error_log  /app/local/log/nginx/error.log warn;
pid        /app/local/nginx/logs/nginx.pid;


events {
	use epoll;
    worker_connections  204800;
}


http {

	server_names_hash_bucket_size 64;
    proxy_headers_hash_max_size 51200;
    proxy_headers_hash_bucket_size 6400;
    include       /app/local/nginx/conf/mime.types;
    default_type  application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" $http_x_forwarded_for $request_length $msec $connection_requests $request_time';

    access_log  /app/local/log/nginx/access.log  main;

	server_tokens off;
    sendfile    on;
    tcp_nopush  on;
	tcp_nodelay on;
	
    keepalive_timeout  65;
	client_header_timeout 20;
	client_body_timeout 20;
	reset_timeout_connection 30;
	send_timeout 30;

	gzip on;
	gzip_min_length 1k;
	gzip_buffers 4 16k;
	gzip_http_version 1.0;
	gzip_comp_level 4;
	gzip_types text/plain application/x-javascript text/css application/xml;
	gzip_vary on;

	open_file_cache max=409600 inactive=30s;
	open_file_cache_valid 30s;
	open_file_cache_min_uses 2;
	open_file_cache_errors on;
	
    include /app/local/nginx/conf/vhosts/*.conf;
}

3.日志格式说明

$remote_addr, $http_x_forwarded_for 记录客户端IP地址
$remote_user 记录客户端用户名称
$request 记录请求的URL和HTTP协议
$status 记录请求状态
$body_bytes_sent 发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。
$bytes_sent 发送给客户端的总字节数。
$connection 连接的序列号。
$connection_requests 当前通过一个连接获得的请求数量。
$msec 日志写入时间。单位为秒,精度是毫秒。
$pipe 如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”。
$http_referer 记录从哪个页面链接访问过来的
$http_user_agent 记录客户端浏览器相关信息
$request_length 请求的长度(包括请求行,请求头和请求正文)。
$request_time 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$time_iso8601 ISO8601标准格式下的本地时间。
$time_local 通用日志格式下的本地时间。

3.2.示例:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" $http_x_forwarded_for $request_length $msec $connection_requests $request_time';
					 
$remote_addr:客户端的真实IP地址
$remote_user: 客户端名称
$time_local: 服务器本地时间
$request: 请求的URL和HTTP协议
$status:记录请求状态
$body_bytes_sent:发送给客户端的字节数,不包括响应头的大小
$http_referer:记录从哪个页面链接访问过来的
$http_user_agent:记录客户端浏览器相关信息
$http_x_forwarded_for:代理模式显示真实客户端地址
$request_length:请求的长度
$msec:日志写入时间
$connection_requests:当前通过一个连接获得的请求数量
$request_time:请求处理时间