Nginx 理论+实例超详细讲解

一、nginx简介

  • Nginx是一款轻量级的web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。
  • Nginx由俄罗斯的程序设计师lgor Sysoev所开发,最初供俄国大型的入口网站及搜寻引擎Rambler 使用。
  • 第一个公开版本0.1.0 发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4 发布。
  • nginx的特点是占有内存少,并发能力强,事实上 nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

二、nginx.的特性与优点

1、nginx特性

Nginx是一个很牛的高性能WEB和反向代理服务器,它具有很多非常优越的特性:
(1)在高连接并发情况下,nginx是apache服务器不错的替代品,能够支持高达5万个并发连接数的相应
(2)使用epoll and kqueue,作为开发模型
(3)Nginx作为负载均衡服务器: nginx既可以在内部直接支持和PHP程序对外进行服务,也可以支持作为HTTP代理服务器对外进行服务
(4)Nginx采用c进行编写,不论系统资源开销还是CPU使用效率都比Perlbal要好很多。

2、nginx的优点

(1)高并发连接:官方测试能够支撑5万并发连接,在实际生产环境中跑到2-3万并发连接数
(2) 内存消耗少:在3万并发连接下,开启的10 个nginx进程才消耗150M内存(15M*10=150M)
(3)配置文件非常简单:风格跟程序一样通俗易懂
(4)成本低廉: nginx为开源软件,可以免费使用。而购买F5 BIG-IP、NetScaler等硬件负载均衡交换机则需要十多万至几十万人民币
(5)支持 Rewrite重写规则:能够根据域名、URL的不同,将HTTP请求分到不同的后端服务器群组
(6) 内置的健康检查功能:如果Nginx Proxy后端的某台Web服务器宕机了,不会影响前端访问
(7)节省带宽:支持GZIP压缩,可以添加浏览器本地缓存的Header头
(8)稳定性高:用于反向代理,宕机的概率微乎其微
(9)模块化设计:模块可以动态编译
(10)外围支持好:文档全,二次开发和模块较多(11)支持热部署:可以不停机重载配置文件
(12)支持事件驱动、AlO (Asynclo,异步l0)、mmap ( Memory Map,内存映射)等性能优化

三、nginx的功能及应用类别

1、nginx的基本功能

(1)静态资源的web服务器,能缓存打开的文件描述符
(2 ) http、smtp、pop3协议的反向代理服务器
(3)缓存加速、负载均衡
(4)支持FastcGl(fpm,LNMP) ,uwSGl(Python)等
(5)模块化(非 DSo机制),过滤器zip、SSI及图像的大小调整
(6)支持SSL

2、nginx的扩展功能

(1)基于名称和IP的虚拟主机
(2)支持 keepalive
(3)支持平滑升级
(4)定制访问日志、支持使用日志缓冲区提高日志存储性能
(5)支持URL重写
(6)支持路径别名
(7)支持基于I及用户的访问控制
(8)支持速率限制,支持并发数限制

3、nginx的应用类别

(1)使用nginx结合FastcGl运行PHP、JSP、Perl等程序
(2)使用nginx_作反向代理、负载均衡、规则过滤
(3)使用nginx运行静态HTML网页、图片
(4) nginx与其他新技术的结合应用

