一.nginx服务器的介绍
nginx服务器是一个web服务器,有高性能,内存消耗比较低,具有反向代理功能,可以代理web和mail,还有负载均衡的功能,将用户的请求进行转发的real server服务器中
二.nginx安装
1.关闭防火墙和SELINUX
service iptables stop
chkconfig iptables off
chkconfig iptables --list
getenforce
2.在官网下载相关安装包
wget http://nginx.org/download/nginx-1.8.1.tar.gz
3.当下载好了,切换到存放安装包的目录中解压
useradd nginx
groupadd nginx
yum install pcre-devel
yum install -y openssl-devel
tar zxf nginx-18.1.tar.gz
cd nginx-18.1
./configure \
--prefix=/usr/local/nginx \
--sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_flv_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/tmp/nginx/client/ \
--http-proxy-temp-path=/var/tmp/nginx/proxy/ \
--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
--with-pcre
make && make install
四.配置启动脚本
vi /etc/init.d/nginx
#!/bin/bash
# chkconfig: 345 99 20
# description: Nginx service control script
PROG="/usr/local/nginx/sbin/nginx"
PIDF="/usr/local/nginx/logs/nginx.pid"
case "$1" in
start)
$PROG
echo "Nginx service start success."
;;
stop)
kill -s QUIT $(cat $PIDF)
echo "Nginx service stop success."
;;
restart)
$0 stop
$0 start
;;
reload)
kill -s HUP $(cat $PIDF)
echo"reload Nginx config success."
;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac
chmod +x /etc/init.d/nginx
service nginx start
chkconfig --add nginx
chkconfig nginx on
然后启动nginx,
service nginx start
netstat -ltunp如果发现有80端口,代表已经启动起来
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4801/nginx
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1033/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1110/master
tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN 1144/sshd
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 1203/sshd
tcp 0 0 :::22 :::* LISTEN 1033/sshd
tcp 0 0 ::1:25 :::* LISTEN 1110/master
tcp 0 0 ::1:6010 :::* LISTEN 1144/sshd
tcp 0 0 ::1:6011 :::* LISTEN 1203/sshd
三.nginx配置文件详细讲解
nginx配置文件有4个部分组成,main(全局设置),server(虚拟主机设置),location(URL匹配设置),upstram(负载均衡器的设置),main设置将影响其它的设置,server 设置指定指定端口和主机,location设置指定URL匹配,upstram指定负载均衡,
user nginx nginx;
#定义nginx运行的用户和用户组
worker_processes 8;
#nginx的运行进程数,建议设置等于cpu的总核心数,一般是8
pid/export/servers/nginx/run/nginx.pid
#进程pid的文件
worker_rlimit_nofile 65535
#一个nginx进程应许打卡的最大文件数。
events
{
use epoll;
#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型
是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。
worker_connections 65535;
#单个进程的最大连接数
}
http
#设定http服务器,利用它的反向代理功能提供负载均衡支持
{
include mime.types;
#设定mime类型,类型由mime.types文件定义
default_type application/octet-stream;
#默认文件类型
server_tokens on;
#nginx在调用的时候,可以知道nginx的版本信息
log_format main '$remote_addr - $remote_user [$time_local] '
#记录客户端的ip,客户端用户名称,访问时间和时区
'"$request" $status $bytes_sent '
#用来记录请求的url与http协议,状态(200成功),发送客户端文件大小
'"$http_referer" "$http_user_agent" '
#记录从哪个页面链接访问过来了,记录客户
'"$request_time $upstream_response_time $pipe" '
#求情相应时间,upstream请求相应时间,
'"$gzip_ratio"';
#设定日志格式
charset utf-8;
#默认的编码字符集
server_names_hash_bucket_size 128;
#服务器名字的hash表的大小
client_header_buffer_size 32k;
#上传文件大小限制
large_client_header_buffers 4 32k;
#设定请求缓存
#nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取,如果设置过小HTTP头/Cookie过大 会报400 错误即:nginx 400 bad request。求行如果超过buffer,就会报HTTP 414错误(URI Too Long)nginx接受最长的HTTP头部大小必须比其中一个buffer大,否则就会报400的,HTTP错误(Bad Request)。
client_max_body_size 300m;
client_body_buffer_size 512k;
#设定请求缓存
sendfile on;
#开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为on
tcp_nopush on;
#防止网络堵塞
tcp_nodelay on;
#防止网络堵塞
keepalive_timeout 0;
#长链接超时时间,单位是秒
#fastcgi相关参数是为了改善网站性能;减少资源占用,提高访问速率
fastcgi_intercept_errors on;
#指定是否传递4xx和5xx错误信息到客户端,或者允许nginx使用error_page处理错误信息
#利用proxy模块给nginx加入缓存,提高http的相应请求效率
proxy_connect_timeout 90;
#后端服务器连接超时的时间,发起握手等候响应超时时间,
proxy_read_timeout 180;
#连接成功后,后端服务器处理请求的时间
proxy_send_timeout 180;
#在180秒内,后端服务器必须传完所有数据
proxy_buffer_size 256k;
#通常情况下,这部分被设置为第一部分应答的缓存区的大小,这个是应答头的大小
proxy_buffers 4 256k;
#缓存区的大小
proxy_busy_buffers_size 256k;
#高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 256k;
#设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
proxy_intercept_errors on;
#设置客户端应许看到缓存的出错信息
proxy_hide_header X-Powered-By;
#隐藏不必要的头,减少数据传输
server_name_in_redirect off;
#让 nginx 在处理自己内部重定向时不默认使用 server_name 设置中的第一个域名;
gzip on;
#开启gzip压缩传输
gzip_min_length 100;
#最小压缩文件大小
gzip_buffers 4 16k;
#压缩缓冲区
gzip_http_version 1.0;
#压缩版本
gzip_types text/plain application/x-javascript text/css application/xml;
#压缩类型
gzip_vary on;
error_page 400 401 402 403 404 405 408 410 412 413 414 415 500 501 502 503 506 = http://www.jd.com/error2.aspx;
lua_package_path '/export/servers/nginx/var/lua/?/?.lua;/export/servers/nginx/var/lua/?.lua;;';
#lua脚本
include domains/*.upstream.conf;
#nginx的upstream模块,负载均衡主要通过这个模块实现
####### server ##########
server
{
listen 80;
#监听的端口
server_name shpls.wms5.jd.com;
#第一个域名
access_log /export/servers/nginx/logs/access.log main;
#访问日志
error_log /export/servers/nginx/logs/error.log warn;
#错误日志,error_log 级别分为 debug, info, notice, warn, error, crit 默认为crit, 该级别在日志名后边定义格式如下:error_log /your/path/error.log crit; crit 记录的日志最少,而debug记录的日志最多。如果你的nginx遇到一些问题,比如502比较频繁出现,但是看默认的error_log并没有看到有意义的信息,那么就可以调一下错误日志的级别,当你调成error级别时,错误日志记录的内容会更加丰富。
location / {
#access_log on;
root html;
indexindex.html index.htm;
}
location = /status {
stub_statuson;
access_logoff;
}
include domains/*.location.conf;
location ^~ /winapp/ {
root /export/App/app.wms5.jd.local;
index ReleaseList.xml;
}
location ^~ /rfapp/ {
root /export/App/app.wms5.jd.local;
index ReleaseList.xml;
}
location ~ ^/([^/]+)/.+ {
set $wms_app_module $1;
rewrite ^/\w+/(.+)$ /$1 break;
content_by_lua_file /export/servers/nginx/var/lua/approute.lua;
}
}
}
1、日志格式说明解释
1.$remote_addr 与$http_x_forwarded_for 用以记录客户端的ip地址;
2.$remote_user :用来记录客户端用户名称;
3.$time_local : 用来记录访问时间与时区;
4.$request : 用来记录请求的url与http协议;
5.$status : 用来记录请求状态;成功是200,
6.$body_bytes_s ent :记录发送给客户端文件主体内容大小;
7.$http_referer :用来记录从那个页面链接访问过来的;
8.$http_user_agent :记录客户端浏览器的相关信息;
三.定义rewrite重写
1.rewrite规则:
nginx通过ngx_http_rewrite_module模块支持url重写和if条件判断,但要使用rewrite功能,还需要pcre的支持,应该在编译nginx的时候指定pcre的源码目录,rewrite的使用语法如下:
rewrite命令默认的最后一项参数为flag标记,其支持flag标记主要有一下集中:
last:相当于apache的[L]标记,表示完成rewrite之后搜索相应的url或者location
break:表示总之匹配,不在匹配后面的规则;
redirect:返回302临时重定向,
permanent:返回301永久重定向
rewrite的使用字段
location
server
if
if (!-e $request_filename) {rewrite ^/(index|atom|rsd)\.xml$ http://feed.shunz.net last;rewrite ^([_0-9a-zA-Z-]+)?(/wp-.*) $2 last;rewrite ^([_0-9a-zA-Z-]+)?(/.*\.php)$ $2 last;rewrite ^ /index.php last;}
if ($document_uri !~ 'abc')
{
rewrite ^/(.*)$ http://www.abc.com/abc/$1 permanent;
}
而不是单独加一句 rewrite ^/(.*)$ http://www.abc.com/abc/$1 permanent;
如果只加rewrite 规则,而不限定条件,那么会造成死循环。 会访问到 http://www.abc.com/abc/abc/abc/abc/....
2.if命令
~ 为区分大小写匹配
~* 为不区分大小写匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
nginx的很多内容变量,可以和if命令一起使用:
$args 1.0.8 请求中的参数;
$body_bytes_sent 1.0.8 已发送的消息体字节数
$content_length 1.0.8 HTTP请求信息里的"Content-Length";
$content_type 1.0.8 请求信息里的"Content-Type";
$document_root 1.0.8 针对当前请求的根路径设置值;
$document_uri 1.0.8 与$uri相同; 比如 /test1/test2/test.php
$host 1.0.8 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$http_cookie 1.0.8 cookie 信息
$http_referer 1.0.8 引用地址
$http_user_agent 1.0.8 客户端代理信息
$http_x_forwarded_for 1.0.8
$remote_addr 1.0.8 客户端地址;
$remote_port 1.0.8 客户端端口号;
$remote_user 1.0.8 客户端用户名,认证用;
$request 1.0.8 用户请求
$request_body_file 1.0.8 发往后端的本地文件名称
$request_filename 1.0.8 当前请求的文件路径名,比如$request_filename:D:\nginx/html/test1/test2/test.php
$request_method 1.0.8 请求的方法,比如"GET"、"POST"等;
$request_uri 1.0.8 请求的URI,带参数; 比如http://localhost:88/test1/test2/test.php
$scheme 1.0.8 所用的协议,比如http或者是https,比如rewrite^(.+)$$scheme://example.com$1redirect;
$server_addr 1.0.8 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name 1.0.8 请求到达的服务器名;
$server_port 1.0.8 请求到达的服务器端口号;
$server_protocol 1.0.8 请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$uri 1.0.8 请求的URI,可能和最初的值有不同,比如经过重定向之类的。
四.nginx内核调优
一、关于内核参数的优化:
net.ipv4.tcp_max_tw_buckets = 6000
timewait 的数量,默认是180000。
net.ipv4.ip_local_port_range = 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.core.somaxconn = 262144
web 应用中listen 函数的backlog 默认会给我们内核参数的net.core.somaxconn限制到128,而nginx 定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。
net.core.netdev_max_backlog = 262144
每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.ipv4.tcp_max_orphans = 262144
系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS攻击,不能过分依
系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。
net.ipv4.tcp_max_syn_backlog = 262144
记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128。
net.ipv4.tcp_timestamps = 0
时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。
net.ipv4.tcp_synack_retries = 1
为了打开对端的连接,内核需要发送一个SYN 并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。
net.ipv4.tcp_syn_retries = 1
在内核放弃建立连接之前发送SYN 包的数量。
net.ipv4.tcp_fin_timeout = 1
如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60 秒。2.2 内核的通常值是180秒,3你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB 服务器,也有因为大量的死套接字而内存溢出的风险,FIN-WAIT-2 的危险性比FIN-WAIT-1 要小,因为它最多只能吃掉1.5K 内存,但是它们的生存期长些。
net.ipv4.tcp_keepalive_time = 30
当keepalive 起用的时候,TCP 发送keepalive 消息的频度。缺省是2 小时。
二:内核参数修改
将/proc/sys中的文件转换成sysctl中的变量依据下面两个简单的规则:
1.去掉前面部分/proc/sys
2.将文件名中的斜杠变为点
例如:
/proc/sys/net/ipv4/ip_forward =》 net.ipv4.ip_forward
/proc/sys/kernel/hostname =》 kernel.hostname
nginx的web连接中出现过多的TIME_WAIT过多,最终会把nginx给脱挂,查看内核参数
把内核参数改成:
shell> sysctl net.ipv4.tcp_timestamps=1
#net.ipv4.tcp_timestamps 开启时,net.ipv4.tcp_tw_recycle开启才能生效 shell> sysctl net.ipv4.tcp_tw_recycle=1
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
这个变量和时间戳有关,lvs的nat模式中,在转发请求的时候,会把请求中的源ip和目标ip改变,时间戳可能会变,所以就会被回收,但是dr模式,时间戳是不会变的,所以dr模式开启没有问题
shell> sysctl net.ipv4.tcp_tw_reuse=1
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;该文件表示是否允许重新应用处于TIME-WAIT状态的socket用于新的TCP连接(这个对快速重启动某些服务,而启动后提示端口已经被使用的情形非常有帮助)
net.ipv4.tcp_tw_recycle依赖net.ipv4.tcp_timestamps
如果后者开启,前者才会生效
也可以vim /etc/sysctl.conf ,最后sysctl -p就可以生效了!、
主动关闭的一方在发送最后一个 ack 后
就会进入 TIME_WAIT 状态 停留2MSL(max segment lifetime)时间
这个是TCP/IP必不可少的,也就是“解决”不了的。
也就是TCP/IP设计者本来是这么设计的
主要有两个原因
1。防止上一次连接中的包,迷路后重新出现,影响新连接
(经过2MSL,上一次连接中所有的重复包都会消失)
2。可靠的关闭TCP连接
在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发
fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以
主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。
三、下面贴一个完整的内核优化设置:
vi /etc/sysctl.confCentOS5.5中可以将所有内容清空直接替换为如下内容:
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_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.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_timestamps = 0
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 = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000
使配置立即生效可使用如下命令:
/sbin/sysctl -p
四、下面是关于系统连接数的优化
linux 默认值 open files 和 max user processes 为1024
#ulimit -n
1024
#ulimit –u
1024
问题描述:说明 server 只允许同时打开 1024 个文件,处理 1024个用户进程
使用ulimit -a 可以查看当前系统的所有限制值,使用ulimit -n 可以查看当前的最大打开文件数。
新装的linux 默认只有1024 ,当作负载较大的服务器时,很容易遇到error: too many open files。因此,需要将其改大。
解决方法:
使用 ulimit –n 65535 可即时修改,但重启后就无效了。(注ulimit -SHn 65535 等效 ulimit-n 65535 ,-S 指soft ,-H 指hard)
有如下三种修改方式:
1. 在/etc/rc.local 中增加一行 ulimit -SHn 65535
2. 在/etc/profile 中增加一行 ulimit -SHn 65535
3.在/etc/security/limits.conf最后增加:
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
具体使用哪种,在 CentOS 中使用第1 种方式无效果,使用第3 种方式有效果,而在Debian 中使用第2种有效果
# ulimit -n
65535
# ulimit -u
65535
备注:ulimit 命令本身就有分软硬设置,加-H 就是硬,加-S 就是软默认显示的是软限制
soft 限制指的是当前系统生效的设置值。 hard 限制值可以被普通用户降低。但是不能增加。 soft 限制不能设置的比hard 限制更高。 只有 root 用户才能够增加 hard 限制值。
第五:反向代理和负载均衡
反向代理,是把一些静态资源存储在服务器上,当用户有请求的时候,就直接返回反向代理服务器上的资源给用户,而如果反向代理服务器上没有的资源,就转发给后面的负载均衡服务器,负载均衡服务器再将请求分发给后端的web服务器。负载均衡用upstream模块,反向代理用location proxy_pass
upstream test {
ip_hash;
server 192.168.31.100;
server 192.168.31.101;
}
server {
listen 80;
server_name bbs.aaa.cn;
location / {
proxy_pass http://test/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}