动静分离
为了加快网站的解析速度,可以把动态页面和静态页面有不同的服务器来解析,加快机械速度。降低原来单个服务器的压力。在动静分离的tomcat时候比较明显,因为tomcat解析静态很慢,其实这些原理的话很好理解,简单来说,就是用正则表达式匹配过滤,然后交给不同服务器。
处理静态的服务器:nginx、Apache
处理动态的服务器:web容器/web中间件、php(php)、tomcat(java)、uwsgi(python)
下面我们进行一个简单的实验
实验环境:
192.168.242.138 (代理+负载均衡+动静分离)
192.168.242.134 静态服务器
192.168.242.140 动态服务器
实验目的:在电脑浏览器上访问代理服务器ip,将动态请求转发到动态服务器,将静态请求转发到静态服务器。
实验思路:先部署好静态服务器,在静态服务器的网站发布目录中放一张图片,配置相应的发布页面。在动态服务器上安装php、php-mysql、mysql、nginx等服务,上线开源的qqfarm。在能正常访问静态服务器和动态服务器的基础上,在代理服务器上部署动静分离。
注意:在做类似实验的时候一定要保证firewalld、selinux是关闭状态,如果因为这两个人万恶之源导致实验结果出错,会非常恶心。
实验过程:
部署静态服务器:
下载nginx,步骤省略
[root@localhost ~]# systemctl start nginx
[root@localhost ~]# vim /etc/nginx/conf.d/abc.conf
server {
listen 80;
server_name localhost;
location / {
root /abc;
index index.html;
}
}
[root@localhost ~]# mkdir /abc 创建网站发布目录 要与nginx的子配置文件对应好
[root@localhost ~]# vim /abc/index.html 编辑网站发布页面
<html> #这些内容都是引用别人的,我们不需要自己写
<head>
<meta charset="utf-8">
<title>qf.com</title>
</head>
<body>
<center><img src="../1.png" alt="xingdian" /></center> #1.png引用发布目录中的图片
</body>
</html>
在网站发布目录中上传一张图片
[root@localhost ~]# cd /abc/
[root@localhost abc]# ls
1.png index.html #图片名字要与index.html引用的名字相同,不然会报错
[root@localhost abc]# nginx -t
[root@localhost abc]# nginx -s reload
浏览器访问静态服务器ip验证。(成功)
部署动态服务器
下载nginx、php php-fpm php-mysql php-gd gd 过程省略
下载mysql5.37,下载之后grep password /var/log/mysqld.log查看初识密码,进入mysql数据库创建项目需要的数据库'farm',创建一个用户就以项目名为用户名'farm'。
然后配置动态服务器的nginx网站发布目录
[root@localhost ~]# vim /etc/nginx/conf.d/php.conf 配置子配置文件
server {
listen 80;
server_name localhost;
location / {
root /php;
index index.php ;
}
location ~ \.php$ { #使nginx支持php
root /php;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[root@localhost ~]# mkdir /php #创建网站发布目录
编辑php的配置文件
[root@localhost ~]# vim /etc/php.ini
.....
short_open_tag = On #将这个配置打开
....
将项目文件上传到网站发布目录下
[root@localhost ~]# cp -r upload/* /php
[root@localhost ~]# chmod 777 /php -R #将网站发布目录的权限递归修改为777
将qqfarm项目的数据导入mysql数据库的farm库中
[root@localhost ~]# mysql -uroot -p1 farm </php/qqfarm.sql
[root@localhost ~]# systemctl restart nginx php-fpm.service #重启nginx和php服务
在浏览器上访问动态服务器ip验证(成功)。(注意:第一次访问不是这个页面,会有检测服务器是否配置成功的页面,如果配置成功会进入引导页面,登录数据库对用的用户,如果配置有问题,页面上可以看到是哪里出了问题)
接下来部署我们的代理服务器
下载nginx。过程省略
[root@localhost ~]# systemctl start nginx
[root@localhost ~]# vim /etc/nginx/nginx.conf 编辑主配置文件
如下图:
然后添加编辑子配置文件做动静分离
[root@localhost ~]# vim /etc/nginx/conf.d/proxy.conf
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://php;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ \.(html|gif|jpg|png|bmp|swf|css|js)$ {
proxy_pass http://abc;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[root@localhost ~]# nginx -t
[root@localhost ~]# nginx -s reload
浏览器访问代理服务器的ip,ip后边记得加路径,访问静态服务器时加上/index.html,访问动态服务器时什么都不用加。因为我们在子配置文件中设置的访问动态服务器访问用的是通配符‘/’。
请求转发到了静态服务器
请求转发到了动态服务器
防盗链
两个网站 A 和 B, A网站引用了B网站上的图片,这种行为就叫做盗链。 防盗链,就是要防止A引用B的图片。
nginx 防止网站资源被盗用模块:ngx_http_referer_module
HTTP Referer是Header的一部分,当浏览器向Web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理,例如防止未经允许的网站盗链图片、文件等。因此HTTP Referer头信息是可以通过程序来伪装生成的,所以通过Referer信息防盗链并非100%可靠,但是,它能够限制大部分的盗链情况。
实验环境:
192.168.242.134 用来做防盗链的部署(A服务器)
192.168.242.137 盗链(测试防盗链是否成功)(B服务器)
实验之前确保firewalld和selinux关闭
实验思路:先在A服务器的网站发布目录上上传图片,在浏览器上访问ip能看看到图片,然后在B服务器上盗链图片,在浏览器上访问B服务器的ip能够看到A服务的图片。(能看到说明盗链成功)然后在A服务器上部署防盗链,接着在服务器上访问B服务器的ip,如果看不到图片说明防盗链部署成功,否则失败。
实验过程:
在A服务器上传图片
[root@localhost abc]# vim /etc/nginx/conf.d/abc.conf 编辑子配置文件
server {
listen 80;
server_name localhost;
location / {
root /abc;
index index.html;
}
}
[root@localhost abc]# mkdir /abc 创建网站发布目录
在目录中上传图片,并写一个index.html
[root@localhost abc]# ls
1.png index.html
[root@localhost abc]# vim index.html
<html>
<head>
<meta charset="utf-8">
<title>qf.com</title>
</head>
<body>
<center><img src="../1.png" alt="xingdian" /></center>
</body>
</html>
B机器
有一个网站发布目录,有index.html的测试网站(不需要有图片 图片直接从A盗用)
[root@localhost ~]# vim /etc/nginx/conf.d/daotu.conf 创建编辑子配置文件
server {
listen 80;
server_name localhost;
location / {
root /daotu;
index index.html;
}
}
[root@localhost ~]# mkdir /daotu
[root@localhost ~]# vim /daotu/index.html
<html>
<head>
<meta charset="utf-8">
<title>qf.com</title>
</head>
<body style="background-color:red;">
<img src="http://192.168.242.134/1.png" /> 盗链A服务器的图片
</body>
</html>
[root@localhost conf.d]# nginx -t
[root@localhost conf.d]# nginx -s reload
浏览器访问B服务器ip(盗链成功)
然后在A服务器上部署防盗链
[root@localhost ~]# vim /etc/nginx/nginx.conf
# 日志格式添加"$http_referer",如果存在就不需要重复添加
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
[root@localhost ~]# vim /etc/nginx/conf.d/abc.conf 编辑子配置文件,添加防盗链配置
server {
listen 80;
server_name localhost;
location ~ {
root /abc;
valid_referers none blocked 192.168.31.54;
if ($invalid_referer) {
return 403;
}
}
location / {
root /abc;
index index.html;
}
}
• none : 允许没有http_refer的请求访问资源;
• blocked : 允许不是http://开头的,不带协议的请求访问资源---被防火墙过滤掉的;
• server_names : 只允许指定ip/域名来的请求访问资源(白名单);
[root@localhost ~]# nginx -s reload
浏览器访问B服务器ip验证是否还能盗链(盗链失败,说明A服务器防盗链部署成功)
我们在A服务器字配置文件中的允许指定ip/域名来的请求访问资源(白名单)中添加B服务器的ip,然后在服务器上验证。
在浏览器上访问B服务器的ip,能够看到图片信息。
location块
Nginx 的 HTTP 配置主要包括三个区块,结构如下:
http { # 这个是协议级别
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
gzip on;
server { # 这个是服务器级别
listen 80;
server_name localhost;
location / { # 这个是请求级别
root html;
index index.html index.htm;
}
location ~ \.(html|jpg)$ {
root /abc;
}
}
}
1、location 区段
• location 是在 server 块中配置,根据不同的 URI 使用不同的配置,来处理不同的请求。
• location 是有顺序的,会被第一个匹配的location 处理。
基本语法如下:
location [=|~|~*|^~|@] pattern{……}2、location 前缀含义
= 表示精确匹配,优先级也是最高的
^~ 表示uri以某个常规字符串开头,理解为匹配url路径即可
~ 表示区分大小写的正则匹配
~* 表示不区分大小写的正则匹配
!~ 表示区分大小写不匹配的正则
!~* 表示不区分大小写不匹配的正则
/ 通用匹配,任何请求都会匹配到
3、location 配置示例
1)、没有修饰符 表示:必须以指定模式开始
location / {
root /abc/location; (/abc/location目录下:有abc的目录,index.html)
index 2.html;
}
2)、=表示:必须与指定的模式精确匹配(创建一个网站发布目录,下面分别a.html和b.html)
location = / {
root /usr/share/nginx/html;
index b.html index.htm;
}
location / {
root /usr/share/nginx/html;
index a.html index.htm;
} #优先匹配第一个location块,匹配不到的话再从第二个location匹配
3)、~ 表示:指定的正则表达式要区分大小写
location ~ \.(jpg|css)$ {
root location; //要在location目录下有一个以.jpg结尾的文件
}
4)、~* 表示:指定的正则表达式不区分大小写
location ~* \.(JPG|css)$ {
root location; //要在location目录下有一个以.jpg结尾的文件
}
查找顺序和优先级
1:带有“=“的精确匹配优先
2:没有修饰符的精确匹配
3:正则表达式按照他们在配置文件中定义的顺序
4:带有“^~”修饰符的,开头匹配
5:带有“~” 或“~*” 修饰符的,如果正则表达式与URI匹配
6:没有修饰符的,如果指定字符串与URI开头匹配优先级 当遇到有location都能匹配该请求的时候,才会用到优先级
如果提交的url只能有一个location,那么该location的参数会去处理该请求
= 大于 ^~ 大于 ~|~*|!~|!~* 大于 /
多个location配置的情况下匹配顺序为:首先匹配 =,其次匹配^~, 其次是按正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。(1) =:表示完全匹配;
(2) ^~:匹配URI的前缀,并且后面的正则表达式不再匹配,如果一个URI同时满足两个规则的话,匹配最长的规则;
(3) ~:匹配正则表达式,大小写敏感;
(4) ~*:匹配正则表达式,大小写不敏感;
优先级:(1)> (2) > (3)
location 区段匹配示例
location = / {
# 只匹配 / 的查询.
[ configuration A ]
}
location / {
# 匹配任何以 / 开始的查询,但是正则表达式与一些较长的字符串将被首先匹配。
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开始的查询并且停止搜索,不检查正则表达式。
[ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配任何以gif, jpg, or jpeg结尾的文件,但是所有 /images/ 目录的请求将在Configuration C中处理。
[ configuration D ]
}
各请求的处理如下例:
/ → configuration A
/documents/document.html → configuration B
/images/1.gif → configuration C 虽然以.gif结尾,但是匹配到/images/就停止搜索了,所以不会交给D处理
/documents/1.jpg → configuration D
root 、alias 指令区别
location /img/ {
alias /var/www/image/;
}
#若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/var/www/image/目录找文件
location /img/ {
root /var/www/image;
}
#若按照这种配置的话,则访问/img/目录下的文件时,nginx会去/var/www/image/img/目录下找文件。
• alias 是一个目录别名的定义,
• root 则是最上层目录的定义。
• 还有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的,而root则可有可无
示例
location /img/ {
alias /abc/location/;
}
location /img/ {
root /abc/location;
}
网站内容
[root@localhost ~]# tree /abc/location
/abc/location
├── img
│ └── index.html
└── index.html
curl 192.168.242.134/img/index.html
会被alias这个location块处理访问到/abc/location/img/index.html
如果改成这样,root /abc/location/img 这样就会访问到/abc/location/img/index.html