四、nginx的模块与工作原理

  • nginx由内核和模块组成。其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block (location是nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作

1、nginx的模块分类

nginx的模块从结构上分为核心模块、基础模块和第三方模块

(1)HTTP模块、EVENT模块和MAIL模块等属于核心模块

(2)HTTP Access模块、HTTP FastCGl,模块、HTTP Proxy模块和HTTP Rewrite模块属于基本模块

(3)HTTP Upstream模块、Request Hash模块、Notice模块和HTTP Access Key模块属于第三方模块

  • 用户根据自己的需要开发的模块都属于第三方模块。正是有了如此多模块的支撑,nginx. 的功能才会如此强大

nginx模块从功能上分为三类,分别是:

(1)Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers 处理器模块一般只能有一个

(2)Filters(过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由nginx输出

(3)Proxies(代理器模块)。就是nginx的 HTTP Upstream之类的模块,这些模块主要与后端一些服务比如 fastcgi等操作交互,实现服务代理和负载均衡等功能

nginx模块分为:核心模块、事件模块、标准Http模块、可选 Http模块、邮件模块、第三方模块和补丁等

nginx,基本模块:所谓基本模块,指的是nginx默认的功能模块,它们提供的指令允许你使用定义nginx,基本功能的变量,在编译时不能被禁用,包括:

(1)核心模块:基本功能和指令,如进程管理和安全。常见的核心模块指令大部分是放置在配置文件的顶部

(2)事件模块:在 Nginx.内配置网络使用的能力。常见的events(事件)模块指令,=大部分是放置在配置文件的顶部

(3)配置模块:提供包含机制

2、nginx的工作原理

  • nginx.的模块直接被编译进nginx,因此属于静态编译方式。
  • 启动nginx后,nginx的模块被自动加载,与Apache不一样,首先将模块编译为一个so文件,然后在配置文件中指定是否进行加载。
  • 在解析配置文件时,nginx的每个模块都有可能去处理某个请求,但是同一个处理请求只能由一个模块来完成。
    nginx的进程架构:
  • 启动nginx时,会启动一个Master进程,这个进程不处理任何客户端的请求,主要用来产生worker线程,一个worker线程用来处理n个request。

1、Nginx进程模型
Nginx 默认采用多进程工作方式,Nginx启动后,会运行一个master进程和多个worker进程。其中master充当整个进程组与用户的交互接口,同时对进程进行监护,管理 worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。worker用来处理基本的网络事件,worker之间是平等的,他们共同竞争来处理来自客户端的请求。

在这里插入图片描述

在创建master进程时,先建立需要监听的socket(listenfd),然后从master进程中 fork()出多个worker进程,如此一来每个worker进程多可以监听用户请求的socket。一般来说,当一个连接进来后,所有在Worker都会收到通知,但是只有一个进程可以接受这个连接请求,其它的都失败,这是所谓的惊群现象。nginx,提供了一个accept_mutex (互斥锁),有了这把锁之后,同一时刻,就只会有一个进程在accpet,连接,这样就不会有惊群问题了。

先打开accept_mutex,选项,只有获得了accept_mutex的进程才会去添加accept事件。nginx.使用一个叫 ngx_accept_disabled 的变量来控制是否去竞争accept_mutex锁。ngx_accept_disabled = ngin…单进程的所有连接总数/ 8-空闲连接数量,当ngx_accept_disabled大于0时,不会去尝试获取accept_mutex锁,ngx_accept_disable越大,于是让出的机会就越多,这样其它进程获取锁的机会也就越大。不去 accept,每个worker进程的连接数就控制下来了,其它进程的连接池就会得到利用,这样,nginx,就控制了多进程间连接的平衡。

每个worker进程都有一个独立的连接池,连接池的大小是worker_connections。这里的连接池里面保存的其实不是真实的连接,它只是一个worker_connections大小的一个ngx_connection_t结构的数组。并且,nginx,会通过一个链表free_connections来保存所有的空闲ngx_connection_t,每次获取一个连接时,就从空闲连接链表中获取一个,用完后,再放回空闲连接链表里面。一个nginx…能建立的最大连接数,应该是worker_connections * worker_processes。当然,这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/2。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。

五、nginx源码安装

环境准备
配置好镜像源和关闭防火墙

[root@localhost ~]# ls /etc/yum.repos.d/
CentOS-Base.repo   epel.repo                  epel-testing.repo
epel-modular.repo  epel-testing-modular.repo


创建系统用户
[root@localhost ~]# useradd -rMs /sbin/nologin nginx
[root@localhost ~]# id nginx 
uid=995(nginx) gid=992(nginx) groups=992(nginx)


安装开发工具包
[root@localhost ~]# yum -y groups mark install 'Development Tools'


创建日志存放路径
[root@localhost ~]# mkdir /var/log/nginx
[root@localhost ~]# chown -R nginx.nginx /var/log/nginx/
[root@localhost ~]# ll -d /var/log/nginx/
drwxr-xr-x. 2 nginx nginx 6 Oct 10 16:56 /var/log/nginx/

安装nginx

[root@localhost ~]# wget http://nginx.org/download/nginx-1.20.2.tar.gz
--2022-10-10 17:04:05--  http://nginx.org/download/nginx-1.20.2.tar.gz
Resolving nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05:d014:edb:5702::6, ...
Connecting to nginx.org (nginx.org)|3.125.197.172|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1062124 (1.0M) [application/octet-stream]
Saving to: ‘nginx-1.20.2.tar.gz’

nginx-1.20.2.tar.gz 100%[=================>]   1.01M   229KB/s    in 6.9s    

2022-10-10 17:04:13 (150 KB/s) - ‘nginx-1.20.2.tar.gz’ saved [1062124/1062124]

[root@localhost ~]# ls
anaconda-ks.cfg  nginx-1.20.2.tar.gz
[root@localhost ~]# tar -zxf nginx-1.20.2.tar.gz -C /usr/src/

预编译
[root@localhost nginx-1.20.2]# cd /usr/local/nginx-1.20.2/
./configure \
--prefix=/usr/local/nginx \
--user=nginx 
--group=nginx \
--with-debug \
--with-http_ssl_module \
--with-http _realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log
[root@localhost nginx-1.20.2]# make
[root@localhost nginx-1.20.2]# make install

配置环境变量以便启动nginx
[root@localhost nginx-1.20.2]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@localhost nginx-1.20.2]# . /etc/profile.d/nginx.sh 
[root@localhost nginx-1.20.2]# nginx
[root@localhost nginx-1.20.2]# ss -antl
State   Recv-Q  Send-Q     Local Address:Port     Peer Address:Port  Process  
LISTEN  0       128              0.0.0.0:22            0.0.0.0:*              
LISTEN  0       128              0.0.0.0:80            0.0.0.0:*              
LISTEN  0       128                 [::]:22               [::]:*    

//启动nginx,并查看端口情况服务控制方式,使用nginx命令
-t 检查配置文件语法
-v 输出nginx的版本
-c 指定配置文件路径
-s 发送服务控制信号,可选值有stop、auit、reopen、reload

六、配置文件详解

主配置文件:/usr/local/nginx/nginx.conf
默认启动nginx时,使用的配置文件是:安装路径/conf/nginx.conf
可以在启动nginx时通过-c选项来指定要读取的配置文件
//nginx常见的配置文件及其作用
nginx.conf nginx的基本配置文件
mime.types MIME类型关联的扩展文件
fastcgi.conf 与fastcgi相关的配置
proxy.conf 与proxy相关的配置
sites.conf 配置nginx,提供的网站,包括虚拟主机

七、部署lnmp机构

以下PHP-MySQL都是源码安装,可以参考之前我写的
MySQL安装

1、 MySQL操作

[root@my ~]# ss -antl | grep 3306
LISTEN 0      80                 *:3306            *:*   

2、php端操作

PHP配置
部署成功后在配置以下内容

[root@node1 php-fpm.d]# pwd
/usr/local/php7/etc/php-fpm.d
listen = 0.0.0.0:9000
listen.allowed_clients = 192.168.47.137
[root@node1 php-fpm.d]# ss -antl | grep 9000
LISTEN 0      128               0.0.0.0:9000      0.0.0.0:*  


网页测试目录
[root@node1 php-fpm.d]# mkdir /var/www/html -p
[root@node1 php-fpm.d]# cd /var/www/html/
[root@node1 html]# ls
[root@node1 html]# vim index.php
[root@node1 html]# useradd -Mrs /sbin/nologin nginx
[root@node1 html]# id nginx 
uid=975(nginx) gid=974(nginx) groups=974(nginx)
[root@node1 html]# chown -R nginx.nginx /var/www/html/
[root@node1 html]# ll
total 4
-rw-r--r-- 1 nginx nginx 21 Oct 11 19:02 index.php

3、nginx操作

[root@localhost conf]# cd /usr/local/nginx/conf
[root@localhost conf]# vim nginx.conf
location / {
            root    html;
            index  index.php index.html index.htm;
        }
   location ~ \.php$ {
            root           /var/www/html;
            fastcgi_pass   192.168.47.50:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /var/www/html/$fastcgi_script_name;
            include        fastcgi_params;
        }


拿nginxip访问
[root@localhost conf]# ss -antl | grep 80
LISTEN 0      128          0.0.0.0:80        0.0.0.0:* 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3YrgFFHM-1666171360698)(./1665487107955.png)]

