Nginx 高级功能详解

222 阅读10分钟

一、 重写功能

Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求。

官方文档:nginx.org/en/docs/htt…

用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为自动访问,另外还可以在一定程度上提高网站的安全性。

1. if 指令

  • if指令可以配置在serverlocation块中
  • if指令用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置
  • Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断
  • 使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false

用法:

if (条件匹配) {   
 action
}

示例:

[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf  //编辑子配置文件

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

location /test {
     index index.html;            //定义网站的默认首页
     default_type text/html;      //指定解析当前内容的类型
   if  ( $scheme = https ) {      //添加if指令
   echo "if -----> $scheme";
   }
 }
}

[root@node1 ~]#  nginx -s reload  //重新加载

浏览器验证 https://192.168.204.10/test
if指令验证.png

2. return 指令

  • return用于完成对请求的处理,并直接向客户端返回响应状态码
  • return可以在serverlocation块和 if 进行配置
  • 处于此指令后的所有配置都将不被执行

语法格式:

Syntax:	return code [text];  //返回给客户端的状态码及响应报文的实体内容
           return code URL;    //返回给客户端的URL地址
           return URL; 
Default:	—
Context:	server, location, if

示例1:

[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

  location /test {
     index index.html;
     default_type text/html;
     return 666 "hello";     //如果访问192.168.204.10/test 就返回666错误代码,页面显示hello
  }
}

[root@node1 ~]#  nginx -s reload     //重新加载        

[root@node2 ~]#  curl 192.168.204.10/test
hello
[root@node2 ~]#  curl 192.168.204.10/test -I
HTTP/1.1 666    //错误代码666
Server: nginx
..........
return 666.png

示例2:301

[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

  location /test {
     index index.html;
     default_type text/html;
     return 301 http://www.baidu.com/;     //如果访问192.168.204.10/test 就返回301并跳转到百度
  }
}

[root@node1 ~]#  nginx -s reload     //重新加载        
return baidu.png

示例3:302

[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

  location /test {
     index index.html;
     default_type text/html;
     return 302 index.html;     //如果访问192.168.204.10/test 就返回302并显示/data/html/index.html内容
  }
}

[root@node1 ~]#  nginx -s reload     //重新加载        
return 302.png

状态码 301 和 302

状态码含义区别
301永久重定向服务器不需要每次向客户提供新的url,客户访问过后会记录在自己的缓存中,即使nginx服务器死机,客户在一定时间内也可以继续跳转
302临时重定向没有缓存,服务器断开无法重定向

3. set 指令

  • set定义格式为set $key value
  • 指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key
  • value可以是text, variables和两者的组合

语法格式:

Syntax:	set $variable value;
Default:	—
Context:	server, location, if

示例:

[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

  location /test {
     index index.html;
     default_type text/html;
set $name kgc;               //添加set指令
echo $name;
set $my_port $server_port;
echo $my_port;
}
}

[root@node1 ~]#  nginx -s reload   //重新加载

[root@node2 ~]#  curl 192.168.204.10/test   //验证
kgc
80

4. break 指令

  • 用于中断 当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行。

语法格式:

Syntax:	break;
Default:	—
Context:	server, location, if

示例:

[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

  location /test {
     index index.html;
     default_type text/html;
set $name kgc;
echo $name;
break;          //添加 break 指令
set $my_port $server_port;
echo $my_port;
echo $host;
}
}

[root@node1 ~]#  nginx -s reload   //重新加载

[root@node2 ~]#  curl 192.168.204.10/test    //验证
kgc
                //break指令下的set指令不执行
192.168.204.10

break下如果出现同属于rewrite模块的指令(if、return、set、rewrite等),那么break后的指令将不再执行。

5. rewrite 指令 ★

  • 通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理

语法格式:

Syntax:	rewrite regex replacement [flag];
Default:	—
Context:	server, location, if

//正则匹配原始访问url    替代你想让客户访问的     标志 ()premanent301   redirect302  break  last

flag 说明:

