一、Nginx基本概念

1.1、Nginx 是什么?能做什么?

Nginx 是高性能的 HTTP 和反向代理的服务器,处理高并发能力是十分强大的,能经受高负载的考验,有报告表明能支持高达 50,000 个并发连接数。

1.2、反向代理

1、正向代理

正向代理就是顺着请求的方向进行的代理,即代理服务器他是由你配置为你服务,去请求目标服务器地址,不直接访问资源,而是通过代理访问资源

  1. 代理客户;
  2. 隐藏真实的客户,为客户端收发请求,使真实客户端对服务器不可见;
  3. 一个局域网内的所有用户可能被一台服务器做了正向代理,由该台服务器负责 HTTP 请求;
  4. 意味着同服务器做通信的是正向代理服务器;

image-20210414112335420

2、反向代理(Reverse Proxy)

指以代理服务器来接受网络上的连接请求,然后将请求转发给内部网络上的服务器,并将服务器上得到的结果返回给请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。客户端无需做任何配置。

  1. 代理服务器;
  2. 隐藏了真实的服务器,为服务器收发请求,使真实服务器对客户端不可见;
  3. 负载均衡服务器,将用户的请求分发到空闲的服务器上;
  4. 意味着用户和负载均衡服务器直接通信,即用户解析服务器域名时得到的是负载均衡服务器的 IP ;

image-20210414113129748

1.3、负载均衡

增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的
情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡。

单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡

image-20210414143824993

1.4、动静分离

为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。

严格意义上说应该是动态请求和静态请求分开,可以理解成使用 Nginx 处理静态请求,Tomcat 处理动态请求。 动静分离从目前实现方式大致分为两种: 一是纯粹的把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案。 二是动态和静态文件混合在一起发布,通过 Nginx 分开。通过 location 指定不同的后缀 名实现不同的请求转发。

image-20210414144306531

二、Nginx 安装、常用命令和配置文件

2.1、Linux 上安装 Nginx

  • 使用 xftp 将安装包传输到 Linux 服务器上。
  • 需要先安装 Nginx 运行所需的依赖
  • 安装 pcre-8.37 ,安装路径为 usr/local
  • 安装 zlib,使用 yum 命令
  • 安装 Nginx
  1. 解压压缩包
  2. 进入解压缩目录,执行
1
./configure
  1. 执行 make && make install
  • 安装完成后,在 usr 文件夹中会多出一个 local/nginx 文件夹,这个文件夹是 nginx 生成的。

  • 启动 nginx

/usr/local/nginx/sbin 文件夹中执行命令,启动 nginx,命令为:

1
./nginx

此时使用 ps -ef | grep nginx 查看进程,可以看到 nginx 已经启动

image-20210414150311947

访问虚拟机地址,可以看到此页面,证明 nginx 安装成功

image-20210414150351821

2.2、常用命令

1、使用 nginx 操作命令前提条件

必须进入 nginx 的目录,即 usr/local/nginx/sbin

2、查看 nginx 版本号

1
./nginx -v

结果

image-20210414150713342

3、启动 nginx

进入usr/local/nginx/sbin,输入以下命令

1
./nginx

4、关闭 nginx

1
nginx -s stop

5、重新加载 nginx

同样需要在 usr/local/nginx/sbin 目录下,执行以下命令

1
./nginx -s reload

2.3、Nginx 配置文件

1、位置

usr/local/nginx/conf/nginx.conf

image-20210414151557972

2、查看 nginx.conf,配置文件中的内容包含三部分内容

  1. 全局块:配置服务器整体运行的配置指令比如 worker_processes 1;处理并发数的配置
  2. events 块:影响 Nginx 服务器与用户的网络连接比如 worker_connections 1024; 支持的最大连接数为 1024
  3. http 块,http块还包含两部分:http 全局块和server 块

image-20210414152051620

  • 全局块

​ 从配置文件开始到 events 块之间的内容,主要会设置一些影响 nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等。

​ 比如这个配置

1
worker_processes  1;

worker_processes 值越大,可以支持的并发处理量就越多。

  • events 块

​ events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 workprocess下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 wordprocess 可以同时支持的最大连接数等。

image-20210414152710314