八、平滑升级

//平滑升级的步骤
1、获取之前的编译参数
2、下载新模块
3、重新编译软件,加上–add-module=新模块的解压路径
4、停止服务并备份原程序
5、把源程序用新程序覆盖
6、启动新程序

1、基于之前部署的nginx

确保网页可以访问,使用自己的手机热点和其他设备即可
[https://github.com/openresty/echo-nginx-module]

下载到本地

[root@localhost ~]# wget https://github.com/openresty/echo-nginx-module
解压
[root@localhost ~]# unzip echo-nginx-module-master.zip 

2、获取之前安装nginx的编译参数
这里nginx软件包推荐使用nginx-1.20.0版本

查看自己原来二进制安装的nginx模块,复制一下

[root@localhost ~]# nginx -V
nginx version: nginx/1.20.0
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC) 
built with OpenSSL 1.1.1k  FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log


重新压缩一份nginx
[root@localhost ~]# tar -zxf nginx-1.20.0.tar.gz 


重新预编译软件
[root@localhost nginx-1.20.0]# ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-debug \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log \
--add-module=../echo-nginx-module-master

//添加成功
[root@localhost nginx-1.20.0]# make
sed -e "s|%%PREFIX%%|/usr/local/nginx|" \
	-e "s|%%PID_PATH%%|/usr/local/nginx/logs/nginx.pid|" \
	-e "s|%%CONF_PATH%%|/usr/local/nginx/conf/nginx.conf|" \
	-e "s|%%ERROR_LOG_PATH%%|/var/log/nginx/error.log|" \
	< man/nginx.8 > objs/nginx.8
make[1]: Leaving directory '/root/nginx-1.20.0'

objs目录以有nginx这个可执行程序
[root@localhost nginx-1.20.0]# cd objs/
[root@localhost objs]# ls
addon         Makefile  nginx.8            ngx_auto_headers.h  ngx_modules.o
autoconf.err  nginx     ngx_auto_config.h  ngx_modules.c       src

3、备份源程序并停止、覆盖、启动服务
//先查看升级前和升级后的版本区别,主要看编译参数
//升级前

[root@localhost nginx-1.20.0]# objs/nginx -V
nginx version: nginx/1.20.0
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC) 
built with OpenSSL 1.1.1k  FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=../echo-nginx-module-master


重新停止启动下nginx,以便程序识别
[root@localhost nginx-1.20.0]# nginx -s stop
将其原有的程序备份到/opt下
[root@localhost nginx-1.20.0]# cp /usr/local/nginx/sbin/nginx /opt/
在用新的版本覆盖掉旧的版本
[root@localhost nginx-1.20.0]# cp objs/nginx /usr/local/nginx/sbin/
cp: overwrite '/usr/local/nginx/sbin/nginx'? 
[root@localhost nginx-1.20.0]# /usr/local/nginx
nginx/        nginx-1.20.2/ 
[root@localhost nginx-1.20.0]# /usr/local/nginx/sbin/nginx 
[root@localhost nginx-1.20.0]# ss -antl
State      Recv-Q     Send-Q         Local Address:Port           Peer Address:Port     Process     
LISTEN     0          128                  0.0.0.0:22                  0.0.0.0:*                    
LISTEN     0          128                  0.0.0.0:80                  0.0.0.0:*    
[root@localhost nginx-1.20.0]# nginx -V
nginx version: nginx/1.20.0
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC) 
built with OpenSSL 1.1.1k  FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=/root/echo-nginx-module-master

4、测试–引用echo模块

  #access_log  logs/host.access.log  main;

        location / {
                echo "good time";
        }

可以使用windos系统中的cmd进行
C:\Users\goodtime>curl 192.168.47.137
good time

九、location案例

location区段,通过指定模式来与客户端请求的URI相匹配
功能:
允许根据用户请求的URI来匹配定义的各个location,匹配时,此请求将被相应的location配置块中的配置所处理,例如做访问控制等功能
语法:
location [修饰符] pattern {…}
修饰符
= 精确匹配
~ 正则表达式模式匹配,区分大小写
~* 正则表达式模式匹配,不区分大小写
^~ 前缀匹配,类似于无修饰符的行为,也是以指定模块开始,不同的是,如果模式匹配,那么就停止搜索其他模式了,不支持正则表达式
@ 定义命名location区段,这些区段客户端不能访问,只可以由内部产生的请求来访问,如try_files或者error_page等

1、定义一个测试字段

[root@localhost sbin]# vim /usr/local/nginx/conf/nginx.conf
   location /hhh {
                echo "good time";
        }
[root@localhost sbin]# ./nginx -s reload

//可见不按添加的字段访问的话显示不了输出值
C:\Users\goodtime>curl 192.168.47.137
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

C:\Users\goodtime>curl 192.168.47.137/hhh
good time

2、= 精确匹配
//如果输出别的就报错

C:\Users\goodtime>curl 192.168.47.137 /hhh
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

3、 ~ 区分大小写,且以绝对路径为搜索(只要在里面即可)

C:\Users\goodtime>curl 192.168.47.137/hhH
<html>
<head><title>404 Not Found</title></head>
//后面可以加任意的数值
C:\Users\goodtime>curl 192.168.47.137/hhhdadadawqeqw
good time

4、 ~* 不区分大小写

C:\Users\goodtime>curl 192.168.47.137/hHh
good time

5、^~ 以数值开头的部分匹配

C:\Users\goodtime>curl 192.168.47.137/hhh
good time

优先级顺序,这里如果一切添加到里面的话按优先级顺序来匹配规则

查找顺序和优先级:由高到低
1、带有“=”的精确匹配优先
2、正则表达式按照他们在配置文件中定义的顺序
3、带有“^~”修饰符的,开头匹配
4、带有或者*修饰符的,如果正则表达式与URI匹配
5、没有修饰符的精确匹配

location = 路径
location ^~ 路径
location ~ 正则(例如/hhh的后面需要添加$,以这个为结尾)
location ~* 正则
location 路径

1 =
2 ^~
3 ~*
4 ~
5 无数

十、nginx访问控制

//用于location段
Allow:设定允许哪台或哪些主机访问,多个参数间用空格隔开
Deny:设定禁止那台或哪些主机访问,多个参数间用空格隔开
比如:
allow 192.168.47.137 192.168.47.136;等
deny all;