类型flag区别
跳转型redirect临时重定向302
 permanent永久重定向301
代理型break是立即终止匹配  使用该url进行匹配
 last停止本location中的匹配,开启新一轮的location匹配
  • 跳转型指由客户端浏览器重新对新地址进行请求
  • 代理型是在WEB服务器内部实现跳转
  • break 和 last 是为了防止死循环使用的

示例1

实验效果:访问 bj 等于访问 beijing

[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf  

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

 location /bj {      
 root /data/;   //注意!url为bj时访问此目录下的页面,但是重写后url变为beijing,就不再生效
 rewrite ^/bj/(.*)   /beijing/$1   permanent;   //添加rewrite指令,$1代表后项引用
 }
}

[root@node1 ~]#  cd html
[root@node1 html]#  mkdir beijing        //创建目录
[root@node1 html]#  echo /data/beijing/ > beijing/index.html   //生成页面


[root@node1 data]#  nginx -t         //检查格式
[root@node1 data]#  nginx -s reload  //重新加载

浏览器访问192.168.204.10/bj/    //注意bj后面要加/,不然会报错404
等于访问192.168.204.10/beijing/
bj 跳转 beijng.png

示例2

实验效果:整个网页跳转 ,www.pc.com 跳转到 www.m.com

[root@node1 html]#  vim /apps/nginx/conf.d/pc.conf

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

 location / {
 rewrite  /  http://www.m.com  permanent;   //重写
 }
}


server  {
listen 80;
server_name  www.m.com;
root /opt;
}

[root@node1 html]#  cd /opt
[root@node1 opt]#  echo "/opt/wo shi m.com" > index.html   //生成页面
[root@node1 opt]#  nginx -s reload   //重新加载

真机 在C:\Windows\System32\drivers\etc下编辑hosts文件,添加域名

浏览器访问192.168.204.10/  会跳转到www.m.com
rewrite整个页面跳转.png

示例3

实验效果:http 转 https

[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf 

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

   location / {
   if  ( $scheme = http ) {
   rewrite ^/(.*)$ https://www.pc.com/$1 permanent;  //重写
   }
  }
}

[root@node1 ~]#  nginx -s reload   //重新加载

浏览器输入http://www.pc.com
会跳转为  https://www.pc.com
http转https.png

6. 防盗链 ★

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:

  • none:请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
  • blocked:请求报文有referer首部,但无有效值,比如为空。
  • server_names:referer首部中包含本主机名及即nginx 监听的server_name。
  • arbitrary_string:自定义指定字符串,但可使用 * 作通配符。示例:*.kgc.org 或 www.kgc.*
  • regular expression:被指定的正则表达式模式匹配到的字符串,要使用 ~ 开头,例如:~.*.kgc.com

实现盗链

7-1:192.168.204.10

7-2:192.168.204.20

  1. 7-1上传一张图片;
[root@node1 ~]#  cd /data/html
[root@node1 html]#  rz   //上传一张图片

[root@node1 html]#  ls
about  beijing  download  index.html  passwd.html  xhr.jpg  //图片上传成功
  1. 7-2安装nginx,自定义页面;
[root@node2 ~]#  yum install epel-release.noarch -y
[root@node2 ~]#  yum install nginx               //yum安装nginx
[root@node2 ~]#  systemctl start nginx           //开启服务
[root@node2 nginx]#  cd /usr/share/nginx/html/   //切换目录
[root@node2 html]#  ls
404.html  50x.html  en-US  icons  img  index.html  nginx-logo.png  poweredby.png
[root@node2 html]#  rm -rf index.html

[root@node2 html]#  vim index.html    //生成页面

<html>
<body>
<h1>this is Bob  </h1>
<img src="http://192.168.204.10/xhr.jpg"/>     //指明图片的源位置
</body>
</html>

[root@node2 html]#  systemctl restart nginx    //重启服务
  1. 浏览器输入7-2的ip地址 192.168.204.20 ;

    模拟盗链.png
  2. 7-2中实际并不存在xhr.jpg这张图片,但由于进行了盗链设置,可以直接使用7-2的ip地址访问7-1内的图片。

