一.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;}

  1. if ($document_uri !~ 'abc')

  2. {

  3. rewrite ^/(.*)$ http://www.abc.com/abc/$1 permanent;

  4. }

而不是单独加一句  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

  1. upstream test {

  2.     ip_hash;

  3.     server 192.168.31.100;

  4.     server 192.168.31.101;

  5. }

  6.      server {

  7.             listen 80;

  8.             server_name bbs.aaa.cn;

  9.             location / {

  10.                 proxy_pass      http://test/;

  11.                 proxy_set_header Host   $host;

  12.                 proxy_set_header X-Real-IP      $remote_addr;

  13.                 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  14.             }

  15.         }