//本地cmd系统中查看ip

C:\Users\goodtime>ipconfig
以太网适配器 VMware Network Adapter VMnet8:

   连接特定的 DNS 后缀 . . . . . . . :
   本地链接 IPv6 地址. . . . . . . . : fe80::70bb:164a:9969:5e53%21
   IPv4 地址 . . . . . . . . . . . . : 192.168.47.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0

模拟拒绝本机访问nginx状态页面
         location /status {
                echo "chenyu";
                deny 192.168.47.1;           //本机ip


C:\Users\goodtime>curl 192.168.47.137/status
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.20.2</center>
</body>
</html>

//开启stub_status模块

stub_status模块主要作用于查看nginx的一些状态信息
         location /status {
                stub_status on;
		}


状态
C:\Users\goodtime>curl 192.168.47.137/status
Active connections: 1
server accepts handled requests
 8 8 6
Reading: 0 Writing: 1 Waiting: 0

解析:
Active connections:当前nginx正在处理的活动连接数
Server accepts handled requests:nginx总共处理了63个连接,成功创建63次握手,总共处理了62个请求
Reading:nginx读取到客户端的Header信息数
Writing:nginx返回给客户端的Header信息数
Waiting:开启keep-alive的情况下,这个值等于active-(reading+writing),意思就是nginx已经处理完成,正在等候下一次请求指令的驻留连接。所以,在访问效率高、请求很快就被处理完毕的情况下,waiting数比较多是正常的。如果reading+writing数较多,则>说明并发访问量非常大,正在处理过程中。

//当allow all存在时,允许其他ip访问

   location /status {
                stub_status on;
                allow 192.168.47.1;
                allow all;
        }


测试,本机成功
C:\Users\goodtime>curl 192.168.47.137/status
Active connections: 1
server accepts handled requests
 8 8 8
Reading: 0 Writing: 1 Waiting: 0


模拟在另一台虚拟机网页中访问主机ip
[root@my ~]# ip a | grep ens32
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc _codel state UP group default qlen 1000
    inet 192.168.47.136/24 brd 192.168.47.255 scope global noprefixroute ens32


可以ping通nginx主机
[root@my ~]# ping 192.168.47.137
PING 192.168.47.137 (192.168.47.137) 56(84) bytes of data.
64 bytes from 192.168.47.137: icmp_seq=1 ttl=64 time=0.408 ms


[root@my ~]# curl 192.168.47.137/status
Active connections: 1 
server accepts handled requests
 13 13 13 
Reading: 0 Writing: 1 Waiting: 0 



当添加deny后
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf



location /status {
                stub_status on;
                allow 192.168.47.1;
                deny all;
        }
[root@localhost ~]# nginx -s reload


失败
[root@my ~]# curl 192.168.47.137/status
<html>
<head><title>403 Forbidden</title></head>


在测试添加136访问
allow 192.168.47.136;
[root@localhost ~]# nginx -s reload
//成功
[root@my ~]# curl 192.168.47.137/status
Active connections: 1 
server accepts handled requests
 16 16 16 
Reading: 0 Writing: 1 Waiting: 0 

1、用户认证加密模式

为虚拟机用户添加一组加密信息,这样在登录虚拟机界面时候会让其输入加密密码,保证其安全性

//授权用户
安装httpd-tools软件包
[root@localhost ~]# yum -y install httpd-tools


//创建用户密钥文件
[root@localhost ~]# cd /usr/local/nginx/conf/
//这里的密码为加密后的密码串,建议用htpasswd来创建文件,这里创建的jr用户是不存在系统中的
[root@localhost conf]# htpasswd -c -m .user_auth_file jr
New password: 
Re-type new password: 
Adding password for user jr
//密码信息
[root@localhost conf]# cat .user_auth_file 
jr:$apr1$ma8B3sAP$r24RhqreiU0O2pqBLnUNq/

//配置nginx(注意auth_basic_user_file必须用绝对路径)
[root@localhost conf]# vim nginx.conf
[root@localhost conf]# nginx -s reload
  location /status {
                stub_status on;
                auth_basic "欢迎光临";
                auth_basic_user_file "/usr/local/nginx/conf/.user_auth_file";
        }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d9SvLFy5-1666173270394)(./1665654224926.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZYogn81M-1666173270395)(./1665654235330.png)]

2、https配置

Nginx:192.168.47.137
CA:192.168.47.136

//在CA服务器中生成一对密钥

[root@CA ~]# mkdir  -p  /etc/pki/CA/private
[root@CA ~]# cd /etc/pki/CA/
//生成私钥
[root@CA CA]# (umask 077;openssl genrsa -out private/cakey.pem 2048)
Generating RSA private key, 2048 bit long modulus (2 primes)
.....+++++
...........+++++
e is 65537 (0x010001)
//生成公钥
[root@CA CA]# openssl rsa -in private/cakey.pem -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuQfU9CLxicvy7XggXSSB
KJp/6VrVd6iHqG8Rfv89kx0X/AOXPKFHrTDiDj1fxwTNDOhPNSTXXVybxgjAdfXT
03DmbgFYoXp6C+SqeetdiDD3NbIBRJjyFb5bgXXt0Se11vN0oDPzp6PowRH+VhFI
gfsvdjpMvaDmuEoYwnefA5SjP4gO4i0CNdu8PSy/JFgXz7NGinp4Eiqxt5Ljtthj
IljqH6yIbuYoao2oW0GrPfFe5hhkKu8cXredNhFD5uz9HJU/ziwPecVqo88FC2af
8GtQCfBGRTewqkoTcLLoIsPum58aVvomnF0t5IU0hcpGl7jlqndk6dnBlqGNTrOp
OwIDAQAB
-----END PUBLIC KEY-----
生成自属签名颁发证书,并导入到cacert.pem中
[root@CA CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 1024
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HB
Locality Name (eg, city) [Default City]:WH
Organization Name (eg, company) [Default Company Ltd]:HH^H
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:LL
Email Address []:[email protected]

//在nginix中生成证书签署请求,发送给CA

[root@localhost ~]# cd /usr/local/nginx/conf/
//生成私钥
[root@localhost conf]# (umask 077;openssl genrsa -out httpd.key 2048)
Generating RSA private key, 2048 bit long modulus (2 primes)
......+++++
...................................+++++
e is 65537 (0x010001)
//在生成一个请求,保持一个合同同步允许确认证书通过
[root@localhost conf]# openssl req -new -key httpd.key -days 1024 -out httpd.csr
Ignoring -days; not generating a certificate
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HB
Locality Name (eg, city) [Default City]:WH
Organization Name (eg, company) [Default Company Ltd]:HH^H
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:LL
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@localhost conf]# ls
httpd.csr        httpd.key
//发送证书             
[root@localhost conf]# scp httpd.csr [email protected]:/root/
[email protected]'s password: 
httpd.csr                                       100% 1017   723.0KB/s   00:00  