实现防盗链

Nginx防盗链主要是通过对请求的Referer头部字段进行检查,如果请求不是从合法的来源(比如自己的网站)来的,Nginx会返回一个错误码,通常是403 Forbidden。

1. 编辑7-1的配置文件;

rerfer你从哪里跳转过来的
设置有效值 来确定是否允许访问我站点上的图片

[root@node1 html]#  vim /apps/nginx/conf.d/pc.conf    //设置防盗链

server  {
listen 80;
listen 443 ssl;
        ssl_certificate /opt/www.pc.com.crt;
        ssl_certificate_key /opt/www.pc.com.key;
server_name  www.pc.com;
root  /data/html/;

    location ~* \.(jpg|gif|swf|jpeg|bmp)$ {       //开启正则,匹配不区分大小写,以.jpg或.gif或.swf结尾的文件
    valid_referers none blocked *.pc.com pc.com;  //设置信任的网站,可以正常使用图片。合法的refer:空、无效值或.pc.com结尾或pc.com
        if ( $invalid_referer ) {                 //如果为非法值,就返回403
       #rewrite ^/ http://www.pc.com/error.png;   //准备一个错误图片返回(注意后缀!陷入死循环问题)
        return   403;
        }
    }
}

[root@node1 html]#  nginx -t           //检查格式
[root@node1 html]#  nginx -s reload    //重新加载

2. 验证:浏览器输入7-2的ip192.168.204.20进行验证;未显示图片,防盗链设置成功。

防盗链.png

二、 反向代理

1. 概述

反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。

Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能。

ngx_http_proxy_module    //将客户端的请求以http协议转发至指定服务器进行处理      7层代理
ngx_http_upstream_module //用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组      负载均衡
ngx_stream_proxy_module  //将客户端的请求以tcp协议转发至指定服务器处理           4层代理
ngx_http_fastcgi_module  //将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module    //将客户端对Python的请求以uwsgi协议转发至指定服务器处理

nginx两种代理模式: 同构代理、异构代理

2. 反向代理配置参数

官方帮助文档:nginx.org/en/docs/htt…

指令语法:

Syntax:	proxy_pass URL;
Default:	—
Context:	location, if in location, limit_except

proxy_pass; 
//用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP地址:端口的方式
//也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持

示例:

location / {
proxy_pass http://192.168.91.101;
}
//访问本机的主站点,那么跳转到 101 的主站点 

3. 实现反向代理

3.1 单台反向代理

单台反向.png

7-1 代理服务器:192.168.204.10
7-2 真实服务器:192.168.204.20
7-3 客户机:192.168.204.30
7-3作为客户端去访问代理服务器7-1,跳到7-2

`7-2 真实服务器:`
[root@node2 ~]#  yum install httpd -y
[root@node2 ~]#  systemctl start httpd   //此处服务起不来记得检查防火墙、nginx是否关闭
[root@node2 ~]#  cd /var/www/html/
[root@node2 html]#  echo "7-2 7-2 7-2" > index.html
[root@node2 html]#  ls
index.html

`7-3验证:`
[root@node3 ~]#  curl 192.168.204.20 
7-2 7-2 7-2


`7-1 代理服务器:`
[root@node1 conf.d]#  vim pc.conf 

server  {
listen 80;
server_name  www.pc.com;
root  /data/html;
 location / {
 proxy_pass http://192.168.204.20;   //因为是7层必须把协议写上,写7-2真实服务器的ip
 }
}

[root@node1 conf.d]#  nginx -s reload

`7-3验证:`
[root@node3 ~]#  curl 192.168.204.10
7-2 7-2 7-2
单台反向代理.png

3.2 动静分离

动静分离.png

7-1 代理服务器:192.168.204.10
7-2 静态服务器:192.168.204.20
7-3 动态服务器:192.168.204.30
7-4 客户端:192.168.204.40


`7-1 代理服务器:`
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf 

