使用Nginx那么久了,一直没时间做总结.今天刚好有时间总结一下.
用过Apache集合Tomcat做Web项目的朋友应该深有体会Apache配置集成的时候各种配置相当繁琐,而且性能一般. 今天我要总结的Nginx和Apache类似也是一款HTTP和反向代理软件,但是他的配置相对Apache简单的多,性能也比Apache要高.大家应该都知道为什么要使用HTTP代理服务器吧举例一点.例如在做的web项目中如果项目中即包含了html页面也包含了jsp页面,Tomcat渲染html的效率和成本不如http服务器.所以可以让http服务器解析html页面和一些静态资源,tomcat提供服务或者渲染jsp页面等.
Nginx特点及优势:
- 模块化结构设计
- 支持正向和反向代理,虚拟主机,URL重写,压缩传输,SSL加密
- 处理静态文件,索引文件效率非常高
- 可用于实现无缓存的反向代理加速,提高网站运行速度
- 可用作HTTP代理服务器对外提供服务,还支持简单的容错和负载均衡
- 专门为性能优化而开发的,采用内核Poll模型,支持并发链接,资源占用低
- 采用分阶段资源分配技术CPU与内存的占用率非常低,因此类似DOS这样的攻击对Nginx基本没用
- 支持热部署,启动速度特别迅速
这里我就不多列举了,我主要介绍的Nginx内容有:
- Nginx的安装
- Nginx的模块化结构
- Nginx的常用模块设置
- Nginx的常用命令
- Nginx常用功能
- Nginx负载均衡
Nginx的安装
- Nginx的官方下载地址: http://nginx.org/en/download.html ,选择对应版本进行安装. 其实windows和linux的安装都比较简单下一步,下面介绍下linux下的安装操作.
- 解压文件tar -xvf nginx-1.10.1.tar.gz
- cd nginx-1.10.1进入解压后的文件,执行configure配置操作
- 然后执行make && make install既可完成nginx的安装
Nginx的模块化结构
Nginx的模块结构主要分为核心模块,基础模块和第三方模块.HTTP模块,EVENT模块和MAIL模块等属于核心模块.HTTP Access模块, HTTP FastCGI模块, HTTP Proxy模块和HTTP Rewrite模块属于基础模块.HTTP Upstream Request Hash模块, Notice模块和HTTP Access Key模块属于第三方模块.
Nginx的模块从功能上分为三类:
- Handlers(处理器模块), 此类模块直接处理请求, 并进行输出内容和修改headers信息等操作. Handlers处理器模块一般只有一个.
- Filters(过滤器模块), 此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出.
- Proxies(代理类模块), 此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务进行交互,实现服务代理和负载均衡等功能.
Nginx请求处理流程如图所示:
Nginx在工作方式上分为单工作进程和多工作进程两种模式.在单工作进程模式下除主进程外,还有一个工作进程,工作进程是单线程的;在多工作进程模式下,每个工作进程包含多个线程.Nginx默认为单工作进程模式.
Nginx配置文件在Nginx安装目录的conf目录下,这个文件目录也是我们主要打交道的文件目录.整个配置文件爱你以block的形式组织,每个block一般以一个大括号”{}”来表示,整个配置文件中main指令位于最高层,在main层下可以有Events,HTTP等层,在HTTP层中又包含server层等信息如下图
Nginx主配置文件中main设置全局参数,server设置主机参数可以包含多个,upstream设置负责均衡服务器可以包含多个,location设置URL匹配特定位置也可以包含多个就是处理哪一个请求的URL.
Nginx的常用配置及参数设置
Nginx配置实例介绍nginx.conf
1 | user nobody nobody; |
这段代码用于对Nginx的全局属性进行设置,每个参数含义如下:
- user: 主模块命令, 指定Nginx的worker进程运行用户以及用户组,默认由nobody账号运行。
- worker_processes: 指定Nginx要开启的进程数。
- error_log: 用来定义全局错误日志文件。日志输出级别有debug, info, notice, warn, error, crit可供选择,其中debug输出日志最为详细,而crit输出日志量最少。
- pid: 用来指定进程id的存储文件位置。
- worker_rlimit_nofile: 用于绑定worker进程和CPU, Linux内核2.4以上可用。
- events: 设定Nginx的工作模式及连接数上限。其中参数“use”用来指定Nginx的工作模式,Nginx支持的工作模式有select, poll, kqueue, epoll, rtsig和/dev/poll。其中select和poll都是标准的工作模式, kqueue和epoll是高效的工作模式,对于Linux系统,epoll工作模式是首选。参数“worker_connections”用于定义Nginx每个进程的最大连接数,默认是1024。进程的最大连接数受Linux系统进程的最大打开文件数限制,在执行操作系统命令“ulimit -n 65536”后worker_connections的设置才有效。
- 最大客户端连接数max_client = worker_processes * worker_connections;
Nginx的HTTP服务器配置实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25http{
include conf/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'"$reqeust" $status $bytes_sent '
'"$http_referer" "4http_user_agent" '
'"$gzip_ratio"';
log_format download '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$$http_referer" "$http_user_agent" '
'"$http_range" "$sent_http_content_range"';
access_log logs/www.xieahui.com.log main;
client_max_body_size 20m;
client_header_buffer_size 32k;
large_client_header_buffers 4 128k;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_time 60;
client_header_timeout 10;
client_body_timeout 10;
send_timeout 10;
}
配置属性的含义如下:
- include: 主模块命令,实现对配置文件所包含文件的设定,可以减少主配置文件的复杂度。这个include命令在大型系统配置使用的概率很高,可以包含独立的server文件、upstream文件等。
- default_type: 属于HTTP核心模块命令,这里设定默认类型为二进制流,就是说当文件类型未定义时使用这种方式,可用于下载文件设置。
- log_format: 用于指定Nginx日志的输出格式。main为此日志输出格式的名称,可以在下面的access_log命令中引用。
- client_max_body_size: 用来设置允许客户端请求的最大的单个文件字节数。
- client_header_buffer_size: 用于指定来自客户端请求的headerBuffer大小。对于大多数请求,1KB的缓存区已经足够,如果自定了消息头或者有更大的cookie可以增加缓冲区大小。
- large_clent_header_buffers: 用来指定客户端请求中较大的消息头的花村最大数量和大小。“4”为个数,“128”为大小,最大缓存数量为4个128KB。
- sendfile: 用于开启高效文件输出模式。将tcp_nopush和tcp_nodelay两个命令设置为“on”用于放置网络阻塞。
- keepalive_time: 设置客户端连接保持活动的超时时间。超过这个时间后服务器会关闭这个连接。
- client_header_timeout: 设置客户端请求头读取超时时间。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回“Request time out(408)”错误。
- client_body_timeout: 设置客户端请求主题读取超时时间。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回“Request time out(408)”错误。
- send_timeout: 指定相应客户端的超时时间。这个超时仅限于两个链接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。
HttpGzip模块属性设置
1 | gzip on; |
配置属性的含义如下:
- gzip: 用于设置开启或关闭gzip模块,“gzip on”表示开启GZIP压缩,实时压缩输出数据流。
- gzip_min_length: 设置允许压缩的页面最小字节,页面字节数从header头的Content-Length中获取。默认值为0,不管页面多大都进行压缩。建议设置成大于1KB的字节,小于1KB可能会越压缩越大。
- gzip_buffers: 表示申请4个单位为16KB的内存座位压缩结果流缓存,默认是申请与原始数据大小相同的内存空间来存储GZIP压缩结果。
- gzip_http_version: 用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP压缩,使用默认即可。
- gzip_cop_level: 用来指定GZIP压缩比,1表示压缩比最小处理速度最开;9表示压缩比最大传输速度快,但是处理速度最慢也比较消耗CPU资源。
- gzip_types: 用来指定压缩的类型,无论是否指定“text/html”类型总是会被压缩的。
- gzip_vary:
虚拟主机配置
1 | server{ |
如果server配置有多个可以将server独立到一个文件中,然后通过include命令包含进去。这样更利于维护和管理,upstream做负载的时候有同理。参数含义:
- server: 定义虚拟主机开始的关键字;
- listen: 用于指定虚拟主机的服务端口;
- server_name: 用来指定IP地址或域名,多个域名之间用空格分开;
- index: 用于设定访问的默认首页地址;
- root: 用于指定虚拟主机的网页根目录,这个目录可以是绝对路径也可以是相对的;
- charset: 用于设置网页的默认编码格式;
- access_log: 用来指定虚拟主机的访问日志存放路径,最后的main用于指定访问日志的输出格式。
URL地址设置
1 | location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${ |
URL地址匹配是Nginx最灵活常见的部分。location支持正则表达式配置也支持条件判断。可以通过location命令实现Nginx对动态、静态网页进行过滤处理。
- 第一个location:所有扩展名以.gif, .jpg, .jpeg, .png, .bmp, .swf结尾的静态文件都交给Nginx处理expires用来指定静态文件的过期时间。
- 第二个location: 将/web/www/page文件夹下的upload和html下所有文件都交给Nginx来处理。
- 第三个location: 将所有以.jsp为后缀的文件都交给本机的8080端口处理,这个配置一般用来配置需要服务器处理的请求。上面两个一般是做前段静态页面解析。
第四个location中参数的意义:
- stub_status: 设置为“on”表示启用StubStatus的工作状态统计功能;
- access_log: 用来指定StubStatus模块的访问日志文件。
- auth_basic: 是Nginx的一种认证机制。
- auth_basic_user_file: 用来指定认证的密码文件。
Nginx的auth_basic认证采用的是与Apache兼容的密码文件,因此需要用Apache的htpasswd命令来生成密码文件。例如,添加一个webadmin用户,可以使用下面的方式生成密码文件:
/usr/local/apache/bin/htpasswd -c /usr/local/nginx/conf/htpasswd webadmin
会得到以下提示信息:
New password:
在输入密码之后,系统会要求再次输入密码。确认面正确之后成功添加用户。
可以输入http://ip/NginxStatus然后输入刚刚创建的用户名和密码,可以查看Nginx的监控信息1
2
3
4Active connections: 1
server accepts handled requests
393411 393411 393799
Reading: 0 Writing: 1 Waiting: 0
其中,“Active connections”表示当前活跃的连接数,第三行的三个数字表示Nginx当前总共处理的请求数, 成功的握手数, 总共处理的请求数。最后一行“Reading”表示Nginx读取到客户端Header信息数, “Writing”表示Nginx返回给客户端的Header信息数, “Waiting”表示Nginx已经处理完,正在等候下一次请求命令时的驻留连接数。
虚拟主机的错误页面设置
1 | error_page 404 /404.html; |
通过error_page命令可以定制各种错误页面,默认请求下Nginx的页面文件是放在html文件夹下。特别注意,这些错误页面大小不要超过512KB,否则会被IE浏览器替换为IE默认的错误页面。
Nginx的常用命令
Nginx配置环境变量后使用很方便不用局限于sbin目录,如果没有配置环境变量需要在nginx安装路径的sbin下执行。
Nginx配置正确性检查:
1
nginx -t 或者 nginx -t -c /usr/local/nginx/conf/nginx.conf
其中“-t” 用于检测配置文件是否正确。“-c”参数用于指定配置文件路径,不指定默认会在安装目录下参照conf/nginx.conf文件。如果没问题会提示 syntax is ok, test is successful等信息。
Nginx版本信息查看:
1
nginx -v
Nginx版本和编译信息:
1
nginx -V
Nginx启动:
1
nginx
Nginx关闭:
1
nginx -s stop
Nginx重启:
1
nginx -s reload
Nginx进程查看:
1
ps -ef | grep nginx
if命令
if命令用于条件判断,可以在server和location中使用。在if命令判断语句中可以使用正则表达式或者匹配条件。
正则表达式如下:
~: 表示区分大小写匹配;
~*: 表示不区分大小写匹配;
!~和!~*: 分别表示区分大小写不匹配以及不区分大小写不匹配。
文件及目录匹配:
-f 和 !-f: 用来判断是否存在文件;
-d 和 !-d: 用来判断是否存在目录;
-e 和 !-e: 用来判断是否存在文件或目录;
-x 和 !-x: 用来判断文件是否可执行。
经常和if命令一起使用的内置变量有:
$args: 用来获取请求中的参数;
$arg_name: 用来获取请求中key为name的字段值,这个很实用name可以是其他字段。
$document_root: 用来获取当前请求的root命令指定的值;
$uri或$document_uri: 用来获取当前请求中的URI;
$host: 用来获取请求头中的“Host”的值;
$limit_rate: 用来设置限制链接的速率;
$request_method: 用来获取请求方式,GET或者POST等;
$remote_addr: 用来获取客户端IP地址;
$remote_port: 用来获取客户端端口;
$remote_user: 用来获取认证用户名,由ngx_http_auth_basic_module认证;
$request_filename: 用来获取当前请求的文件路径;
$request_uri: 用来获取含有参数的完整的厨师URI;
$request:用来获取客户端的请求地址;
$request_body:用来获取post方式请求的数据,而且只有location中用到proxy_pass,fastcgi_pass,scgi_pass命令时,该变量才有值;
$query_string: 用来获取请求参数合$args相同;
$server_name: 用来获取请求处理的服务器名;
$server_port: 用来获取请求处理的服务器端口;
实例-根据不同的请求参数,指向到相应的服务器处理1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62server{
listen 80;
server_name www.xieahui.com;
access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
#未携带标识mark的请求不处理
if ($args !~* mark ){
add_header Content-Type 'text/html; charset=utf-8';
return 200 '缺少参数mark';
}
# 请求参数mark以100开头的交给8080端口的服务器处理
if( $arg_mark ~* ^100 ){
proxy_pass http://localhost:8080;
}
# 请求参数mark不是以100开头的交给8081端口的服务器处理
if( $arg_mark !~* ^100 ){
proxy_pass http://localhost:8081;
}
}
}
server{
# 监听的端口
listen 80;
# 监听的域名,支持正则表达式
server_name www.xieahui.com;
access_log logs/host.access.log main;
# 所有请求,location命中规则有优先级区分,相似度越高优先级越高
location / {
root /web/www/page;
index index.html index.htm;
}
# 静态资源信息
location ~ *\. (gif|jpg|jpeg|png|bmp|swf|htm|html|css|js)$ {
root /usr/local/nginx/www/img;
if(!-f $request_filename){
root /web/www/page/img;
}
if(!-f $request_filename){
root /apps/images;
}
}
# 动态jsp页面if中判断页面文件是否存在与正定的文件夹中, proxy_pass处理请求的服务器地址
location ~ *\. (jsp)$ {
rot /webapp/www/ROOT;
if(!-f $request_filename){
root /user/local/nginx/www/jsp;
}
proxy_pass http://localhost:8080;
}
}rewrite命令
Nginx通过ngx_http_rewrite_module模块支持URL重写和if条件判断,但是rewrite功能需要pcre支持,在编译Nginx时指定pcre源码目录。rewrite的语法为: rewrite regex flag。可以在server、location和if中使用。
rewrite命令默认值为空,最后一个项参数为flag标记,支持的flag标记主要有以下几种:- last: 表示完成rewrite之后搜索相应的URI或location;
- break: 表示终止匹配,不在匹配后续规则;
- redirect: 将返回302临时重定向;
- permanent: 将返回301永久重定向;
其中last和break用来实现URL重写,浏览器地址栏中URL地址不变,配置示例:1
2
3
4location ~ ^/best/ {
rewrite ^/best/(.*)$ /test/$1 break;
proxy_pass http://www.xieahui.com;
}
这个例子实现了将请求www.xieyucan.com/best/info.html的页面转发到www.xieahui.com/test/info.html这个功能在新旧网站交替的时候可以用。
set命令
set命令可以设置变量的值,值可以是文本、变量或者他们的组合。也可以设置一个新的变量,但是不能使用set设置$http_xxx头部变量的值。可以使用在server、location和if中。
在配合使用ssi时可以设置替换变量的值,例如nginx中配置1
2
3
4
5
6location / {
ssi on;
set $DOMAIN http://img.zcool.cn;
root html;
index index.html index.htm;
}页面中设置为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<img src="<!--#echo var="DOMAIN"-->/community/01dbca5840d8bea801219c773977d7.jpg" width="300"/>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>Nginx在解析页面时会把DOMAIN替换为nignx中set $DOMAIN 设置的域名,这个功能在测试环境和线上环境域名切换时很方便.
示例
1
2
3
4
5location / {
proxy_pass http://location:8080/;
set $query $quer_string;
rewrite /dede /wordpress?$query?;
}这个例子实现了将请求www.xieahui.com/wp/?p=160的页面转发到www.xieahui.com/wordpress/?p=160 ,也就是带参数的重定向。
Nginx常用功能
多域名跳转
这个比较简单,说白了就是不同的请求地址跳转到不同的服务路径。举例说明看下就知道了
1
2
3
4
5
6
7
8
9
10
11
12
13server www.xieahui.com
location / {
proxy_pass http://localhost:8080/web/;
}
location /admin {
proxy_pass http://localhost:8080/admin;
}
server m.xieahui.com
location / {
proxy_pass http://localhost:8080/wap/;
}
这里需要注意的是,通过proxy_pass配置代理目录web和wap后面必须添加上一个颉颃,否则Nginx报错。
重定向新旧域名过度
假设有这么个需求,用户访问www.xieahui.com/page/index.html时跳转到新域名yoo.xieahui.com/page/index.html.有两种方式可以实现这个需求
第一种:
1
2server_name www.xieahui.com;
rewrite ^/(.*)$ http://yoo.xieahui.com/$1 permanent;
这里使用了Nginx的重定向功能,通过rewrite模块的permanent参数实现永久重定向301。
第二种
1
2
3
4server_name www.xieahui.com yoo.xieahui.com;
if($host != 'yoo.xieahui.com'){
rewrite ^/(.*)$ http://yoo.xieahui.com/$1 permanent;
}
这里利用了Nginx的核心变量host实现重定向功能。
alias别名功能
alias可以是吸纳别名功能和root有点类似,但是区别还是很明显。例如:
1
2
3
4
5
6
7location /i {
alias /web/www/page/images/;
}
location ~ ^/download/(.*)$ {
alias /web/www/file/$1;
}上面两个例子中使用的都是alias:
如果请求是 www.xieahui.com/i/logo.png, 那么Nginx会到目录/web/www/page/images/下找logo.png文件;如果是root配置Nginx会到/web/www/page/image/i/下找logo.png文件。第二个和第一个类似,只不过使用了$1代替了download后的路径信息。Nginx中目录权限控制,IP访问控制,文件访问权限控制
- 要实现IP访问控制,需要使用ngx_http_access_module模块,例子如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15location / {
deny 192.168.11.1;
allow 192.168.11.11/12;
allow 192.168.11.11/16;
deny all;
}
location ~ ^/(WEB-INF)/ {
deny al;
}
location ~* \.(txt|doc)${
root /data/www/file;
deny all;
}
- 要实现IP访问控制,需要使用ngx_http_access_module模块,例子如下:
location匹配规则
location是最常见的配置。
1. 下面举例介绍下Nginx的优先级问题:
1
2
3
4
5
6
7
location = / {}
location / {}
location ^~ /images/ {}
location ~* \.(gif|jpg|jpeg)$ {}
这四个例子中,第一个表示只匹配对”/“目录的查询,优先级最高,其他三个优先级一次降低。
第二个匹配以”/“开始的所有查询
第三个匹配以”/images/“开始的查询,不再检测正则
第四个匹配以括号中结尾的文件,优先级低于第三个
Nginx负载均衡
Nginx的负载均衡算法
Nginx的负载均衡模块目前支持5中调度算法,其中轮询(默认的)、weight权重和ip_hash属于系统自带的,fair和url_hash属于第三方的。他们分别的特点是:
* 轮询(默认):每个请求按时间顺序逐一分配到不同的服务器,如果后端服务宕机自动提出;
* weight:指定轮询权重,weight值越大分配到的访问频率越高,主要针对后台服务配置不均的情况下;
* ip_hash:每个请求按访问IP的哈希结果分配有效解决session共享问题,不过一般我们使用其他方式解决session共享问题,类似缓存数据库等;
* fair:这种算法可以根据页面大小和加载时间长度智能的进行负载均衡。Nginx本身不支持fair如果需要必须下载Nginx的upstream_fair模块。
* url_hash:按访问的URL的哈希结果来分配请求。Nginx本身不支持,如果需要必须下载安装Nginx的hash软件包。
在HTTP Upstream模块中,可以通过server命令指定后端服务器的IP和端口,同时还可以设定每台服务器在负载均衡调度中的状态。常用的状态有:
* down: 表示当前的server展示不参与负载均衡;
* backup: 预留的备份机器,当其他的所有非backup服务宕机后才会启用该服务;
* max_fails: 允许请求失败的次数,默认为1.超过最大次数时返回proxy_nex_upstream模块定义的错误;
* fail_timeout: 在经过max_fails次失败后,暂停服务的时间.
Nginx的负载均衡配置
负载均衡实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20http{
upstream serverList{
server 192.168.11.1:80 weight=3 max_fails=3 fail_timeout=20s;
server 192.168.11.2:80 weight=2 max_fails=3 fail_timeout=20s;
server 192.168.11.3:80 weight=1 max_fails=3 fail_timeout=20s;
}
server{
listen 80;
server_name www.xieahui.com 192.168.11.123;
index index.htm idex.html;
root /web/www/page;
location / {
proxy_pass http://serverList;
proxy_nex_upstream http_500 http_502 http_503 error timeout invalid_header;
include /nginx/conf/conf.d/*.conf;
}
}
}
proxy_next_upstream参数用来定义故障转移策略,当后端服务节点返回500,502,503,504和执行超时等错误时,自动将请求发到upstream负载均衡组中的另一个服务器。
以上.
1 | tcp{ |