//在CA主机中查看

[root@CA ~]# ls
anaconda-ks.cfg  httpd.csr
//CA签署证书并发送给NGINX
[root@CA ~]# mkdir /etc/pki/CA/newcerts          //将来颁发证书的存放路径
[root@CA ~]# touch /etc/pki/CA/index.txt          //网页数据显示
[root@CA ~]# echo "01" > /etc/pki/CA/serial       //设置序列号
//重新对证书进行签名,并生成httpd.crt
[root@CA ~]#  openssl ca -in httpd.csr -out httpd.crt -days 1024
Using configuration from /etc/pki/tls/openssl.cnf 
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Oct 13 09:50:22 2022 GMT
            Not After : Aug  2 09:50:22 2025 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = HB
            organizationName          = HH\08
            organizationalUnitName    = linux
            commonName                = LL
            emailAddress              = [email protected]
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                B9:E3:DC:E2:75:93:5A:8C:82:FD:80:30:75:99:CC:C5:5A:95:3B:56
            X509v3 Authority Key Identifier: 
                keyid:2C:A2:DB:98:54:06:EB:2D:24:A8:84:E4:8E:71:36:D0:70:88:BC:2D

Certificate is to be certified until Aug  2 09:50:22 2025 GMT (1024 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
[root@CA ~]# ls
anaconda-ks.cfg  httpd.crt  httpd.csr



//将CA签署的证书httpd.crt和服务器的证书cacert.pem(密钥信息)发送给nginx
[root@CA ~]# scp httpd.crt [email protected]:/usr/local/nginx/conf/ 
The authenticity of host '192.168.47.137 (192.168.47.137)' can't be established.
ECDSA key fingerprint is SHA256:cdmo9f87/nd53T0zrSlRNvEDKskgEb2tSwNZINSW84U.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.47.137' (ECDSA) to the list of known hosts.
[email protected]'s password: 
httpd.crt                                              100% 4517     2.8MB/s   00:00    
[root@CA ~]# scp /etc/pki/CA/[email protected]:/usr/local/nginx/conf/
[email protected]'s password: 
cacert.pem                                             100% 1367     1.4MB/s   00:00 

//nginx配置https

[root@localhost conf]# vim /usr/local/nginx/conf/nginx.conf
 server {
        listen       443 ssl;                      //监听443加密
        server_name  localhost;
        ssl_certificate httpd.crt;              //证书位置
        ssl_certificate_key httpd.key;          //私钥信息
        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;
        }

[root@localhost conf]# nginx -s reload
[root@localhost html]# echo "jrhh" > index.html 
[root@localhost html]# nginx -s reload

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZdGh5n1t-1666173270395)(./1665654999590.png)]

十一、Rewrite重定向

和apache等web服务软件一样,rewrite的主要功能是实现URL地址的重定向。Nginx的rewrite功能需要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持rewrite的模块,但是也必须要PCRE的支持

Rewirte功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。

Rewrite只能放在server{},location{},if{}中,并且默认只能对域名后边的除去传递参数外的字符串起作用。例如http://www.cy.com/abc/aa/index.php?a=1&b=2 只对/abc/aa/index.php重写

URL:就是具体路径/位置
URI:指的是一个拥有相同类型/特性的对象集合
URL地址俗称网页地址,简称网址,是用于完整地描述Internet上网页和其他资源地址的字符串
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uDhliX2-1666173614317)(./1665804328382.png)]
Nginx:通过ngx_http_rewrite_module模块支持URL重写,支持if条件判断,但不支持else。
跳转:从一个location跳转到另一个location,循环最多可以执行10次,超过后nginx将返回500错误。
PCRE支持:perl兼容正则表达式的语法规则匹配
重写模块set指令:创建新的变量并设其值

//语法格式:
rewrite [flag];
regex:表示正则匹配规则
replacement:表示跳转后的内容
flag:表示rewrite支持的flag标记

//flag标记说明:
last:本条规则匹配完成后,继续向下匹配新的location URL规则,一般用在server和if中。
break:本条规则匹配完成即终止,不在匹配后面的任何规则,一般使用在location中。
redirect:返回302临时重定向代表临时跳转,当用户访问一个页面时,服务器会返回一个302状态码,告诉浏览器该页面已被重定向。就必须手动地将浏览器重定向到新的URL上,浏览器地址会显示跳转后的URL地址
permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址。

匹配正则的标识符和意义
^ 必须以^后的实体开头
$ 必须以$前的实体结尾
. 匹配任意单个字符
[] 匹配指定字符集的任意字符
[^] 匹配任何不包括在指定字符集内的任意字符串
| 匹配|之前或之后的实体
() 分组,组成一组用于匹配的实体,通常会有|来协助
\ 转义

  • *** 匹配前面的字符出现零次或者多次,如“ab*”能匹配a、ab、abb
  • +\ 匹配前面的字符出现一次或者多次,如“ab+”能匹配ab、abb,但是不能匹配a
  • ? 匹配前面的字符出现零次或者一次,如“ab(cd)?”能匹配ab、abcd

(pattern) 匹配括号内pattern并可以在后面获取对应的匹配,常用$0-9 属性获取小括号中匹配的内容。 如 ( h e l l o ∣ c h e n y u ) 9属性获取小括号中匹配的内容。如^(hello | chenyu)9属性获取小括号中匹配的内容。如(hell**ocheny**u) //字符串为“hello chenyu”,可以捕获的结果为:
$1=hello$2=chenyu 这些被捕获的数据,在后面就可以当作变量一样进行使用了