server  {
listen 80;
server_name  www.pc.com;
root  /data/html;
   location /api {                       //动态资源
   proxy_pass http://192.168.204.30/;
   }
   location ~* \.(jpg|png|bmp|gif)$ {    //静态资源
   proxy_pass http://192.168.204.20;
   }
}

[root@node1 ~]#  nginx -t
[root@node1 ~]#  nginx -s reload


`7-2 静态服务器:`
[root@node2 ~]#  systemctl stop firewalld
[root@node2 ~]#  setenforce 0
[root@node2 ~]#  systemctl stop nginx
[root@node2 ~]#  systemctl start httpd
[root@node2 ~]#  cd /var/www/html
[root@node2 html]#  rz       //准备图片

[root@node2 html]#  ls
kkaa.jpg


`7-3 动态服务器:`
[root@node3 ~]#  systemctl stop firewalld
[root@node3 ~]#  setenforce 0
[root@node3 ~]#  systemctl stop nginx
[root@node3 ~]#  systemctl start httpd
[root@node3 ~]#  cd /var/www/html/
[root@node3 html]#  ls
[root@node3 html]#  echo "7-3 dongtaifuwuqi" > index.html    //准备页面
[root@node3 html]#  ls
index.html


`7-4 客户端验证:`
[root@localhost ~]#  curl 192.168.204.10/api        //动态
7-3 dongtaifuwuqi
[root@localhost ~]#  curl 192.168.204.10/kkaa.jpg   //静态
动静分离2.png

动静分离1.png

3.3 缓存功能

关闭后端服务器后,图片无法访问,因为缓存功能默认关闭,需要开启。

示例:

  1. 在未开启缓存前测试下载速度;
`7-2 真实服务器上传一张图片`
[root@node2 html]#  rz

[root@node2 html]#  ls
fast.jpg  kkaa.jpg

`7-4 客户端压力测试`
[root@localhost ~]#  ab -c100 -n1000 http://192.168.204.10/fast.jpg
  1. 7-1 代理服务器修改主配置文件,建立代理缓存文件夹;
7-1代理服务器
让nginx软件产生缓存

