大纲
一、环境准备
二、编译安装Nginx
三、Nginx反向代理
四、Nginx负载均衡
五、Nginx缓存功能
六、Nginx之URL重写
七、Nginx读写分离
一、环境准备
系统环境
CentOS5.8 x86_64
172.16.1.101 nginx
172.16.1.102 web1
172.16.1.103 web2
软件包
nginx-1.8.0.tar.gz
1、时间同步
1
2
3
4
5
6
7
8
|
[root@nginx ~]
# ntpdate s2c.time.edu.cn
20 Jan 10:20:44 ntpdate[31442]: adjust
time
server 202.112.10.36 offset -0.014753 sec
[root@web1 ~]
# ntpdate s2c.time.edu.cn
20 Jan 10:12:53 ntpdate[31373]: adjust
time
server 202.112.10.36 offset -0.007873 sec
[root@web2 ~]
# ntpdate s2c.time.edu.cn
20 Jan 10:12:46 ntpdate[4132]: step
time
server 202.112.10.36 offset 1432097.703563 sec
|
2、关闭iptables和selinux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
nginx
[root@nginx ~]
# service iptables stop
[root@nginx ~]
# chkconfig iptables off
[root@nginx ~]
# sed -r -i "s/^(SELINUX=).*/\1permissive/g" /etc/sysconfig/selinux
[root@nginx ~]
# setenforce 0
[root@nginx ~]
# getenforce
Permissive
web1
[root@web1 ~]
# service iptables stop
[root@web1 ~]
# chkconfig iptables off
[root@web1 ~]
# sed -r -i "s/^(SELINUX=).*/\1permissive/g" /etc/sysconfig/selinux
[root@web1 ~]
# setenforce 0
[root@web1 ~]
# getenforce
Permissive
web2
[root@web2 ~]
# service iptables stop
[root@web2 ~]
# chkconfig iptables off
[root@web2 ~]
# sed -r -i "s/^(SELINUX=).*/\1permissive/g" /etc/sysconfig/selinux
[root@web2 ~]
# setenforce 0
[root@web2 ~]
# getenforce
Permissive
|
3、下载所需的软件包
1
2
|
nginx
[root@nginx ~]
# wget http://nginx.org/download/nginx-1.8.0.tar.gz
|
二、编译安装Nginx
1、解决依赖关系
1
2
|
[root@nginx ~]
# yum groupinstall -y "Development Tools" "Development Libraries"
[root@nginx ~]
# yum install openssl-devel pcre-devel
|
2、创建nginx用户和组
1
2
|
[root@nginx ~]
# groupadd -r nginx
[root@nginx ~]
# useradd -r -g nginx nginx
|
3、编译安装
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
|
[root@nginx ~]
# tar xf nginx-1.8.0.tar.gz
[root@nginx ~]
# cd nginx-1.8.0
[root@nginx nginx-1.8.0]
# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile
man
objs README src
[root@nginx nginx-1.8.0]
# ./configure \
--prefix=
/usr
\
--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
\
--http-scgi-temp-path=
/var/tmp/nginx/scgi
\
--with-pcre
显示我们自定义的配置信息和编译选项
Configuration summary
+ using system PCRE library
+ using system OpenSSL library
+ md5: using OpenSSL library
+ sha1: using OpenSSL library
+ using system zlib library
nginx path prefix:
"/usr"
nginx binary
file
:
"/usr/sbin/nginx"
nginx configuration prefix:
"/etc/nginx"
nginx configuration
file
:
"/etc/nginx/nginx.conf"
nginx pid
file
:
"/var/run/nginx/nginx.pid"
nginx error log
file
:
"/var/log/nginx/error.log"
nginx http access log
file
:
"/var/log/nginx/access.log"
nginx http client request body temporary files:
"/var/tmp/nginx/client/"
nginx http proxy temporary files:
"/var/tmp/nginx/proxy/"
nginx http fastcgi temporary files:
"/var/tmp/nginx/fcgi/"
nginx http uwsgi temporary files:
"/var/tmp/nginx/uwsgi"
nginx http scgi temporary files:
"/var/tmp/nginx/scgi"
编译安装
[root@nginx nginx-1.8.0]
# make && make install
补充:
Nginx可以使用Tmalloc(快速、多线程的malloc库及优秀性能分析工具)来加速内存分配
使用此功能需要事先安装gperftools,而后在编译nginx添加--with-google_perftools_module选项即可
|
4、为nginx提供SysV init脚本
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
[root@nginx nginx-1.8.0]
# vim /etc/rc.d/init.d/nginx
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /etc/sysconfig/nginx
# pidfile: /var/run/nginx.pid
# Source function library.
.
/etc/rc
.d
/init
.d
/functions
# Source networking configuration.
.
/etc/sysconfig/network
# Check that networking is up.
[
"$NETWORKING"
=
"no"
] &&
exit
0
nginx=
"/usr/sbin/nginx"
prog=$(
basename
$nginx)
NGINX_CONF_FILE=
"/etc/nginx/nginx.conf"
[ -f
/etc/sysconfig/nginx
] && .
/etc/sysconfig/nginx
lockfile=
/var/lock/subsys/nginx
make_dirs() {
# make required directories
user=`nginx -V 2>&1 |
grep
"configure arguments:"
|
sed
's/[^*]*--user=\([^ ]*\).*/\1/g'
-`
options=`$nginx -V 2>&1 |
grep
'configure arguments:'
`
for
opt
in
$options;
do
if
[ `
echo
$opt |
grep
'.*-temp-path'
` ];
then
value=`
echo
$opt |
cut
-d
"="
-f 2`
if
[ ! -d
"$value"
];
then
# echo "creating" $value
mkdir
-p $value &&
chown
-R $user $value
fi
fi
done
}
start() {
[ -x $nginx ] ||
exit
5
[ -f $NGINX_CONF_FILE ] ||
exit
6
make_dirs
echo
-n $
"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -
eq
0 ] &&
touch
$lockfile
return
$retval
}
stop() {
echo
-n $
"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -
eq
0 ] &&
rm
-f $lockfile
return
$retval
}
restart() {
configtest ||
return
$?
stop
sleep
1
start
}
reload() {
configtest ||
return
$?
echo
-n $
"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >
/dev/null
2>&1
}
case
"$1"
in
start)
rh_status_q &&
exit
0
$1
;;
stop)
rh_status_q ||
exit
0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q ||
exit
7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q ||
exit
0
;;
*)
echo
$
"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit
2
esac
添加执行权限,并加入到服务列表中
[root@nginx nginx-1.8.0]
# chmod +x /etc/rc.d/init.d/nginx
[root@nginx nginx-1.8.0]
# chkconfig --add nginx
[root@nginx nginx-1.8.0]
# chkconfig nginx on
[root@nginx nginx-1.8.0]
# chkconfig --list nginx
nginx 0:off 1:off 2:on 3:on 4:on 5:on 6:off
|
5、启动Nginx服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
[root@nginx nginx-1.8.0]
# service nginx start
Starting nginx: [ OK ]
查看80端口是否处于监听状态
[root@nginx nginx-1.8.0]
# netstat -tnlp
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:111 0.0.0.0:* LISTEN 2820
/portmap
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 30414
/nginx
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 25126
/sshd
tcp 0 0 0.0.0.0:922 0.0.0.0:* LISTEN 2860
/rpc
.statd
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 24814
/sshd
tcp 0 0 :::22 :::* LISTEN 25126
/sshd
tcp 0 0 ::1:6011 :::* LISTEN 24814
/sshd
|
6、测试访问
三、Nginx反向代理
1、首先准备一个web服务器,这里以web1演示
1
2
|
首先安装web服务,这里使用yum安装httpd,以httpd作为web服务器
[root@web1 ~]
# yum install -y httpd
|
2、配置并启动httpd服务,测试能正常访问
1
2
3
4
5
6
7
8
9
10
11
|
创建目录,配置页面文件
[root@web1 ~]
# mkdir /var/www/html/bbs
[root@web1 ~]
# echo "<h1>Forum On Apache Server</h1>" > var/www/html/bbs/index.html
启动httpd服务
[root@web1 ~]
# service httpd start
Starting httpd: [ OK ]
测试自己能否访问,当前web1的ip地址就是172.16.1.102
[root@web1 ~]
# curl http://172.16.1.102/bbs/
<h1>Forum On Apache Server<
/h1
>
|
3、配置Nginx作为反向代理
1
2
3
4
5
6
7
8
9
|
这是切换到nginx主机,配置其作为反向代理服务器
[root@nginx ~]
# hostname
nginx
编辑配置文件,加入下面三行至server段中
[root@nginx ~]
# vim /etc/nginx/nginx.conf
location
/forum
{
proxy_pass http:
//172
.16.1.102
/bbs
;
}
|
4、用浏览器测试访问
1
2
3
4
5
6
7
8
9
10
11
12
13
|
再来看web1上的访问日志
[root@web1 ~]
# tail /var/log/httpd/access_log
172.16.1.101 - - [20
/Jan/2016
:13:57:21 +0800]
"GET /bbs/ HTTP/1.0"
200 32
"-"
"Mozilla
/5
.0
(Windows NT 6.1; WOW64) AppleWebKit
/537
.36 (KHTML, like Gecko) Chrome
/47
.0.2526.106 Safari
/537
.36"
可以看到源ip是nginx反向代理并不是我们真正的客户端,但是有时候我们需要记录真正的client便于做日志分析
此时我们只需要添加proxy模块的proxy_set_header指令即可实现,此指令的语法格式如下
Syntax: proxy_set_header field value;
Default:
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location
|
5、配置Nginx反向代理和web服务器,使web服务器能够记录真实客户端ip地址
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
|
编辑配置文件,修改反向代理location那一段如下
[root@nginx ~]
# vim /etc/nginx/nginx.conf
location
/forum
{
proxy_pass http:
//172
.16.1.102
/forum/
;
proxy_set_header X-Real-IP $remote_addr;
# 其实就是添加此行
}
而后重新载入Nginx代理服务器
[root@nginx nginx]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
Reloading nginx: [ OK ]
再来用浏览器访问一下,可以看到仍然没有记录真实客户端的ip地址
[root@web1 ~]
# tail /var/log/httpd/access_log
172.16.1.101 - - [20
/Jan/2016
:13:57:21 +0800]
"GET /bbs/ HTTP/1.0"
200 32
"-"
"Mozilla
/5
.0
(Windows NT 6.1; WOW64) AppleWebKit
/537
.36 (KHTML, like Gecko) Chrome
/47
.0.2526.106 Safari
/537
.36"
172.16.1.101 - - [20
/Jan/2016
:13:58:03 +0800]
"GET /bbs/ HTTP/1.0"
200 32
"-"
"Mozilla
/5
.0
(Windows NT 6.1; WOW64) AppleWebKit
/537
.36 (KHTML, like Gecko) Chrome
/47
.0.2526.106 Safari
/537
.36"
因为我们web服务器访问日志记录格式中第一项记录的请求客户端的地址,也就是我们的Nginx反向代理服务器地址
修改web服务器端的访问日志格式,修改之前先备份原有的combined模式并注释,将第一个%h修改为%{X-Real-IP}i即可
[root@web1 ~]
# vim /etc/httpd/conf/httpd.conf
#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat
"%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
combined
然后重启httpd服务或是重新载入都可以
[root@web1 ~]
# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
再用浏览器访问一下然后看httpd服务器的访问日志
[root@web1 ~]
# tail /var/log/httpd/access_log
172.16.1.101 - - [20
/Jan/2016
:13:57:21 +0800]
"GET /bbs/ HTTP/1.0"
200 32
"-"
"Mozilla
/5
.0
(Windows NT 6.1; WOW64) AppleWebKit
/537
.36 (KHTML, like Gecko) Chrome
/47
.0.2526.106 Safari
/537
.36"
172.16.1.101 - - [20
/Jan/2016
:13:58:03 +0800]
"GET /bbs/ HTTP/1.0"
200 32
"-"
"Mozilla
/5
.0
(Windows NT 6.1; WOW64) AppleWebKit
/537
.36 (KHTML, like Gecko) Chrome
/47
.0.2526.106 Safari
/537
.36"
172.16.1.100 - - [20
/Jan/2016
:14:09:28 +0800]
"GET /bbs/ HTTP/1.0"
200 32
"-"
"Mozilla
/5
.0
(Windows NT 6.1; WOW64) AppleWebKit
/537
.36 (KHTML, like Gecko) Chrome
/47
.0.2526.106 Safari
/537
.36"
可以看到客户端真实ip已经记录,这个172.16.1.100就是我自己物理主机的地址
|
四、Nginx负载均衡
1、准备两台web服务器,配置好页面并进行本地测试。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
web1在上面反向代理的示例中已经安装了httpd,这里不需要再安装,只是配置好主页并测试即可
[root@web1 ~]
# echo "<h1>web1</h1>" > /var/www/html/index.html
[root@web1 ~]
# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
[root@web1 ~]
# curl localhost
<h1>web1<
/h1
>
web2
[root@web2 ~]
# yum install -y httpd
[root@web2 ~]
# echo "<h1>web2</h1>" > /var/www/html/index.html
[root@web2 ~]
# service httpd start
Starting httpd: [ OK ]
[root@web2 ~]
# curl localhost
<h1>web2<
/h1
>
|
2、配置Nginx提供负载均衡功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
首先定义一个upstream组,注意,此upstream需定义在server段之外
[root@nginx nginx]
# pwd
/etc/nginx
[root@nginx nginx]
# vim nginx.conf
upstream webservers {
server 172.16.1.102 weight=1;
server 172.16.1.103 weight=1;
}
然后再修改location段为如下所示
location / {
proxy_pass http:
//webservers
;
proxy_set_header X-Real-IP $remote_addr;
}
重新载入nginx
[root@nginx nginx]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
Reloading nginx: [ OK ]
|
用浏览器访问一下
再刷新一下
可以看到,已经实现了简单的负载均衡效果
3、为Nginx增加上游服务器的健康状态监测功能
1
2
3
4
5
6
7
8
9
10
11
12
|
修改配置文件中upstream段为如下所示
[root@nginx nginx]
# vim nginx.conf
upstream webservers {
server 172.16.1.102 weight=1 max_fails=2 fail_timeout=2s;
server 172.16.1.103 weight=1 max_fails=2 fail_timeout=2s;
}
然后重新载入nginx
[root@nginx nginx]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
Reloading nginx: [ OK ]
|
用浏览器访问一下
再刷新一下
此时停止web1上的httpd服务,一直刷新,显示的一直都是web2
1
2
|
[root@web1 ~]
# service httpd stop
Stopping httpd: [ OK ]
|
再让web1上的httpd服务启动起来,可以看到,web1重新被加入进来了
1
2
|
[root@web1 ~]
# service httpd start
Starting httpd: [ OK ]
|
再刷新一下
4、为Nginx增加sorry_server
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
|
修改配置文件中upstream段为如下所示
[root@nginx nginx]
# vim nginx.conf
upstream webservers {
server 172.16.1.102 weight=1 max_fails=2 fail_timeout=2s;
server 172.16.1.103 weight=1 max_fails=2 fail_timeout=2s;
server 127.0.0.1:8080 backup;
}
再在配置文件中定义一个server
server {
listen 8080;
server_name localhost;
root
/var/www/mantainance
;
index index.html;
}
接着创建维护页面目录及文件
[root@nginx nginx]
# mkdir /var/www/mantainance
[root@nginx nginx]
# echo "<h1>Mantainance Time</h1>" > /var/www/mantainance/index.html
然后重新载入nginx
[root@nginx nginx]
# nginx -t
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
[root@nginx nginx]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
Reloading nginx: [ OK ]
此时停掉web1和web2上的httpd服务
[root@web1 ~]
# service httpd stop
Stopping httpd: [ OK ]
[root@node2 ~]
# service httpd stop
Stopping httpd: [ OK ]
再使用浏览器访问一下
|
1
2
3
4
5
|
此时再上线web1
[root@web1 ~]
# service httpd start
Starting httpd: [ OK ]
浏览器刷新
|
1
2
3
4
5
|
再上线web2
[root@web2 ~]
# service httpd start
Starting httpd: [ OK ]
浏览器刷新
|
可以看到,当所有的web服务器都宕机时,Nginx自身会加入sorry_server
1
2
3
4
5
6
7
|
补充知识1
nginx支持三种调度算法:ip_hash(相当于LVS的sh),round_robin(相当于LVS的rr和wrr),least_conn(相当于LVS的lc)
要想使用ip_hash算法,直接在upstream段中定义ip_hash即可,但是用ip_hash时,不能定义sorry_server
补充知识2
统计80端口服务的每种连接状态数目
[root@nginx nginx]
# netstat -tan | awk '/:80\>/{S[$NF]++}END{for(A in S) {print A,S[A]}}'
|
五、Nginx缓存功能
1、缓存功能模块相关指令介绍
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
|
Nginx的缓存功能也是跟反向代理功能使用的是同一个模块:ngx_http_proxy_module
Nginx的缓存由两个部分组成
共享内存:存储键和缓存对象元数据
磁盘空间:缓存数据
缓存功能所用到的几个常用指令语法如下
1、proxy_cache
Syntax: proxy_cache zone | off;
Default:
proxy_cache off;
Context: http, server, location
zone指的是启用某个共享内存区域的缓存功能
2、proxy_cache_path
Syntax: proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size
[inactive=
time
] [max_size=size] [loader_files=number] [loader_sleep=
time
] [loader_threshold=
time
]
[purger=on|off] [purger_files=number] [purger_sleep=
time
] [purger_threshold=
time
];
Default: —
Context: http
path指的是缓存数据的存储路径
levels指的是nginx的缓存目录层次级别,最多有3级,并且每级最多用2个字符定义
keys_zone指的是缓存的共享内存名称,也是proxy_cache后面所引用的名称,size指明这段共享内存区域大小
max_size指的是缓存数据的磁盘空间大小
3、proxy_cache_valid
Syntax: proxy_cache_valid [code ...]
time
;
Default: —
Context: http, server, location
code指的是http响应报文的状态码
time
指的是对于某种code所缓存的时长
|
2、为Nginx增加缓存功能
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
|
首先编辑配置文件,定义proxy_cache_path,此指令跟upstream指令一样需定义在server段之外
[root@nginx nginx]
# vim nginx.conf
proxy_cache_path
/nginx/cache/first
levels=1:2 keys_zone=first:20m max_size=1g;
上面只是定义缓存功能,但是还没有启用,所以我们需要在某个location中定义明确启用哪个缓存
[root@nginx nginx]
# vim nginx.conf
location / {
proxy_pass http:
//webservers
;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache first;
# proxy_cache后面跟的是keys_zone中所定义的名称
proxy_cache_valid 200 10m;
# 表示响应报文状态码为200的缓存10分钟
}
检查是否有语法错误
[root@nginx nginx]
# nginx -t
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: [emerg]
mkdir
()
"/nginx/cache/first"
failed (2: No such
file
or directory)
nginx: configuration
file
/etc/nginx/nginx
.conf
test
failed
创建缓存目录
[root@nginx nginx]
# mkdir -pv /nginx/cache/first
mkdir
: created directory `
/nginx
'
mkdir
: created directory `
/nginx/cache
'
mkdir
: created directory `
/nginx/cache/first
'
检查是否有语法错误
[root@nginx nginx]
# nginx -t
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
重新载入nginx
[root@nginx nginx]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
Reloading nginx: [ OK ]
|
3、测试Nginx的缓存功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
为了方便测试是否命中缓存,在配置文件中的server段中定义一个指令
[root@nginx nginx]
# vim nginx.conf
add_header X-Cache
"$upstream_cache_status from $server_addr"
;
检查是否有语法错误
[root@nginx nginx]
# nginx -t
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
重新载入nginx
[root@nginx nginx]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
Reloading nginx: [ OK ]
首先查看我们的缓存目录,可以看到此时是空的,里面并没有缓存任何内容
[root@nginx nginx]
# ls /nginx/cache/first/f/63/
接着用浏览器访问看看,此时是第一次访问,所以是X-Cache为MISS
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
此时再次查看缓存目录,可以看到缓存已经有了
[root@nginx nginx]
# cat /nginx/cache/first/f/63/681ad4c77694b65d61c9985553a2763f
aVn.VRVh3
"c04fd-e-529be6a44b2a8"
KEY: http:
//webservers/
HTTP
/1
.1 200 OK
Date: Wed, 20 Jan 2016 13:53:22 GMT
Server: Apache
/2
.2.15 (CentOS)
Last-Modified: Wed, 20 Jan 2016 06:51:26 GMT
ETag:
"c04fd-e-529be6a44b2a8"
Accept-Ranges: bytes
Content-Length: 14
Connection: close
Content-Type: text
/html
; charset=UTF-8
<h1>web1<
/h1
>
再刷新一下浏览器,可以看到我们始终是被定向至web2
因为我们在配置文件中定义了对于状态码为200的缓存10m,并且此时X-Cache显示为命中
|
1
2
3
4
5
|
补充知识:
Nginx常用的三种缓存
open_log_cache:日志缓存,可以降低磁盘io
open_file_cache:文件缓存,加速nginx响应过程
fastcgi_cache:后端应用程序服务器生成的结果缓存,这个要慎用
|
六、Nginx之URL重写
1、编辑配置文件,定义rewrite规则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
这里为了不受上面负载均衡的示例,恢复配置文件到最初安装nginx时候的状态
[root@nginx ~]
# cd /etc/nginx/
[root@nginx nginx]
# mv nginx.conf{,.back}
[root@nginx nginx]
# cp nginx.conf.default nginx.conf
编辑配置文件,在location段中增加如下rewrite一行
[root@nginx nginx]
# vim nginx.conf
location / {
root html;
index index.html index.htm;
rewrite ^
/bbs/
(.*)$ http:
//172
.16.1.102
/forum/
$1;
}
测试是否有语法错误
[root@nginx nginx]
# nginx -t
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
重新载入nginx
[root@nginx nginx]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
Reloading nginx: [ OK ]
|
2、在web服务器上配置好相应的目录及页面文件
1
2
3
4
5
6
7
8
9
|
[root@web1 ~]
# cd /var/www/html/
[root@web1 html]
# ls
index.html
[root@web1 html]
# mkdir forum
[root@web1 html]
# echo "<h1>Forum On Apache Server</h1>" > forum/index.html
本地测试访问一下
[root@web1 html]
# curl http://172.16.1.102/forum/
<h1>Forum On Apache Server<
/h1
>
|
3、浏览器访问测试
在浏览器地址栏中输入http://172.16.1.101/bbs,页面直接被重定向至172.16.1.102/forum
4、配置永久重定向
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
Nginx编辑配置文件,将rewrite一行修改为如下所示
[root@nginx nginx]
# vim nginx.conf
rewrite ^
/bbs
(.*)$
/forum/
$1;
本地配置好forum目录及页面文件
[root@nginx ~]
# cd /usr/html/
[root@nginx html]
# ls
50x.html index.html
[root@nginx html]
# mkdir forum
[root@nginx html]
# echo "<h1>Forum On Nginx Server</h1>" > forum/index.html
测试是否有语法错误
[root@nginx nginx]
# nginx -t
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
重新载入nginx
[root@nginx nginx]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
Reloading nginx: [ OK ]
|
5、浏览器访问测试
在浏览器地址栏中输入http://172.16.1.101/bbs,可以看到Status code为200,这种也叫隐形重定向。一般跨服务器的是临时重定向,服务器内部的则是永久重定向。
七、Nginx读写分离
1、需求分析及拓扑图
需求分析
构建一个论坛,前端是个Nginx,实现读写分离,将用户的写请求(上传附件之类的操作)定向至web1,读请求定向至web2。web1和web2之间使用rsync+inotify或者sersync同步用户上传的文件,从而实现用户不管被定向至哪个web服务器,都能访问到自己之前上传的文件
拓扑图
2、WebDAV概念介绍
WebDAV (Web-based Distributed Authoring and Versioning) 一种基于 HTTP 1.1协议的通信协议。它扩展了HTTP 1.1,在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法,使应用程序可直接对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。
3、修改web1的配置文件,使其支持put方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
修改配置文件,启用如下两个模块
[root@web1 ~]
# vim /etc/httpd/conf/httpd.conf
LoadModule dav_module modules
/mod_dav
.so
LoadModule dav_fs_module modules
/mod_dav_fs
.so
再在网页的根目录即Directory段中定义一个Dav指令
<Directory
"/var/www/html"
>
Dav on
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
<
/Directory
>
测试语法是否有错误
[root@web1 ~]
# httpd -t
Syntax OK
重新启动httpd服务
[root@web1 ~]
# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
|
4、测试两个web是否支持读和写请求
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
|
测试两个web的读请求是否正常
[root@web1 ~]
# curl http://172.16.1.102
<h1>web1<
/h1
>
[root@web1 ~]
# curl http://172.16.1.103
<h1>web2<
/h1
>
测试web1是否能够支持写请求,也就是上传操作
[root@web1 ~]
# curl -T /etc/fstab http://172.16.1.102
<!DOCTYPE HTML PUBLIC
"-//IETF//DTD HTML 2.0//EN"
>
<html><
head
>
<title>403 Forbidden<
/title
>
<
/head
><body>
<h1>Forbidden<
/h1
>
<p>You don't have permission to access
/fstab
on this server.<
/p
>
<hr>
<address>Apache
/2
.2.15 (CentOS) Server at 172.16.1.102 Port 80<
/address
>
<
/body
><
/html
>
提示403 Forbidden,没有权限
因为
/var/www/html
的属主属组是root,而运行httpd服务的是apache用户,加上写权限即可
[root@web1 ~]
# setfacl -m u:apache:rwx /var/www/html/
可以看到状态码为201,并且文件已经上传到了172.16.1.102上,也就是我们定义的那个能写的web服务器
[root@web1 ~]
# curl -T /etc/issue http://172.16.1.102
<!DOCTYPE HTML PUBLIC
"-//IETF//DTD HTML 2.0//EN"
>
<html><
head
>
<title>201 Created<
/title
>
<
/head
><body>
<h1>Created<
/h1
>
<p>Resource
/issue
has been created.<
/p
>
<hr />
<address>Apache
/2
.2.15 (CentOS) Server at 172.16.1.102 Port 80<
/address
>
<
/body
><
/html
>
测试是否成功上传
[root@web1 ~]
# curl http://172.16.1.102/issue
CentOS release 6.5 (Final)
Kernel \r on an \m
再来测试web2是否能够支持写请求,我们的目的是web1能上传,web2不能上传,只能读
[root@web1 ~]
# curl -T /etc/fstab http://172.16.1.103
<!DOCTYPE HTML PUBLIC
"-//IETF//DTD HTML 2.0//EN"
>
<html><
head
>
<title>405 Method Not Allowed<
/title
>
<
/head
><body>
<h1>Method Not Allowed<
/h1
>
<p>The requested method PUT is not allowed
for
the URL
/fstab
.<
/p
>
<hr>
<address>Apache
/2
.2.15 (CentOS) Server at 172.16.1.103 Port 80<
/address
>
<
/body
><
/html
>
可以看到状态码为405而不是403,说不支持这种方法,因为我们在httpd的配置文件并没有定义它可以上传
|
5、修改前端Nginx配置,使其实现读写分离功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
编辑配置文件,在location段中定义
[root@nginx ~]
# vim /etc/nginx/nginx.conf
location / {
proxy_pass http:
//172
.16.1.103;
if
($request_method =
"PUT"
) {
proxy_pass http:
//172
.16.1.102;
}
}
测试是否有语法错误
[root@nginx ~]
# nginx -t
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
重新载入nginx
[root@nginx ~]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
Reloading nginx: [ OK ]
|
6、测试Nginx的读写分离功能
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
|
首先测试读请求,可以看到我们的读请求被定向至web2上
[root@nginx nginx]
# curl http://172.16.1.101
<h1>web2<
/h1
>
[root@nginx nginx]
# curl http://172.16.1.101
<h1>web2<
/h1
>
[root@nginx nginx]
# curl http://172.16.1.101
<h1>web2<
/h1
>
[root@nginx nginx]
# curl http://172.16.1.101
<h1>web2<
/h1
>
[root@nginx nginx]
# curl http://172.16.1.101
<h1>web2<
/h1
>
再来测试写请求
[root@nginx ~]
# curl -T /etc/fstab http://172.16.1.101
<!DOCTYPE HTML PUBLIC
"-//IETF//DTD HTML 2.0//EN"
>
<html><
head
>
<title>201 Created<
/title
>
<
/head
><body>
<h1>Created<
/h1
>
<p>Resource
/fstab
has been created.<
/p
>
<hr />
<address>Apache
/2
.2.15 (CentOS) Server at 172.16.1.102 Port 80<
/address
>
<
/body
><
/html
>
访问测试一下
[root@nginx ~]
# curl http://172.16.1.102/fstab
#
# /etc/fstab
# Created by anaconda on Fri Aug 28 10:30:25 2015
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/vg_centos6-lv_root
/ ext4 defaults 1 1
UUID=7a79d653-e9b7-43f2-a2c1-e41af29b3f5d
/boot
ext4 defaults 1 2
/dev/mapper/vg_centos6-lv_swap
swap swap defaults 0 0
tmpfs
/dev/shm
tmpfs defaults 0 0
devpts
/dev/pts
devpts gid=5,mode=620 0 0
sysfs
/sys
sysfs defaults 0 0
proc
/proc
proc defaults 0 0
/dev/myvg/mydata
/mydata
ext4 defaults 0 0
可以看到已经成功上传到了web1上,此时就实现了读写分离功能
我这里只使用了一个读服务器,其实可以定义一组服务器用作读,Nginx同时实现读写分离和负载均衡
|