nginx的rewrite功能在企业里应用非常广泛
1、可以调整用户浏览的URL,看起来更规范,合乎开发及产品人员的需求
2、为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态的URL地址伪装成静态地址提供服务
3、网址更新域名后,让旧的访问跳转到新的域名上,例如访问京东的360buy.com会跳转到jd.com
4、根据特殊变量、目录、客户端的信息进行URL调整等。

1、rewrite配置

//nginx访问小李子自定义网页

[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# ls
50x.html  index.html
[root@localhost html]# mkdir imgs
[root@localhost html]# cd imgs/
[root@localhost images]# ls
xlz.jpg
[root@localhost imgs]# vim /usr/local/nginx/conf/nginx.conf
location = /imgs {
        }
[root@localhost imgs]# nginx -s reload

确实帅!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6vnYmRkc-1666173614318)(./1665755821173.png)]

2、flag标记–break

break:本条规则匹配完成即终止,不在匹配后面的任何规则,一般使用在location中。
//需要写rewrite
//网页的绝对路径是/images/,但做一个变量就不同了

[root@localhost html]# vim /usr/local/nginx/conf/nginx.conf
  location = /imgs {
                rewrite ^/imgs/(.*\.jpg)$ /images/$1 break;       //$定义正则表达式访问网页
        }

[root@localhost images]# nginx -s reload

访问的依旧是imgs
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-76R9cQi1-1666173614318)(./1665757889785.png)]

//还可以使用break,让我们访问得站点跳转到百度得首页
location /imgs {
rewrite ^/imgs/(.*.jpg)$ http://www.baidu.com break;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BHEbskjA-1666173614319)(./1665758229034.png)]

3、flag标记-last

last:本条规则匹配完成后,继续向下匹配新的location URL规则,一般用在server和if中。
//匹配多个数值,跳转到免费听歌网站中(分享)

[root@localhost html]# vim /usr/local/nginx/conf/nginx.conf
   location /imgs {
                rewrite ^/imgs/(.*\.jpg)$ /images/$1 last;
        }
        location /images {
                rewrite ^/images/(.*\.jpg)$ https://music.y444.cn/#/ last;
        }

[root@localhost html]# nginx -s reload

//可以用来一边学习一边听jay的歌
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6G2xvbLN-1666173614319)(./1665758631629.png)]

4、flag标记–redirect

redirect:返回302临时重定向代表临时跳转,当用户访问一个页面时,服务器会返回一个302状态码,告诉浏览器该页面已被重定向。就必须手动地将浏览器重定向到新的URL上,浏览器地址会显示跳转后的URL地址

   location /imgs {
                rewrite ^/imgs/(.*\.jpg)$ /images/$1 redirect;
        }

//按F12进行状态监测
F5刷新网页
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x4xiivh4-1666173614320)(./1665759378483.png)]

5、flag标记–permanent

返回301永久重定向,浏览器地址栏会显示跳转后的URL地址。

[root@localhost html]# vim /usr/local/nginx/conf/nginx.conf

       location /imgs {
                rewrite ^/imgs/(.*\.jpg)$ /images/$1 permanent;
        }
[root@localhost html]# nginx -s reload

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U7rcwXuZ-1666173614320)(./1665759612819.png)]

6、if判断

可以使用在server段和location段
语法:
if (condition) {…}
常见的condition:
(1)变量名
(2)以变量名为操作数构成的比较表达式(可使用=,!=类似的比较符进行测试)
(3)正则表达式的模式匹配操作

  • ~ 区分大小写的模式匹配检查
  • ~* 不区分大小写的模式检查
    (4)测试指定路径为文件的可能性(-f !-f)
    (5)测试指定路径为目录的可能性(-d !-d)
    (6)测试文件的存在性(-e !-e)
    (7)检查文件是否有执行权限(-x !-x)

6.1、配置基于域名跳转

假如现在公司旧的域名www.lty.com有业务需求,需要使用新的域名www.liutianyang.com代替,但是旧域名不能废除,需要跳转到新的域名上,而且后面的参数保持不变
//修改nginx服务器主机名为www.lty.com

[root@localhost html]# hostnamectl set-hostname www.lty.com
[root@localhost html]# bash
[root@www html]# 

//将本机两个域名映射关系写入到/etc/hosts中,并传给客户端
[root@localhost html]# vim /etc/hosts 
192.168.47.137 www.lty.com
192.168.47.137 www.liutianyang.comm
[root@localhost html]# scp /etc/hosts [email protected]:/etc/hosts
[email protected]'s password: 
hosts                                     100%  220    42.1KB/s   00:00 
//修改配置文件,写入rewrite和if结合使用
[root@www html]# vim /usr/local/nginx/conf/nginx.conf
  server {
        listen       80;
        server_name  www.lty.com;
        
       location / {
                if ($host = 'www.lty.com') {
                        rewrite ^/(.*)$ http://www.liutianuang.com/$1 permanent;
                }
                root html;
                index index.html index.htm;
      
[root@www html]# echo "This is a test" > /usr/local/nginx/html/index.html
[root@www html]# nginx -s reload

//客户端使用浏览器访问–http://www.lty.com—我们会发现自动跳转到新的域名www.liutianuang.com中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3FwBIWPO-1666173614321)(./1665798296829.png)]

6.2、基于客户端ip访问跳转

假如今天公司业务新版本上线,要求所有ip访问任何内容都显示一个固定维护页面,只有公司ip:192.168.47.50访问正常

[root@www html]# vim /usr/local/nginx/conf/nginx.conf
  server {
        listen       80;
        server_name  www.lty.com;
        set $rewrite true;                         //开启重写规则
        if ($remote_addr = "192.168.47.50") {          //如果判断等于对应的ip则成立
                set $rewrite false;                                   //关闭重写
        }

        if ($rewrite = true) {    //当变量判断是其他ip成立时
                rewrite (.+) /weihu.html;   //.+代表配合任何ip并以/网页状态显示
        }
[root@www html]# nginx -s reload
//新建/var/www/html目录,并往该目录下写入文件weihu.html,内容为weihu
[root@www html]# mkdir /var/www/html -p
[root@www html]# echo "in  weihuing" >  /var/www/html/weihu.html

验证:
50客户端访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XW38lcHj-1666173614322)(./1665799618879.png)]

137端访问
[root@www html]# curl http://www.lty.com
in weihuing

7、基于浏览器实现分离

//在/usr/local/nginx/html目录中创建如下目录和文件

[root@www html]# mkdir firefox chrome
[root@www html]# echo "firefox test" > firefox/index.html
[root@www html]# echo "chrome test" > chrome/index.html

//修改配置文件
[root@www html]# vim /usr/local/nginx/conf/nginx.conf
server {
        listen       80;
        server_name  localhost;


        location / {
                if ($http_user_agent ~ Firefox) {
                        rewrite ^(.*)$ /firefox/$1 break;
                }

                if ($http_user_agent ~ Chrome) {
                        rewrite ^(.*)$ /chrome/$1 break;
                }
                root html;
                index index.html index.htm;
        }

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location /firefox {
                root html;
                index index.html;
        }
        location /chrome {
                root html;
                index index.html;
        }
[root@www html]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@www html]# nginx -s reload

验证
1、chrome谷歌浏览器访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TAbbCnTo-1666173614322)(./1665801439953.png)]

