实验环境配置:
三台虚拟机:server1 server2 server3
每台虚拟机的本地解析都需要写//etc/hosts
1.反向代理
什么是代理?
所谓代理就是一个代表、一个渠道
此时就涉及到两个角色,一个是被代理角色,一个是目标角色,被代理角色通过这个代理访问目标角色完成一些任务的过程称为代理操作过程
正向代理:
正向代理最大的特点是客户端明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;正向代理模式屏蔽或者隐藏了真实客户端信息
反向代理:
由于企业当中一台服务器不能承受负载,所以会通过部署多台服务器来解决访问人数限制的问题
多个客户端给服务器发送的请求,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。此时~请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,nginx扮演的就是一个反向代理角色
实验
在已经安装好nginx的server1主机中将nginx拷贝给server2 server3
scp -r /usr/local/nginx server2:/usr/local/
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ #建立软连接
scp -r /usr/local/nginx server3:/usr/local/
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ #建立软连接
在server2 server3中编辑主配置文件
worker_processes 设置为auto自动识别工作线程
然后在两个代理服务器server2 server3中配置
语法检测nginx -t
echo server2 > /usr/local/nginx/html/index.html
echo server3 > /usr/local/nginx/html/index.html
nginx ##启动nginx
nginx -s reload ##重新加载
回到server1中
vim /usr/local/nginx/conf/nginx.conf
http {
upstream westos {
server 172.25.7.2:80;
server 172.25.7.3:80;
}
...
server {
listen 80;
server_name www.westos.org;
location / {
proxy_pass http://westos;
}
}
nginx -t
nginx -s reload
现在可以在真机充当的客户端当中进行测试
curl www.westos.org
得到的结果是代理服务器server2 server3 并不是server1
2.负载均衡
我们已经明确了所谓代理服务器的概念,那么接下来,nginx扮演了反向代理服务器的角色,它是以依据什么样的规则进行请求分发的呢?不用的项目应用场景,分发的规则是否可以控制呢?
这里提到的客户端发送的、nginx反向代理服务器接收到的请求数量,就是我们说的负载量
请求数量按照一定的规则进行分发到不同的服务器处理的规则,就是一种均衡规则
所以我们将服务器接收到的请求按照规则分发的过程,称为“负载均衡”
nginx支持的负载均衡调度算法
1.weight轮询
接收到的请求按照顺序逐一分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,nginx会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。 这种方式下,可以给不同的后端服务器设置一个权重值(weight),用于调整不同的服务器上请求的分配率;权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的
实验效果如下:这里我们将server2的权重值调为3
即在访问服务器时通过server2代理服务器的与server3的比例应该为3:1
2.备用机backup
当所有代理服务器都故障时将服务器本身设置为备用机
使用回环接口将调度站本身设置为备用,当后端主机恢复时则不会访问备用主机
3.ip_hash
每个请求按照发起客户端的ip的hash结果进行匹配,这样的算法下一个固定ip地址的客户端总会访问到同一个后端服务器,这也在一定程度上解决了集群部署环境下session共享的问题
hash自动匹配到固定代理服务器让客户进行访问,除非这个服务器停止运行才会调度到新的服务器,或者有新的域名访问才会重新调度
实验结果如图: 后半段我们将server3nginx停止,发现会自动调度到新的服务器
4.fair智能调整调度算法
动态的根据后端服务器的请求处理到响应的时间进行均衡分配,响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少;结合了前两者的优点的一种调度算法。但是需要注意的是nginx默认不支持fair算法,如果要使用这种调度算法,需要安装upstream_fair模块
5.url_hash
按照访问的url的hash结果分配请求,每个请求的url会指向后端固定的某个服务器,可以在nginx作为静态服务器的情况下提高缓存效率。这种调度算法要使用的话也需要安装nginx的hash软件包
3.算法扩展——sticky算法
nginx并不支持一些算法,当我们需要使用时则需要进行拓展
比如sticky模块,nginx本身不支持,当在配置文件中写入并调用时会汇报出错
所以需要算法拓展
sticky算法模块
Sticky工作原理:
Sticky是基于cookie的一种负载均衡解决方案,通过分发和识别cookie,使来自同一个客户端的请求落在同一台服务器上,默认cookie标识名为route:
1.客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
2.后端服务器处理完请求,将响应数据返回给nginx。
3.此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值。
4.客户端接收请求,并保存带route的cookie。
5.当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器。
sticky模块与Ip_hash都是与负载均衡算法相关,但又有区别
区别:
1.ip hash,根据客户端的IP的hash进行匹配绑定,
客户端将会与一个后端服务器绑定,一定程度上解决了集群部署环境下session共享的问题
2.sticky,根据服务器给客户端的cookie,客户端再次请求时会带上此cookie,nginx会把有此cookie的请求转发到颁发cookie的服务器上
推荐使用sticky算法
cd /usr/local/nginc/conf
vim nginx.conf
///
http {
upstream westos {
sticky;
server 172.25.24.2:80 weight=2;
///
nginx -t
算法检测时报错
我们需要对nginx进行扩展,先将sticky注释掉,并停止nginx服务
更改火墙策略,下载算法模块
nginx -t
nginx -s stop
iptables -t nat -I POSTROUTING -s 172.25.24.0/24 -j MASQUERADE ##真机上写火墙策略,开启地址伪装
cd
lftp 172.25.254.250
> ls
> cd pub/docs/lamp/
> get nginx-goodies-nginx-sticky-module-ng-08a395c66e42.zip ##下载
> exit
yum install -y unzip ##下载zip解压软件包
unzip nginx-goodies-nginx-sticky-module-ng-08a395c66e42.zip ##解压sticky软件包
安装好之后切入nginx目录,清理缓存,执行编译configure->make
cd nginx-1.20.1/ make clean ##清理缓存
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-threads --with-file-aio --add-module=/root/nginx-goodies-nginx-sticky-module-ng-08a395c66e42 ##配置
make ##编译
提示:有的时候我们在编译时不知道是否编译成功,而在编译失败时去make install(安装)肯定会出错,这样会增加问题的复杂性,所以我们可以在编译完成后输入
echo $? ##输出为0则成功
将nginx复制到sbin并覆盖,切入配置目录,编辑配置文件,此时可以使用sticky算法 并检测语法
ls
cd objs/
\cp -f nginx /usr/local/nginx/sbin/ ##复制覆盖文件,\表示告诉shell不要去查alias,直接执行原本的cp
vim nginx.conf
nginx -t
4.nginx限流
先建立一个实验素材
cd html/
mkdir downloads
cd downloads/
lftp 172.25.254.250
> cd pub/docs/
> get vim.jpg
> exit
du -h vim.jpg ##444K
(1)限制并发连接数
在真机执行压力测试命令,设定并发用户数为10,请求总数为10,成功10个
###真机
ab -c10 -n 10 http://172.25.7.1/downloads/vim.jpg ##并发用户数为10,请求总数为10,失败0个
在server1中编辑配置文件
limit_conn_zone $binary_remote_addr zone=addr:10m;
location /download/ {
limit_conn addr 1;
}
###真机中
ab -c10 -n 10 http://172.25.24.1/download/vim.jpg ##部分被拒绝
(2)限制每秒请求数
在真机执行压力测试,设定并发用户数为1,请求总数为10,则请求全部通过
ab -c1 -n 10 http://172.25.24.1/downloads/vim.jpg ##全部通过
在server1主机中编辑配置文件,设定每秒只通过1个请求,重启服务
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
limit_req zone=one;
重新在真机执行压力测试,因为每秒只通过一个,则其余9个被拒绝
(3)排队,超过指定数量则排队访问
在配置文件中设定一次访问5个,超过的排队等待,因为上一个实验设定每秒通过1个请求,则访问2次,差不多10秒
limit_req zone=one burst=5;
在真机中,执行压力测试,访问时长大约9秒
(在真实情况下,偏差在几台主机的情况是可以忽略不计的)
(4)无延迟
编辑配置文件,设定请求无延迟,在上一个实验的情况下,只能执行1次,即5个请求,重启服务
limit_req zone=one burst=5 nodelay;
真机中,执行压力测试,只能通过4个,其余被拒绝(误差可以忽略)
(5)限制带宽
现实生活中,我们下载东西时,会被限制网速,其实就是限制带宽。
在配置文件中设定带宽50k,重启服务,注释掉上面实验的参数,不然会很慢
limit_rate 50k;
在真机中执行压力测试,文件大小为444k,访问5次,限制带宽50k,大概需要40s
5.平滑升级
当服务器在运行的时候我们想升级版本的情况下就需要用到平滑升级
平滑升级可以在服务器运行的状态下最大限度的保持数据的完整性
实验步骤:
1.版本更新
安装一个比当前版本高的nginx,解压,重新编译
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-threads --with-file-aio
make
注意:此处不需要make install
make之后备份原程序,将升级版本拷贝覆盖原程序
cd /usr/local/nginx/sbin
\cp -f nginx nginx.old #备份
cd ~/nginx1.21.1/objs
\cp -f nginx /usr/local/nginx/sbin #新程序覆盖替换
ps ax | grep nginx #查看当前nginx进程
kill -USR2 原主进程pid #开启新版本
此时新版本已经打开
因为有时觉得就版本更好,所以保留就版本的主进程为了即回退,则只关闭worker,保留master
kill -WINCH 原主进程pid #关闭原worker进程但保留主进程:为了回退
curl localhost -I #查看当前nginx版本
2.版本回退
回退的过程与更新相反,先还原nginx程序,唤醒进程,回收新版本,并关闭即可
cd /usr/local/nginx/sbin/
\cp -f nginx.old nginx #还原nginx程序
kill -HUP 原进程pid #唤醒原进程
ps ax | grep nginx #查看进程
kill -WINCH 21337 #回收新版本进程
kill -QUIT 21337 #关闭新版本进程
6.nginx配置管理
(1)自动索引
当我们在访问浏览器时为了下载软件更加方便,可以在配置文件中设定自动索引
**注意:**注释这些参数设定,重启服务
vim nginx.conf
///
location /download/ {
limit_conn addr 1;
#limit_req zone=one burst=5 nodelay;
#limit_rate 50k; ##注释
autoindex.on;
///
nginx -s reload
(2)nginx expire 缓存配置
缓存可以降低网站带宽,加速用户访问。
编辑配置文件,设定对图片等进行缓存,缓存时间为1年,在此期间访问就会减少访问时间
vim nginx.conf
///
location /download/ {
limit_conn addr 1;
#limit_req zone=one burst=5 nodelay;
#limit_rate 50k;
autoindex on;
} ##在此位置下方进行设定
location ~ .*\.(gif|jpg|png)$ { ##对图片等进行缓存
expires 365d;
root html;
}
///
nginx -s reload
在真机中,使用curl命令访问素材文件,可以看到缓存至2022年
curl -I 172.25.7.1/download/vim.jpg
(3)日志轮询
编写一个脚本,设定打开nginx时会生成日志文件,命名格式为前一天
cd /opt/ ##第三方软件安装位置
vim nginx.sh
///
#!/bin/bash
cd /usr/local/nginx/logs && mv access.log access_$(date +%F -d -1day).log
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
///
给脚本执行权限,执行脚本,切入到日志目录,产生日志
chmod +x nginx.sh
./nginx.sh
cd /usr/local/nginx/logs/
ls --> access_2021-08-31.log ##生成日志
(4)禁用不必要的日志记录,以节省磁盘IO的消耗
在配置文件中设定禁用浏览器访问指定目录时生成日志文件
cd ..(nginx)
cd conf/
vim nginx.conf
///
location ~ .*\.(gif|jpg|png)$ {
expires 365d;
root html;
} ##在这个位置的下面加入设定
location /status {
stub_status on;
access_log off;
}
///
nginx -t
nginx -s reload
此时在浏览器中访问该目录,在日志目录中不会生成日志记录
在浏览器访问
172.25.24.1/status ##刷新会增加访问次数,但不会有日志生成
cd ../logs
ls
cat access.log ##为空
但当在真机中使用curl命令访问该目录时,会产生日志文件
###真机
curl -I 172.25.7.1/status
###server1
cat access.log ##会产生日志文件
(5)站点目录和文件的限制
在配置文件中设定指定目录只能本机访问,拒绝其他所有请求
cd conf/
vim nginx.conf
///
location /status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
///
nginx -t
nginx -s reload
当在真机访问status目录时,拒绝访问,报错403,资源不可用,服务器理解客户的请求,但拒绝处理
curl 172.25.7.1/status ##拒绝访问
当在server1本机访问时,允许访问
curl localhost/status
(6)中文乱码
nginx默认不支持中文字符,在浏览器访问时,中文会变成乱码。
在nginx发布文件中加入一行中文,在浏览器中试访问,为乱码
cd /usr/localnginx/html/
echo hello中国 > index.html
#在浏览器访问时中文是乱码
但是在server1本机中,可以使用curl命令查看本地的发布文件,是可以正常显示中文的
编辑配置文件,设定nginx支持中文字符,并重启服务
vim nginx.conf
///
server {
listen 80;
server_name localhost;
charset utf-8;
///
nginx -s reload
此时在浏览器中访问172.25.7.1,可以看到中文正常显示
7.nginx 重定向
(1) 防止域名恶意解析到服务器IP
1)拒绝访问,报错500
切入配置目录,编辑配置文件,设定在访问本机时,返回500,重启服务。此时使用curl命令访问本机,会显示http报错500
cd /usr/local/nginx/conf/
vim nginx.conf
///
server {
listen 80;
server_name localhost;
return 500;
///
nginx -s reload
curl -I localhost ##HTTP/1.1 500 Internal Server Error
当在浏览器中访问server1主机时,也会报错500
2)将所有访问重定向至指定域名
编辑配置文件,设定将所有访问请求重定向至指定域名,重启服务,此时使用curl命令访问本机,会显示访问地址为http://www.westos.org
vim nginx.conf
///
server {
listen 80;
server_name localhost;
rewrite ^(.*) http://www.westos.org permanent;
///
nginx -s reload
curl -I localhost ##Location: http://www.westos.org
当在浏览器中访问server1主机时,写入172.25.7.1回车后会自动跳转至www.westos.org
(2)端口重定向
编辑配置文件,将80端口定向到443端口
vim nginx.conf
///
server {
listen 443 ssl;
server_name www.westos.org;
ssl_certificate cert.pem;
ssl_certificate_key cert.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
server {
listen 80;
server_name www.westos.org;
rewrite ^/(.*)$ https://www.westos.org/$1 permanent;
#location / {
# proxy_pass http://westos;
# }
}
///
生成证书,并移动到配置目录中,检测语法,重启服务。此时检测端口
cd /etc/pki/tls/certs
make cert.pem ##生成证书
mv cert.pem /usr/local/nginx/conf
nginx -t
nginx -s reload
netstat -antlup | grep 443
在浏览器中访问server1主机,可以看到https即代表443端口重定向成功
在真机中使用curl命令,可以看到加密端口已打开
(3)虚拟主机重定向
1)www.westos.org 重定向bbs.westos.org
cd ..(nginx)
cd html
mkdir bbs
mv bbs/ /
vim nginx.conf
///
server {
listen 80;
server_name www.westos.org;
#rewrite ^/(.*)$ https://www.westos.org/$1 permanent;
rewrite ^/bbs$ http://bbs.westos.org permanent;
#rewrite ^/(.*)$ http://bbs.westos.org/$1 permanent;
#location / {
# proxy_pass http://westos;
# }
}
server {
listen 80;
server_name bbs.westos.org;
location / {
root /bbs;
index index.html;
}
}
///
nginx -s reload
在真机使用curl命令可以查看
浏览器输入www.westos.org会自动跳转为bbs.westos.org
当你想访问域名下的目录时,但是只能输入规定www.westos.org/bbs
输入其他会报错
所以可以加
rewrite ^/(.*)$ http://bbs.westos.org/$1 permanent; #以任何开头或结尾都可以重定向到bbs.westos.org
2)bbs.westos.org 重定向www.westos.org
vim nginx.conf
///
server {
listen 80;
server_name www.westos.org bbs.westos.org;
#rewrite ^/(.*)$ https://www.westos.org/$1 permanent;
#rewrite ^/bbs$ http://bbs.westos.org permanent;
#rewrite ^/(.*)$ http://bbs.westos.org/$1 permanent;
if ($host = "bbs.westos.org") {
rewrite ^/(.*)$ http://www.westos.org/bbs/$1 permanent;
}
#server { ##全部注释
# listen 80;
# server_name bbs.westos.org;
#
# location / {
# root /bbs;
# index index.html;
# }
# }
///
nginx -s reload
在真机先做地址解析,使用curl命令可以查看
172.25.7.1 server1 www.westos.org reg.westos.org bbs.westos.org
在浏览器中输入bbs.westos.org会自动跳转至www.westos.org/bbs
(4)防盗链
由于经常有些人可能会盗链你的主机中内容进行流量浏览
我们可以通过防盗链进行限制别人盗链我们的内容
盗链主机server2
防盗主机server1
在我们的server1当中/usr/local/nginx/html下建立一个目录download
目录内下载一张图片,假设盗链这张图片
配置server2盗链主机
cd /usr/local/nginx/html
vim test.html
\\\
<html>
<body>
<br> hello中国 </br>
<img src="http://www.westos.org/download/vim.jpg">
</body>
</html>
\\\
配置完毕
在浏览器当中通过server2的IP进行访问
成功盗链到serve1主机的内容
配置防盗主机server1
vim /usr/local/nginx/conf/nginx.conf
location ~ \.(jpg|png)$ {
valid_referers none blocked www.westos.org;
if ($invalid_referer) {
return 403; ##只能通过www.westos.org域名进行访问,否则将会403拒绝
#rewrite ^/ http://www.westos.org/daolian.jpg;
}
}
防盗连配置完毕!
此时浏览器再次访问
为了防盗连的效果,我们可以将防盗链重定向到一张图片,展示给盗链你的人
location ~ \.(jpg|png)$ {
valid_referers none blocked www.westos.org;
if ($invalid_referer) {
#return 403;
rewrite ^/ http://www.westos.org/daolian.jpg;
}
}
此时再次访问