[root@node1 ~]#  vim /apps/nginx/conf/nginx.conf   //编辑主配置文件
http {
    include       mime.types;
    proxy_cache_path /data/nginx/proyxcache   levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;
    //proxy_cache_path代理缓存的路径,必须放在http语句块中,并放在include子配置文件语句前!
    //levels=1:1:1; 定义缓存目录结构层次,1:1:1可以生成2^4x2^4x2^4=2^12=4096个目录
    //keys_zone=proxycache:20m; 指内存中缓存的大小,主要用于存放key和metadata(如:使用次数),一般1M可存放8000个左右的key
    //inactive=120s;  缓存有效时间
    //max_size=10g;  最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
    include  /apps/nginx/conf.d/*.conf;
  
[root@node1 ~]#  mkdir /data/nginx    //建立/data/nginx/文件夹,proyxcache会自动生成
[root@node1 ~]#  ls /data
beijing  html  nginx  pc  phone
  1. 7-1 代理服务器修改子配置文件
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf   //编辑子配置文件
server  {
listen 80;
server_name  www.pc.com;
root  /data/html;
        proxy_cache proxycache;            //调用缓存功能
        proxy_cache_key $request_uri;      //对指定的数据进行MD5的运算做为缓存的key
        proxy_cache_valid 200 302 301 10m; //指定的状态码返回的数据缓存多长时间
        proxy_cache_valid any 5m;          //除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存
   location /api {
   proxy_pass http://192.168.204.30/;
   }
   location ~* \.(jpg|png|bmp|gif)$ {
   proxy_pass http://192.168.204.20;
   }
}
[root@node1 ~]#  nginx -s reload      //重建加载
[root@node1 ~]#  tree /data/nginx     //已自动生成proyxcache文件
/data/nginx
└── proyxcache

1 directory, 0 files
  1. 验证是否实现缓存。
用浏览器访问192.168.204.10/fast.jpg
[root@node1 ~]#  tree /data/nginx
/data/nginx
└── proyxcache
    └── d
        └── 8
            └── 0
                └── 1b2939146b393f2cb2c4be06c38ea08d    //实现缓存

4 directories, 1 file
缓存功能.png

扩展知识:清理缓存

  • 方法1: rm -rf 缓存目录
  • 方法2: 第三方扩展模块ngx_cache_purge

添加首部字段

nginx基于模块ngx_http_headers_module可以实现对后端服务器响应给客户端的报文中添加指定的响应首部字段。

添加响应报文的自定义首部:
add_header name value [always]; 

例:
add_header X-Via   $server_addr;            //当前nginx主机的IP
add_header X-Cache $upstream_cache_status;  //是否缓存命中
add_header X-Accel $server_name;            //客户访问的FQDN

示例:

[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf 
server  {
listen 80;
server_name  www.pc.com;
root  /data/html;
        proxy_cache proxycache;
        proxy_cache_key $request_uri;
        proxy_cache_valid 200 302 301 10m;
        proxy_cache_valid any 5m;
add_header class ky36;                     //添加首部字段
add_header X-Via $server_addr;             //当前nginx主机的IP
add_header X-Cache $upstream_cache_status; //是否缓存命中
add_header X-Accel $server_name;           //客户访问的FQDN
   location /api {
   proxy_pass http://192.168.204.30/;
   }
   location ~* \.(jpg|png|bmp|gif)$ {
   proxy_pass http://192.168.204.20;
   }
}
[root@node1 ~]#  nginx -s reload

[root@localhost ~]#  curl 192.168.204.10/fast.jpg -I
命中缓存.png

3.4 IP透传

用apache实现单层ip透传

ip透传示意图.png

7-1 代理服务器:192.168.204.10
7-3 真实服务器:192.168.204.30
7-4 客户端:192.168.204.40

`修改配置前,客户端访问代理服务器,真实服务器的日志中不会显示客户端ip`
[root@localhost ~]#  curl 192.168.204.10/api    //访问代理服务器
7-3 dongtaifuwuqi

[root@node2 html]#  tail -f /var/log/httpd/access_log   //查看真实服务器日志
...............
192.168.204.10 - - [09/Jun/2024:18:02:57 +0800] "GET / HTTP/1.0" 200 18 "-" "curl/7.29.0"
//显示的是7-1代理服务器的ip地址192.168.204.10
`修改配置,当客户端访问代理服务器,使真实服务器的日志中显示客户端ip`

`7-1 代理服务器:`
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf 

server  {
listen 80;
server_name  www.pc.com;
root  /data/html;
proxy_set_header cxk $remote_addr;    //远程ip地址传给cxk
   location /api {
   proxy_pass http://192.168.204.30/;
   }
   location ~* \.(jpg|png|bmp|gif)$ {
   proxy_pass http://192.168.204.20;
   }
}

[root@node1 ~]#  vim /apps/nginx -s reload



`7-3 真实服务器:`
[root@node3 ~]#  vim /etc/httpd/conf/httpd.conf    //修改日志格式
 LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"\"%{cxk}i\"" combined
 LogFormat "%h %l %u %t \"%r\" %>s %b" common
[root@node3 ~]#  systemctl restart httpd

[root@node3 html]#  tail -f /var/log/httpd/access_log  //查看真实服务器日志
..............
192.168.204.10 - - [09/Jun/2024:18:23:33 +0800] "GET / HTTP/1.0" 200 18 "-" "curl/7.29.0""192.168.204.40"
//会显示的是7-4客户端的ip地址192.168.204.40

IP透传.png

用nginx实现多层ip透传

ip多层透传nginx.png

7-1 代理服务器:192.168.204.10
7-2 代理服务器:192.168.204.20
7-3 真实服务器:192.168.204.30
7-4 客户端:192.168.204.40
nginx不需要修改日志格式,自带变量
X-Forwarded-For如果为空就是$remote_addr,有值那么就追加新的$remote_addr

`7-1 代理服务器:`
[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf 
server  {
listen 80;
server_name  www.pc.com;
root  /data/html;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   location /api {
   proxy_pass http://192.168.204.20/;
   }
}
[root@node1 ~]#  nginx -s reload


`7-2 代理服务器:`
[root@node2 ~]#  yum install nginx -y
[root@node2 ~]#  systemctl start nginx
[root@node2 ~]#  vim /etc/nginx/nginx.conf

location / {
      proxy_pass http://192.168.204.30;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      }

[root@node2 ~]#  nginx -s reload


`7-3 真实服务器:`
[root@node3 ~]#  yum install nginx -y
[root@node3 ~]#  systemctl start nginx
[root@node3 ~]#  cd /usr/share/nginx/html/
[root@node3 html]#  ls
404.html  50x.html  en-US  icons  img  index.html  nginx-logo.png  poweredby.png
[root@node3 html]#  echo "7-3 7-3" > index.html


`验证:`
[root@localhost ~]#  curl 192.168.204.10/api   //客户端进行访问
7-3 7-3
[root@node3 html]#  tail -f /var/log/nginx/access.log 
192.168.204.20 - - [09/Jun/2024:19:34:44 +0800] "GET / HTTP/1.0" 200 8 "-" "curl/7.29.0" "192.168.204.40, 192.168.204.10"

4. 负载均衡

Nginx 可以基于ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能。

官方文档:nginx.org/en/docs/htt…

算法

nginx 代理服务器的 调度算法:

  1. 轮询:一人一次
  2. 加权轮询:根据权重 分配次数
  3. hash算法
    • ip hash :根据ip地址来决定客户端访问的服务器
    • url hash :根据客户端访问的url来决定访问的服务器
    • cookie hash :根据cookie的值来决定访问的服务器
    • 一致性 hash
  4. 最小连接算法
  5. fair算法:根据响应时间来进行分配

示例1:轮询

轮询:默认一人一次

7-1192.168.204.10
7-2192.168.204.20
7-3192.168.204.30


`7-2:`
[root@node2 ~]#  yum install httpd -y
[root@node2 ~]#  systemctl start httpd
[root@node2 ~]#  cd /var/www/html/
[root@node2 html]#  ls
[root@node2 html]#  echo  222222  > index.html   //生成页面


`7-3:`
[root@node3 ~]#  yum install httpd -y
[root@node3 ~]#  systemctl start httpd
[root@node3 ~]#  cd /var/www/html/
[root@node3 html]#  ls
[root@node3 html]#  echo  333333  > index.html   //生成页面


`7-1:`
[root@node1 ~]#  vim /apps/nginx/conf/nginx.conf //编辑主配置文件
http {
    include       mime.types;
    upstream  web {           //自定义一组服务器,配置在http块内
    server 192.168.204.20;
    server 192.168.204.30;
    }  
    [root@node1 ~]#  nginx -s reload

[root@node1 ~]#  vim /apps/nginx/conf.d/pc.conf  //编辑子配置文件
server  {
listen 80;
server_name  www.pc.com;
root  /data/html;
  location / {
  proxy_pass http://web/;
  }
}
[root@node1 ~]#  nginx -s reload

客户端访问192.168.204.10进行验证
初级负载均衡.png

nginx 具有后端服务器健康检查功能,能检测到后端服务器是否活着。如果7-2挂掉,会全部调度到7-3。

示例2:加权轮询

加权轮询:根据权重 分配次数

[root@node1 ~]#  vim /apps/nginx/conf/nginx.conf
http {
    include       mime.types;
    upstream  web {
  server 192.168.204.20 weight=2;   //加权重
  server 192.168.204.30;
  }
[root@node1 ~]#  nginx -s reload

加权重:默认算法是轮询,一人一次;加了权重weight=2后次数比为21 ,但不是绝对的!
加权重2.png

示例3:hash算法——ip hash

根据ip地址来决定客户端访问的服务器

[root@node1 ~]#  vim /apps/nginx/conf/nginx.conf
http {
    include       mime.types;
  upstream  web {
  hash $remote_addr;      //ip hash
  server 192.168.204.20;         
  server 192.168.204.30;
  }
[root@node1 ~]#  nginx -s reload
ip hash.png

示例4:hash算法——url hash

根据客户端访问的url来决定访问的服务器

[root@node1 ~]#  vim /apps/nginx/conf/nginx.conf
http {
    include       mime.types;
  upstream  web {
  hash $request_uri;     //url hash  发请求的地址,一旦定下不会轻易改变
  server 192.168.204.20;
  server 192.168.204.30;
  }
[root@node1 ~]#  nginx -s reload

多生成文件
[root@node2 html]#  for i in {1..10};do echo 192.168.204.20 test$i > test$i.html;done
[root@node3 html]#  for i in {1..10};do echo 192.168.204.30 test$i > test$i.html;done
url hash.png

示例5:hash算法——cookie hash

根据cookie的值来决定访问的服务器

[root@node1 ~]#  vim /apps/nginx/conf/nginx.conf
http {
    include       mime.types;
  upstream  web {
  hash  $cookie_hello;   //cookie hash
  server 192.168.204.20;
  server 192.168.204.30;
  }
[root@node1 ~]#  nginx -s reload
cookie hash.png

5. 实现 Nginx tcp 负载均衡 四层

Nginx在1.9.0版本开始支持tcp模式的负载均衡,在1.9.13版本开始支持udp协议的负载,udp主要用于DNS的域名解析,其配置方式和指令和http 代理类似,其基于ngx_stream_proxy_module模块实现tcp负载,另外基于模块ngx_stream_upstream_module实现后端服务器分组转发、权重分配、状态监测、调度算法等高级功能。

官方文档:nginx.org/en/docs/str…

nginx.org/en/docs/str…

stream {      //定义stream相关的服务

   }
注意:stream块 与 http块 同级别

示例:redis

`7-2安装redis`
[root@node2 ~]#  yum install epel-release.noarch -y
[root@node2 ~]#  yum install redis -y
[root@node2 ~]#  vim /etc/redis.conf
[root@node2 ~]#  systemctl start redis
[root@node2 ~]#  redis-cli
127.0.0.1:6379> set name wyf
OK
127.0.0.1:6379> get name
"wyf"
127.0.0.1:6379> 


`7-3安装redis`
[root@node3 ~]#  yum install epel-release.noarch -y
[root@node3 ~]#  yum install redis -y
[root@node3 ~]#  vim /etc/redis.conf 
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 0.0.0.0
[root@node3 ~]#  systemctl start redis
[root@node3 ~]#  systemctl start redis
[root@node3 ~]#  redis-cli
127.0.0.1:6379> 
127.0.0.1:6379> set name cxk
OK
127.0.0.1:6379> get name
"cxk"
127.0.0.1:6379> 



`7-1 修改配置文件`
要在主配置文件里面进行修改,因为stream与http块同级
[root@node1 ~]#  vim /apps/nginx/conf/nginx.conf
stream {
upstream redis {
server 192.168.204.20:6379;
server 192.168.204.30:6379;
}
 server {
 listen 6379;
 proxy_pass redis;
 }
}
[root@node1 ~]#  nginx -s reload

[root@node1 ~]#  ss -natp |grep 6379
LISTEN     0      128          *:6379                     *:*                   users:(("nginx",pid=13240,fd=11),("nginx",pid=13239,fd=11),("nginx",pid=13238,fd=11),("nginx",pid=13237,fd=11),("nginx",pid=5339,fd=11))


`验证:`测试通过nginx负载连接redis
[root@node3 html]#  redis-cli -h 192.168.204.10
192.168.204.10:6379> get name
"wyf"
192.168.204.10:6379> 
[root@node3 html]#  redis-cli -h 192.168.204.10
192.168.204.10:6379> get name
"cxk"
192.168.204.10:6379>