2、Firefox浏览器访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4YElJ7Qq-1666173614323)(./1665801467016.png)]

十二、防盗链案例

了解防盗链的原理之前,我们得先学习一个HTTP的头信息Referer,当浏览器向web服务器发送请求的时候,一般都会带上Referer,来告诉浏览器该网页是从哪个页面链接过来的。

后台服务器可以根据获取到的这个Referer信息来判断是否为自己信任的网站地址,如果是则放行继续访问,如果不是则可以返回403(服务端拒绝访问)的状态信息。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vHETmPaF-1666173614324)(./1665801507579.png)]

语法:
valid_referers none blocked server_names string

  • none: 如果Header中的Referer为空,允许访问
  • blocked:在Header中的Referer不为空,但是该值被防火墙或代理进行伪装过,如不带"http://" 、"https://"等协议头的资源允许访问。
  • server_names:指定具体的域名或者IP
  • string: 可以支持正则表达式和*的字符串。如果是正则表达式,需要以~开头表示
    案例:
    //在/usr/local/nginx/html目录下创建abc目录,将一张图片到该目录下
[root@www html]# mkdir abc
[root@www html]# cd abc/
[root@www abc]# ls
悟蓝.png

[root@www abc]# vim /usr/local/nginx/conf/nginx.conf
  location ~* \.(jpg|png) {
                root html/abc;
        }
[root@www abc]# nginx -s reload

在这里插入图片描述

//使用命令查看referer信息,此时还未配置防盗链](https://img-blog.csdnimg.cn/a37ddec96be740919d774758e2c9ebaf.png)

[root@www abc]# curl --referer http://baidu.com -I http://192.168.47.137/悟 蓝.png
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Sat, 15 Oct 2022 02:57:12 GMT
Content-Type: image/png
Content-Length: 540902
Last-Modified: Sat, 15 Oct 2022 02:50:36 GMT
Connection: keep-alive
ETag: "634a1ffc-840e6"
Accept-Ranges: bytes

这里的状态也是没有标头的
![(img-qMmq8inY-1666173614326)(./1665802902479.png)]](https://img-blog.csdnimg.cn/37419da8250649189bf993c83695dd1c.png)

1、开始配置防盗链

[root@www html]# vim /usr/local/nginx/conf/nginx.conf
   location ~* \.(jpg|png) {                 //以~开始正则匹配(jpg|png)为结尾的后缀
                root html/abc;
                valid_referers  blocked www.cy.com;        //如果返回的头部referer为www.lty.com那么就不会执行valid_referer下面内容   
                if ($invalid_referer) {        //反之则会生成防盗链
                        return 403;
                        break;
                }
        }
[root@www html]# nginx -s reload

这里不用加none参数,这种形式的访问是直接请求服务器中默认html中的1.jpg文件,是没有头部的(只有二次以上请求才会有referer头部),并且我们在配置文件中添加了[none]这个参数,它的含义就是当我们在没有头部referer时,依然能访问到文件,所以我们配置的防盗链在这个时候是不起作用的。

验证:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p5p7e28C-1666173614327)(./1665804020215.png)]

[root@www html]# curl --referer http://baidu.com -I http://192.168.47.137/悟蓝.png
HTTP/1.1 403 Forbidden
Server: nginx/1.20.2
Date: Sat, 15 Oct 2022 03:19:57 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive

十三、反向代理和负载均衡

  1. nginx通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离以及负载均衡,从而大大提高服务器的处理能力。
  2. nginx实现动静分离,其实就是在反向代理的时候,如果是静态资源,就直接从nginx发布的路径去读取,而不需要从后台服务器获取了。
  3. 但是要注意,这种情况下需要保证后端跟前端的程序保持一致,可以使用Rsync做服务端自动同步或者使用NFS、MFS分布式共享存储。
    • Http Proxy模块,功能很多,最常用的是proxy_pass和proxy_cache
      如果要使用proxy_cache,需要集成第三方的ngx_cache_purge模块,用来清除指定的URL缓存。这个集成需要在安装nginx的时候去做,如:
      ./configure --add-module=…/ngx_cache_purge-1.0 …

1、什么是代理

说到代理,首先我们要明确一个概念,所谓代理就是一个代表、一个渠道;
此时就设计到两个角色,一个是被代理角色,一个是目标角色,被代理角色通过这个代理访问目标角色完成一些任务的过程称为代理操作过程;如同生活中的专卖店~客人到某达斯专卖店买了一双鞋,这个专卖店就是代理,被代理角色就是某达斯厂家,目标角色就是用户

2、正向代理

这样的代理模式称为正向代理,正向代理最大的特点是客户端非常明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;正向代理模式屏蔽或者隐藏了真实客户端信息。
blob:https://maxiang.io/34804c1c-8b3d-406f-9658-8923f38d07b0

3、反向代理

多个客户端给服务器发送的请求,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。此时~请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,nginx扮演的就是一个反向代理角色

反向代理,主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uj7OjlcK-1666168246998)(./1666151082692.png)]

//在实际生产项目中,大部分的就是正向代理和反向代理结合起来使用

我们在实际项目操作时,正向代理和反向代理很有可能会存在在一个应用场景中,正向代理代理客户端的请求去访问目标服务器,目标服务器是一个反向代理服务器,反向代理了多台真实的业务处理服务器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OUksK3Mh-1666168247000)(./1666151102613.png)]