上述例子就表示每个 workprocess 支持的最大连接数为 1024.
这部分的配置对 Nginx的性能影响较大,在实际中应该灵活配置。

  • http 块

配置最频繁的部分,代理,缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。

注意:Http块也可以包括 http 全局块、server 块。

  1. http 全局块

    http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。

  2. server 块

    这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。

    每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。而每个 server 块也分为全局 server 块,以及可以同时包含多个 location 块。

    • 全局 server 块

    最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或IP 配置。

    • location 块

    一个 server 块可以配置多个 location 块。

    这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(也可以是 IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

三、Nginx 配置实例

3.1、配置反向代理

1、实现效果

打开浏览器,在浏览器地址中输入 www.123.com ,跳转到 Linux 系统 tomcat 主页面中。

image-20210414153844419

2、准备工作

  • Linux 中安装 tomcat
  • 安装完成后,进入 tomcat/bin 下执行命令启动 tomcat
1
./startup.sh
  • 访问虚拟机地址:8080,可以看到如下页面

image-20210414154618048

3、执行步骤

  • 修改hosts,添加域名 ip 映射规则。

需要配置电脑域名映射 ip,我这里使用 SwichHosts! 来配置

image-20210414154908499

测试配置的域名

image-20210414154949670

  • nginx 中进行请求转发的配置(反向代理配置)

找到 nginx 配置文件,对配置文件进行编辑。

  1. 修改 server_name 为虚拟机 ip

image-20210414155309542

  1. 修改路径

添加一行配置

proxy_pass 代表代理转发

image-20210414155853452

  1. 测试结果

此时再次访问 www.123.com ,不添加8080端口

image-20210414160453577

3.2、配置反向代理实例二

1、实现效果

实现效果:使用 nginx 反向代理,根据访问的路径跳转到不同端口的服务中。

在本实例中,nginx 监听端口为 9001。
访问 http://192.168.20.100/edu/ 直接跳转到 127.0.0.1:8081

访问 http://192.168.20.100/vod/ 直接跳转到 127.0.0.1:8082

2、准备工作

  • 准备两个 tomcat 服务器

usr/local 下创建两个 目录,存放两个 tomcat

image-20210414161213931

  • 修改两个 tomcat 的启动端口,分别为 8081、8082
  • 准备测试页面

在 8081 tomcat 的 webapps 目录下创建一个 edu 文件夹,添加一个 8081.html

1
<h1>我是tomcat8081</h1>

同理在 8082 tomcat 的 webapps 目录下创建一个 vod 目录,添加一个 8082.html

1
<h1>我是tomcat8082</h1>

3、修改 nginx.conf 配置文件

添加一个 Server 块

1
2
3
4
5
6
7
8
9
10
server {
listen 9001;
server_name 192.168.20.100;
location ~ /edu/ {
proxy_pass http://localhost:8081;
}
location ~ /vod/ {
proxy_pass http://localhost:8082;
}
}
  • 重启 nginx ,进行测试

访问时路径带有 edu

image-20210414164703108

访问时路径带有 vod

image-20210414164901498

4、location 指令说明

该指令用于匹配 URL,语法如下

image-20210414163309991

  1. = :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。
  2. ~:用于表示 uri 包含正则表达式,并且区分大小写。
  3. ~*:用于表示 uri 包含正则表达式,并且不区分大小写。
  4. ^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location块中的正则 uri 和请求字符串做匹配。

注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识。

3.3、配置负载均衡

1、效果

浏览器地址栏中输入地址 http://192.168.20.100/edu/a.html ,实现负载均衡,请求既访问8081,也访问8082.

2、准备工作

  • 准备两台 tomcat ,分别为 8081/8082
  • 在两台 tomcatwebapps 目录下,创建名称为 edu 的文件夹,在 edu 文件夹中创建一个名为 a 的html文件。
1
2
3
<h1>
Server port = 8081/8082
</h1>
  • 重启 两台 tomcat

3、在 Nginx 配置文件中进行负载均衡的配置

在 http 块中添加配置

  1. 在 http 块中添加一个 upstream 负载均衡服务名 ,本例配置的负载均衡服务名为 myserver
1
2
3
4
5
6
upstream myserver {
# 在这里配置server 负载均衡服务器ip:端口;
server 192.168.20.100:8081;
server 192.168.20.100:8082;

}
  1. 在下面 server 块的 location 块中添加配置如下

location / {

​ proxy_pass http://上面配置的负载均衡服务名;

}

  1. 同时在 server 块中的 server_name 中需要配置虚拟机 ip

image-20210414184320309

4、测试

访问 http://192.168.20.100/edu/a.html

  • 第一次访问

image-20210414184429715

  • 第二次访问

image-20210414184446288

5、 nginx 中负载均衡的几种策略

  • 轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。

  • 权重

weight 代表权重,默认为 1,权重越高,被分配的客户端越多。

指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。

例如

1
2
3
4
upstream server_pool{
server 192.168.5.21 weight=10;
server 192.168.5.22 weight=10;
}
  • ip_hash

每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。

1
2
3
4
5
upstream server_pool{ 
ip_hash;
server 192.168.5.21:80;
server 192.168.5.22:80;
}
  • fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。

1
2
3
4
5
upstream server_pool{ 
server 192.168.5.21:80;
server 192.168.5.22:80;
fair;
}

3.4、配置动静分离

1、概念

image-20210414190443274

Nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离。

严格意义上说应该是动态请求跟静态请求分开,可以理解成使用 Nginx处理静态页面Tomcat 处理动态页面

动静分离从目前实现角度来讲大致分为两种

  1. 一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;
  2. 另外一种方法就是动态跟静态文件混合在一起发布,通过 nginx 来分开。

通过 location 指定不同的后缀名实现不同的请求转发。

通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。

具体 Expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。

此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用 Expires 来缓存),我这里设置 3d,表示在这 3 天之内访问这个 URL,发送一个请求,比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码304,如果有修改,则直接从服务器重新下载,返回状态码 200。

