利用 `nginx反向代理` 实现的动静分离

0x01 关于 动静分离

1
2
主要用于一些较大型的站点架构,这样做一定程度上可以有效减轻后端节点压力,也就是说,有时候你在前端url中看到的一个目录,其后端对应的很可能就是一个集群
另外,这样会使网站更加静态化,利于缓存,可显著提高网站访问速度,有效实现前后端解耦,但这样无疑会加大开发的繁琐程度,前后端只能通过各种接口进行通信

0x02 此次演示环境

1
2
3
NginxHttp ip: 192.168.3.49 对应域名: reverse.org nginx反向代理服务器
OldLamp ip: 192.168.3.45 对应域名: www.bwapp.cc 假设为动态服务器
OldLnmp ip: 192.168.3.42 对应域名: test.bwapp.org 假设为静态服务器

0x03 务必先统一所有机器的host解析,因为等会儿要直接用域名的方式往后抛,如下

1
2
3
4
5
# vi /etc/hosts
192.168.3.42 test.bwapp.org bwapp.org
192.168.3.45 bwapp.cc www.bwapp.cc
192.168.3.75 lvs.org
192.168.3.49 reverse.org

0x04 匹配url中指定的目录名实现的分离

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
# vi /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 先定义好代理池,即后端所有的web节点,因为实现已经在hosts中做好指向,所以此处可以直接用域名
upstream default_pools{
server test.bwapp.org:80 weight=2;
server www.bwapp.cc:80;
}
upstream static_pools {
server test.bwapp.org:80;
}
upstream dynamic_pools {
server www.bwapp.cc:80;
}
server {
listen 80;
server_name reverse.org;
location / {
# root html;
# index index.html index.htm;
# 此为缺省代理池,意思只要没命中下面的目录就走这里向后抛
# 注意,所有向后抛的动作均要带上主机头和客户端真实ip,否则会报400错误
proxy_pass http://default_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /static/ {
# 当命中到url中访问的是此静态目录时,就直接抛给后端的test.bwapp.org节点去处理
proxy_pass http://static_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /dynamic/ {
# 当命中到url中访问的是此动态目录时,就直接抛给后端的www.bwapp.cc节点去处理
proxy_pass http://dynamic_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
}
# /usr/local/nginx/sbin/nginx -t
# /usr/local/nginx/sbin/nginx -s reload

0x05 匹配url中指定的文件后缀实现的分离

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
# cd /usr/local/nginx/conf/
# mv nginx.conf nginx.conf.bak.dir
# vi nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 依然是先定义好代理池
upstream default_pools{
server test.bwapp.org:80 weight=3;
server www.bwapp.cc:80;
}
upstream static_pools {
server test.bwapp.org:80;
}
upstream dynamic_pools {
server www.bwapp.cc:80;
}
server {
listen 80;
server_name reverse.org;
location / {
# root html;
# index index.html index.htm;
# 缺省代理池,具体同上
proxy_pass http://default_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
# 当在url中命中到的是这些静态资源后缀时就抛给后面的静态服务器
location ~ .*.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
proxy_pass http://static_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
# 当在url中命中到的是这些动态脚本资源后缀时就抛给后面的动态服务器
location ~ .*.(php|jsp|do)$ {
proxy_pass http://dynamic_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
}
# /usr/local/nginx/sbin/nginx -t
# /usr/local/nginx/sbin/nginx -s reload

0x06 除了根据url中指定的目录或文件后缀,我们还可以根据客户端的user-agent类型来判断,实现让不同系统平台的请求抛到指定的后端节点上,如,pc,ipad,iphone,android...也可以通过判断浏览器类型类决定具体要抛给后端的哪个程序去处理,等等…,另外,在前面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
45
46
47
48
49
50
51
52
53
54
55
56
57
# vi /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream default_pools{
server test.bwapp.org:80 weight=3;
server www.bwapp.cc:80;
}
upstream static_pools {
server test.bwapp.org:80 weight=2;
}
upstream dynamic_pools {
server www.bwapp.cc:80;
}
server {
listen 80;
server_name lvs.org;
location / {
# root html;
# index index.html index.htm;
proxy_pass http://default_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
# 当侦测到客户端用的是IE浏览器就抛给后端的动态服务器
if ($http_user_agent ~* "MSIE"){
proxy_pass http://dynamic_pools;
}
# 当侦测到客户端用的是火狐浏览器就抛给后端的静态服务器
if ($http_user_agent ~* "Firefox"){
proxy_pass http://static_pools;
}
# 当侦测到客户端用的是android设备就抛给后端的移动服务器,这里只是简单举个例子
if ($http_user_agent ~* "android"){
proxy_pass http://mobile_pools;
}
# 专门用来侦测iphone设备
if ($http_user_agent ~* "iphone"){
proxy_pass http://static_pools;
}
}
}
}

0x07 利用nginx实现缓存功能,待续…



后话:
    乐趣无穷的nginx , 待续…^_^