4、负载均衡

  • nginx通过upstream模块来实现简单的负载均衡,upstream需要定义在http段内
  • weight轮询(默认):接收到的请求按照顺序逐一分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,nginx会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。
  • 这种方式下,可以给不同的后端服务器设置一个权重值(weight),用于调整不同的服务器上请求的分配率;权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的。
  • ip_hash:每个请求按照发起客户端的ip的hash结果进行匹配,这样的算法下一个固定ip地址的客户端总会访问到同一个后端服务器,这也在一定程度上解决了集群部署环境下session共享的问题。

5、Nginx负载均衡案例

主机 Ip 安装 系统
Nginx 192.168.47.137 Nginx RHEL8
Rs1 192.168.47.136 Httpd RHEL8
Rs2 192.168.47.50 Httpd RHEL8

//三台主机都关闭防火墙和selinux,还需要配置好yum仓库
//nginx主机部署nginx服务,之前已经部署好了,我这里就不演示了
//rs1主机上,安装httpd,然后添加一个测试网页

[root@rs1 ~]# yum -y install httpd
[root@rs1 ~]# systemctl restart httpd
[root@rs1 ~]# systemctl enable --now httpd
[root@rs1 ~]# echo "This is a server1" > /var/www/html/index.html
[root@rs1 ~]# cat /var/www/html/index.html 
This is a server1
[root@rs1 ~]# systemctl restart httpd

//rs2主机上,安装httpd,然后添加一个测试网页

[root@rs2 ~]# yum -y install httpd
[root@rs2 ~]# systemctl restart httpd.service 
[root@rs2 ~]# systemctl enable --now httpd.service 
[root@rs2 ~]# echo "This is a server2" > /var/www/html/index.html
[root@rs2 ~]# systemctl restart httpd.service 

//在nginx主机上,修改配置文件,设置负载均衡

[root@www ~]# vim /usr/local/nginx/conf/nginx.conf
http {
        upstream webserver {                    //定义负载模块为webserver
        server 192.168.47.136;
        server 192.168.47.50;
}

  server {
        listen       80;
        server_name  localhost;
        
  location / {
                proxy_pass http://webserver;
        }
[root@www ~]# nginx -t  		//检查配置文件是否正确
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@www ~]# nginx -s reload

//用nginx ip访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ha9eQIps-1666168247001)(./1666151821145.png)]
server2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pX3pwq19-1666168247002)(./1666151837666.png)]
负载均衡设置成功

6、设置负载均衡权重

如果想其中一台后端真实服务器数据量足够,多承担一些访问量,可以去用weight设置请求访问的权重

[root@www ~]# vim /usr/local/nginx/conf/nginx.conf
http {
        upstream webserver {
        server 192.168.47.136 weight=2;     ///添加此行
        server 192.168.47.50;
}
[root@www ~]# nginx -s reload

重载nginx并测试访问,此时会发现47.136 主机(rs1)访问时访问2次后,才轮询到rs2中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tPjEKxYz-1666168247002)(./1666152292189.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6IERC8z8-1666168247003)(./1666152293881.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bNUwoqxY-1666168247003)(./1666152307993.png)]

7、测试访问不同端口

//此时,我们发现三台主机都是使用80端口,所以在nginx配置文件中使用的upstream中,对应的真实后端服务器。假若我们并没有设置端口,如果其中某台后端服务器使用8080端口呢?我们如何进行设置,rs1为8080端口,rs2为80端口
//首先修改rs1的httpd服务,侦听8080端口,并重启httpd服务

[root@www ~]# vim /usr/local/nginx/conf/nginx.conf

http {
        upstream webserver {
        server 192.168.47.136:8080 weight=2;
        server 192.168.47.50:80;
}
[root@www ~]# nginx -s reload

//第一台服务端修改端口
[root@rs1 ~]# vim /etc/httpd/conf/httpd.conf 
Listen 8080
[root@rs1 ~]# systemctl restart httpd
[root@rs1 ~]# ss -antl | grep 8080
LISTEN 0      128                *:8080            *:*    

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3leMTIWR-1666168247005)(./1666152657490.png)]

8、ip_hash配置

[root@www ~]# vim /usr/local/nginx/conf/nginx.conf
http {
        upstream webserver {
        ip_hash
        server 192.168.47.136:8080 weight=2;
        server 192.168.47.50:80;
}
[root@www ~]# nginx -s reload

ip_hash这种负载均衡模式根据个人理解就是:例如多个用户通过nginx访问到了后端的httpd集群中,这个时候因为有不同用户,所以ip也不同,ip+hash算法计算的hash值都传到了httpd,nginx就记录了这个ip和hash值,那么下次同一个ip过来还是会分配到这个httpd的。

  • 如果在集群中的某台服务器出现故障,我们想要从nginx的集群配置中移除掉,我们不可以直接的将那一行删掉,比如server
    192.168.100.10:8080 weight=2;删掉,如果直接删掉会导致nginx的hash算法重新计算,那么用户的会话或者说缓存都会失效掉,所以这里如果不用这台服务器,直接比较为down即可,也就是
    server 192.168.100.10:8080 down 这么做就可以了。

9、动静分离nginx+tomcat

还是基于上面的环境额外添加一台tomcat
Tomcat:192.168.47.50

//想要部署tomcat可以看我之前jenkins服务部署中的tomcat,此时我就省略掉了,部署好了后,我们来测试访问以下基于tomcat的动态测试网页

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9A9Vw5WC-1666168247006)(./1666155354420.png)]
nginx端部署

[root@www ~]# vim /usr/local/nginx/conf/nginx.conf
http {
        upstream static {
        server 192.168.47.136;
        server 192.168.47.148 weight=2;   
}
        upstream tomcat {                           //动态测试
                server 192.168.47.50:8080;
        }


 server {
        listen       80;
        server_name  localhost;


        location / {
                proxy_pass http://static;
        }

        location /jenkins {
                proxy_pass http://tomcat;
        }
        
[root@www ~]# nginx -s reload

静态页面访问成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g3c2UkU2-1666168247007)(./1666157238625.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8DSfDCmc-1666168247008)(./1666157245983.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yAjV9GWu-1666168247008)(./1666157253986.png)]
动态访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ng9d4gqW-1666168247009)(./1666157287451.png)]

猜你喜欢

转载自blog.csdn.net/qq_36306519/article/details/131097273