2、准备工作

  • 在 Linux 系统中准备静态资源

在根目录下创建两个文件夹:/data/www 和 /data/image

www 文件夹下创建一个 a.html 文件

1
<h1>test nginx html!!!</h1>

在 image 文件夹中放一张图片

dab56a12b31bb051f8eda86e217adab448ede0e9

3、实现通过 nginx 访问静态资源,修改 nginx 配置文件

修改 server 块中的 location 配置

1
2
3
4
5
6
7
8
9
location /www/ {
root /data/;
index index.html index.htm;
}
location /image/ {
root /data/;
# 该配置意思为:列出当前文件夹内容
autoindex on;
}

image-20210414193240817

重启 Nginx

4、测试

  • 访问 www 文件夹下的静态 html 页面

在浏览器中输入地址:http://192.168.20.100/www/a.html

image-20210414192923090

  • 访问 image 文件夹下的图片静态资源

在浏览器中输入地址:http://192.168.20.100/image/daqiao.jpg

image-20210414193212717

四、Nginx 原理

4.1、Master 和 Worker

image-20210414194532005

启动 Nginx 后,实际上会运行两个进程,一个为 Master ,一个为 Worker。

1
ps -ef | grep nginx

image-20210414194739905

4.2、Worker 是如何工作的?

image-20210414194845608

一个 master 和多个 woker 有好处

  • 可以使用 nginx –s reload 热部署,利用 nginx 进行热部署操作
  • 每个 woker 是独立的进程,不需要加锁,如果有其中的一个 woker 出现问题,其他 woker 独立的,继续进行争抢,实现请求过程,不会造成服务中断

1、设置多少个 Worker 最合适?

worker 数和服务器的 cpu 数相等是最为适宜的

2、连接数 Worker_connection?

  • 发送一个请求,占用了 Worker 的几个连接数?

答:2个或者4个。

其中动态请求4个,静态请求2个。

静态请求不需要和 tomcat 发生连接,所以只有两根线(一根请求,一根返回)。

动态请求需要四根线(其中两根与 tomcat)

image-20210414195646030

  • nginx 有一个 master,有四个 woker,每个 woker 支持最大的连接数 1024,支持的最大并发数是多少?

普通的静态访问最大并发数是 worker_connections * worker_processes /2

如果是 HTTP 作为反向代理来说,最大并发数量应该是 worker_connections * worker_processes / 4