nginx介绍:
nginx是一款轻量级的web服务器/反向代理服务器及邮件代理服务器,由俄罗斯人
Igor Sysoev研发,特点是占用内存较少,并发能力强,官方测试,能支持高达50000并发,还有丰富的第三方模块,满足大部分业务需求,中国大陆使用nginx的大公司有阿里、百度、腾讯、新浪、网易等。
一、安装(以下采用源码安装,方便以后嵌入第三方模块):
1.1 系统centos6.5(nginx最好使用linux系统,对windows支持不是很好,功能模块也不多)
nginx: 192.168.4.72
apache: 192.168.4.69
apache: 192.168.4.68
1.2
安装gcc和nginx需要的依赖库
yum install gcc-c++ -y
yum -y install zlib-devel openssl-devel pcre-devel
1.3
如有安装老版本,则卸载。
查看:whereis nginx #如果有则
卸载
卸载:yum remove nginx
1.4
下载nginx源码并解压.(源码去官网下载, 以下是官方链接)
#源码是采用官方稳定版本1.8.0,
解压:
tar -zxvf nginx-1.8.0.tar.gz
cd nginx-1.8.0
编译:
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx
--with-http_ssl_module --with-http_realip_module
--with-http_addition_module --with-http_sub_module
--with-http_dav_module --with-http_gunzip_module
--with-http_gzip_static_module --with-http_random_index_module
--with-http_secure_link_module --with-http_stub_status_module --with-file-aio --with-debug
注:这里--with开头的选项为nginx自带的模块,需要什么就添加,默认是不安装,(第三方模块下面再介绍)
make && make install
1.5
建立nginx用户及用户组
groupadd -r nginx
useradd -s /sbin/nologin -g nginx -r nginx
1.6 启动:
cd 到nginx目录,看能否启动
sbin/nginx
再ps一下,ps ax | grep nginx,看到如下,
说明ok
2537 ? Ss 0:00 nginx: master process sbin/nginx
2538 ? S 0:00 nginx: worker process
nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。
查看安装的nginx版本:
sbin/nginx -v
查看安装的编译选项:
sbin/nginx -V
二、nginx配置及正向与反向代理:
2.1 nginx.conf配置文件的结构
….. #全局块,设置nginx整体运行的配置指令
events { #events块,设置nginx与用户的网络连接,这块指令对性能影响较大
…...
}
http { #http块,包含代理,缓存,日志字义和第三方模块
…… #http的全局块,设置文件引入,日志,连接超时时间....
server { #server块,相当于“虚拟主机”的意思,可以多个
……. #server全局块,作用域只在本server,不会影响其它server
location [ pattern ] { #location块,可以多个,对访问用户的url进行匹配处理,地址定向,
#数据缓存,还有很多第三方模块配置也在这
…….
}
}
server { #server块
…….
}
……. #http全局块
}
2.2 下面是一个正向代理的例子,指令不多(这里只展示server段的配置,其它默认就行):
…..
server {
resolver 8.8.8.8;
listen 82;
location / {
proxy_pass http://$http_host$request_uri;
}
}
2.3 下面是反向代理的例子(这块指令较多,只配置关键的指令,其它一些指令在优化中有体现)
user nginx nginx; #这里是nginx运行的用户
worker_processes 2; #设置nginx服务的worker子进程,比如设为2:
error_log logs/error.log #去掉前面的#,记录nginx错误日志,方便检查bug:
pid logs/nginx.pid #nginx的pid位置
events {
worker_connections 1024;
}
http {
include 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"';
access_log logs/access.log main; #日志存放位置
#
这里的upstream就是配置负载均衡的,当然得两台以上才叫负载,我这里的ip69和68都是
用的apache, 也许你们的是tomcat, 没关系,按这样配置一样可以,
upstream proxy_test {
server 192.168.4.69:80 weight=1; #如果要测试,把这里换成自己要代理后端的ip
server 192.168.4.68:80 weight=1;
#ip_hash; #当负载两台以上用ip来hash解决session的问题,一台就别hash了。
}
server {
listen 80;
charset utf8;
location / {
proxy_pass http://proxy_test; #该指令设置被代理服务器地址
#这里proxy_test是上面的负载的名称,映射到代理服务器,
#可以是ip加端口, 或url ,
proxy_set_header Host $host; #该指令接收客户端请求头信息,然后发送给被代理服务器,
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
保存退出后,
nginx平滑重启:sbin/nginx -s reload #加载刚刚加入的配置。
2.3.2.
测试:
后端服务器开启,在192.168.4.69和68的网页文件位置添加测试文件test.html, 内容69上: this is test 69, 68上:this is test 68,这样方便查看访问到哪台,
在本地配置好host,
打开浏览器用www.test.com去访问后端服务器的文件,
浏览器打开显示有this...说明配置ok了。
然后F5刷新一下,如果是68和69不停的切换,说明负载ok。
2.4 nginx处理请求的几个阶段:
NGX_HTTP_POST_READ_PHASE:
读取请求内容阶段
NGX_HTTP_SERVER_REWRITE_PHASE: Server请求地址重写阶段
NGX_HTTP_FIND_CONFIG_PHASE: 配置查找阶段:
NGX_HTTP_REWRITE_PHASE: Location请求地址重写阶段
NGX_HTTP_POST_REWRITE_PHASE: 请求地址重写提交阶段
NGX_HTTP_PREACCESS_PHASE: 访问权限检查准备阶
NGX_HTTP_ACCESS_PHASE: 访问权限检查阶段
NGX_HTTP_POST_ACCESS_PHASE: 访问权限检查提交阶段
NGX_HTTP_TRY_FILES_PHASE: 配置项try_files处理阶段
NGX_HTTP_CONTENT_PHASE: 内容产生阶段
NGX_HTTP_LOG_PHASE: 日志模块处理阶段
三、nginx优化:
优化不光是nginx本身,还得结合服务器硬件来优化以及系统内核优化,下面是nginx本身的优化的一些指令:
worker_processes 4; #
nginx进程数,建议按cpu数目来指定,一般为它的倍数,官方默认为1,
#当然这个值不是越大就越好,越大会影响系统的IO效率,也会增加主进程的负担,
#我这里使用的是4,即4核cpu, 该指令配置在全局块。
worker_cpu_affinity 0001 0100 1000 0010; #该指令用来分配cpu的内核,设置有点麻烦,参数是二进制
#下面是一个8核的配置;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
worker_rlimit_nofile 102400;
#这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。
worker_connections 102400;
#每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数是: worker_processes*worker_connections。
keepalive_timeout 60; #keepalive超时时间。
client_header_buffer_size 4k;
#
客户端请求头部的缓冲区大小,这个可以根据系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。(用命令getconf PAGESIZE 取得系统分页大小
)
open_file_cache max=102400 inactive=20s;
#这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。
open_file_cache_valid 30s;
#这个是指多长时间检查一次缓存的有效信息。
open_file_cache_min_uses 1;
#open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。
下面是http段的一些指令(这些指令偏重于对生产业务的需求,有部分指令可以在全局设置,详细可以参考官网)
client_max_body_size 300m;
# 设定通过nginx上传文件的大小
proxy_connect_timeout 90;
#后端服务器连接的超时时间_发起握手等候响应超时时间
proxy_read_timeout 180;
#连接成功后等候后端服务器响应时间,其实已经进入后端的排队之中等候处理,也可以说是后端服务器处理请求的时间,当超过这个时间后,返回的是504,之前在生产环境中遇到过这个问题,也就是后端的tomcat有个程序需要解压大文件,花时要3分多钟,而我这设置的是60,所以一直是504。
proxy_send_timeout 180;
#后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
proxy_buffer_size 256k;
#设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头,默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小
proxy_buffers 4 256k;
#设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k
proxy_busy_buffers_size 256k; #
控制同时传输到客户端的buffer数量
proxy_temp_file_write_size 256k;
#设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
proxy_temp_path /data0/proxy_temp_dir;
#proxy_temp_path和proxy_cache_path指定的路径必须在同一分区
proxy_cache_path /data0/proxy_cache_dir levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;
#设置内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。
client_body_buffer_size 512k;
#如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了,无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误。
gzip on; #这里开启压缩功能,更快的传输,
gzip_min_length 1k; #压缩大于1K的文件,小于1K的越压越大
gzip_buffers 4 16k; #压缩缓存大小配置。
gunzip on; #开启解压缩。
注:这里出现一个问题,就是这么多的buffers配置,是不是很多请求使用同一个buffers呢,答案是否,一个请求来时,nginx会分配独立的一套配置给它,然后使用这些参数,当使用完,即刻就释放了,另外这里只是nginx常用的需要优化的指令,更多的指令参考官网:
http://nginx.org/en/docs/
四、nginx的内置变量(部分):
nginx提供了很多的内置变量,可以使用这些变量得到想关信息
$args, 请求中的参数;
$status 响应的状态代码;
$request_time 请求时间,这个时间是指nginx在这个请求中的所花的时间,精确到毫秒
$content_length, HTTP请求信息里的"Content-Length";
$content_type, 请求信息里的"Content-Type";
$document_root, 针对当前请求的根路径设置值;
$document_uri, 与$uri相同;
$host, 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$limit_rate, 对连接速率的限制;
$request_method, 请求的方法,比如"GET"、"POST"等;
$remote_addr, 客户端地址;
$remote_port, 客户端端口号;
$remote_user, 客户端用户名,认证用;
$request_filename, 当前请求的文件路径名
$request_body_file, ??
$request_uri, 请求的URI,带参数;
$query_string, 与$args相同;
$scheme, 所用的协议,比如http或者是https,比如rewrite ^(.+)$ $scheme://example.com$1 redirect;
$server_protocol, 请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr, 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name, 请求到达的服务器名;
$server_port, 请求到达的服务器端口号;
$uri, 请求的URI,可能和最初的值有不同,比如经过重定向之类的。
注:更多指令参考官方
五、嵌入第三方模块,这里以nginx_upstream_check_module和lua-nginx-module为例
nginx_upstream_check_module
这个模块是由淘宝姚伟斌团队开发,已经开源,功能是对后端服务器的健康检查,如果后端某台服务器不可用时,会标记为down, 并把请求转发给其它后端可用的服务器。 直到该服务器可用时,才标记为up,并转发请求。
lua-nginx-module这个模块主要由前淘宝章亦春开发,并已经开源,代码在github上,现在他主要在做这方面的开源工作,并不断在更新完善,丰富的API,功能集非常强大,主要满足业务上的各种需求。
模块:
nginx把各个功能模块加载起来,形成链条式的,当用户请求过来,然后依次经过这些模块或跳过某些模块,让这些模块实现特定的功能需求。
5.1 nginx_upstream_check_module模块下载地址:
nginx加载模块时,需要重新编译,编译时加上这个
--add-module=nginx_upstream_check_module-0.3.0
配置:
upstream www.test.com {
server 172.10.2.170:80;
server 172.10.2.206:80;
check interval=3000 rise=2 fall=4 timeout=1000; #该模块的配置主要在这
}
#interval检测间隔时间,单位为毫秒,rsie请求2次正常的话,标记此realserver的状态为up,fall表示请求4次都失败的情况下,标记此realserver的状态为down,timeout为超时时间,单位为毫秒。
5.2lua-nginx-module模块下载地址:
下载lua需要的库:
wget http://luajit.org/download/LuaJIT-2.0.0-beta9.tar.gz
安装库:
cd LuaJIT-2.0.0-beta9 make &&
make install PREFIX=/usr/local/luajit
ln -sf luajit-2.0.0-beta9 /usr/local/bin/luajit
配置好环境变量
export LUAJIT_LIB=/usr/local/lib
export LUAJIT_INC=/usr/local/include/luajit-2.0
再编译加上
--add-module=lua-nginx-module-0.9.13
5.3 简单例子:
location / {
content_by_lua '
ngx.say("hello nginx")
';
}
#然后用ip进行访问,会输出hello nginx