Nginx详解配置实例及企业高性能web服务器

news2024/9/24 3:28:24

目录

企业高性能web服务器

一.Web 服务基础介绍

1.1 互联网发展历程回顾

1.2 Web 服务介绍

1.2.1 Apache 经典的 Web 服务端

1.2.1.1 Apache prefork 模型

1.2.1.2 Apache worker 模型

1.2.1.3 Apache event模型

1.2.2 Nginx-高性能的 Web 服务端

1.2.3服务端 I/O 流程

1.2.3.1 磁盘 I/O

1.2.3.2 网络 I/O

1.3 I/O 模型

1.3.1 I/O 模型相关概念

1.3.2 网络 I/O 模型

1.3.2.1 阻塞型 I/O 模型(blocking IO)

1.3.2.2 非阻塞型 I/O 模型 (nonblocking IO)

1.3.2.3 多路复用 I/O 型(I/O multiplexing)

1.3.2.4 信号驱动式 I/O 模型 (signal-driven IO)

1.3.2.5 异步 I/O 模型 (asynchronous IO)

1.3.3 五种 IO 对比

二 环境安装与配置

2.1编译安装 Nginx

2.2Nginx 启动文件

2.3使用安装完成的二进制文件nginx

2.4平滑升级和回滚

2.4.1平滑升级流程

2.4.2平滑升级和回滚案例

三 Nginx 核心配置详解

3.1 配置文件说明

3.2 全局配置

3.3核心配置示例

3.3.1 新建一个 PC web 站点

3.3.2root 与 alias

3.4location 的详细使用

3.5Nginx 账户认证功能

3.6自定义错误页面

3.7自定义错误日志

3.8检测文件是否存在

3.9长连接配置

3.10作为下载服务器配置

四 Nginx 高级配置

4.1 Nginx 状态页

4.2 Nginx 压缩功能

4.3Nginx 变量使用

五 Nginx Rewrite 相关功能

5.1 ngx_http_rewrite_module 模块指令

5.1.1 if 指令

5.1.2 set 指令

5.1.3 break 指令

5.1.4return 指令

5.2 rewrite 指令

5.2.1 rewrite flag 使用介绍

5.2.2 rewrite案例: 域名永久与临时重定向

5.2.3永久重定向301

5.3rewrite 案例: break 与 last

5.3.1 break和last区别案例

5.3.2rewrite案例: 自动跳转 https

5.3.3rewrite 案例: 判断文件是否存在

5.4Nginx 防盗链

六 Nginx 反向代理功能

6.1 实现 http 反向代理

6.1.1 http 协议反向代理

6.1.1.1 反向代理配置参数

6.1.1.2 实战案例: 反向代理单台 web 服务器

6.1.1.3 实战案例: 指定 location 实现反向代理

6.1.1.3.1 针对指定的 location

6.1.1.3.2 针对特定的资源实现代理

6.1.1.4 反向代理示例: 缓存功能

6.1.1.4.1 非缓存场景压测

6.1.1.4.2 准备缓存配置

6.1.1.4.3 访问并验证缓存文件

6.1.2 http 反向代理负载均衡

6.1.2.1 http upstream配置参数

6.1.2.2 反向代理示例: 后端多台 web服务器

6.2 实现 Nginx 四层负载均衡

6.2.1 tcp负载均衡配置参数 +DNS

6.2.2 负载均衡实例: MySQL 后端服务器安装 MySQL

6.3 实现 FastCGI

6.3.1 FastCGI配置指令

6.3.2 FastCGI实战案例 : Nginx与php-fpm在同一服务器

6.3.3 php的动态扩展模块(php的缓存模块)

6.3.4 php高速缓存

7 nginx 二次开发版本

7.1 openresty

7.2 编译安装 openresty


企业高性能web服务器

一.Web 服务基础介绍

1.1 互联网发展历程回顾

1993年3月2日,中国科学院高能物理研究所租用AT&T公司的国际卫星信道建立的接入美国SLAC国家实 验室的64K专线正式开通,成为我国连入Internet的第一根专线。 1995年马云开始创业并推出了一个web网站 中国黄页 1999年创建阿里巴巴www.alibabagroup.com 2003年5月10日创立淘宝网 2004年12月,马云创立第三方网上支付平台支付宝(蚂蚁金服旗下,共有蚂蚁金服支付宝、余额宝、招 财宝、蚂蚁聚宝、网商银行、蚂蚁花呗、芝麻信用等子业务板块) 2009年开始举办双十一购物狂欢节

2012年1月11日淘宝商城正式更名为“天猫” 2014年9月19日里巴巴集团于纽约证券交易所正式挂牌上市

1.2 Web 服务介绍

1.2.1 Apache 经典的 Web 服务端

Apache起初由美国的伊利诺伊大学香槟分校的国家超级计算机应用中心开发 目前经历了两大版本分别是1.X和2.X 其可以通过编译安装实现特定的功能

1.2.1.1 Apache prefork 模型

预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024 每个子进程有一个独立的线程响应用户请求 相对比较占用内存,但是比较稳定,可以设置最大和最小进程数 是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景 优点:稳定 缺点:每个用户请求需要对应开启一个进程,占用资源较多,并发性差,不适用于高并发场景

1.2.1.2 Apache worker 模型

一种多进程和多线程混合的模型 有一个控制进程,启动多个子进程 每个子进程里面包含固定的线程 使用线程程来处理请求 当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求, 由于其使用了线程处理请求,因此可以承受更高的并发 优点:相比prefork 占用的内存较少,可以同时处理更多的请求 缺点:使用keepalive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超 时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用(该问题在 prefork模式下,同样会发生)

1.2.1.3 Apache event模型

Apache中最新的模式,2012年发布的apache 2.4.X系列正式支持event 模型,属于事件驱动模型(epoll) 每个进程响应多个请求,在现在版本里的已经是稳定可用的模式 它和worker模式很像,最大的区别在于,它解决了keepalive场景下长期被占用的线程的资源浪费问题 (某些线程因为被keepalive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)event MPM中,会有一个专门的线程来管理这些keepalive类型的线程 当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场 景下的请求处理能力 优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keepalive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放 缺点:没有线程安全控制

1.2.2 Nginx-高性能的 Web 服务端

Nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学为俄罗斯rambler.ru公司开发的,开发 工作最早从2002年开始,第一次公开发布时间是2004年10月4日,版本号是0.1.0 2019年3月11日F5 与 NGINX达成协议,F5 将收购 NGINX 的所有已发行股票,总价值约为 6.7 亿美元。 6.7亿美金约合44.97亿人民币,nginx核心模块代码长度198430(包括空格、注释),所以一行代码约为 2.2万人民币 官网地址 www.nginx.org Nginx历经十几年的迭代更新(https://nginx.org/en/CHANGES), 目前功能已经非常完善且运行稳 定,另外Nginx的版本分为开发版、稳定版和过期版,nginx以功能丰富著称,它即可以作为http服务 器,也可以作为反向代理服务器或者邮件服务器能够快速的响应静态网页的请求 支持FastCGI/SSL/Virtual Host/URL Rwrite /Gzip / HTTP Basic Auth/http或者TCP的负载均衡(1.9版本以 上且开启stream模块)等功能,并且支持第三方的功能扩展。 天猫 淘宝 京东 小米 163 新浪等一线互联网公司都在用Nginx或者进行二次开发

1.2.3服务端 I/O 流程

I/O在计算机中指Input/Output, IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数), 是衡量磁盘性能的主要指标之一。IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处理的 I/O请求数量为单位,I/O请求通常为读或写数据操作请求。 一次完整的I/O是用户空间的进程数据与内核空间的内核数据的报文的完整交换,但是由于内核空间与用 户空间是严格隔离的,所以其数据交换过程中不能由用户空间的进程直接调用内核空间的内存数据,而 是需要经历一次从内核空间中的内存数据copy到用户空间的进程内存当中,所以简单说I/O就是把数据从 内核空间中的内存数据复制到用户空间中进程的内存当中。 服务器的I/O 磁盘I/O 网络I/O : 一切皆文件,本质为对socket文件的读写

1.2.3.1 磁盘 I/O

磁盘I/O是进程向内核发起系统调用,请求磁盘上的某个资源比如是html 文件或者图片,然后内核通过相 应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存, 如果是比较大的数据也需要等待时间

机械磁盘的寻道时间、旋转延迟和数据传输时间:
寻道时间:是指磁头移动到正确的磁道上所花费的时间,寻道时间越短则I/O处理就越快,目前磁盘的寻道时
间一般在3-15毫秒左右。
旋转延迟:是指将磁盘片旋转到数据所在的扇区到磁头下面所花费的时间,旋转延迟取决于磁盘的转速,通常
使用磁盘旋转一周所需要时间的1/2之一表示,比如7200转的磁盘平均训传延迟大约为
60*1000/7200/2=4.17毫秒,公式的意思为 (每分钟60秒*1000毫秒每秒/7200转每分/2),如果是
15000转的则为60*1000/15000/2=2毫秒
数据传输时间:指的是读取到数据后传输数据的时间,主要取决于传输速率,这个值等于数据大小除以传输速
率,目前的磁盘接口每秒的传输速度可以达到600MB,因此可以忽略不计。
常见的机械磁盘平均寻道时间值:
7200转/分的磁盘平均物理寻道时间:9毫秒
10000转/分的磁盘平均物理寻道时间:6毫秒
15000转/分的磁盘平均物理寻道时间:4毫秒
常见磁盘的平均延迟时间:
7200转的机械盘平均延迟:60*1000/7200/2 = 4.17ms
10000转的机械盘平均延迟:60*1000/10000/2 = 3ms
15000转的机械盘平均延迟:60*1000/15000/2 = 2ms
每秒最大IOPS的计算方法:
7200转的磁盘IOPS计算方式:1000毫秒/(9毫秒的寻道时间+4.17毫秒的平均旋转延迟时
间)=1000/13.13=75.9 IOPS
10000转的磁盘的IOPS计算方式:1000毫秒/(6毫秒的寻道时间+3毫秒的平均旋转延迟时
间)=1000/9=111IOPS
15000转的磁盘的IOPS计算方式:15000毫秒/(4毫秒的寻道时间+2毫秒的平均旋转延迟时
间)=1000/6=166.6 IOPS
1.2.3.2 网络 I/O

网络通信就是网络协议栈到用户空间进程的IO就是网络IO

网络I/O 处理过程 获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3) 构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4) 返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端(5-7) 不论磁盘和网络I/O 每次I/O,都要经由两个阶段: 第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长 第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短

1.3 I/O 模型

1.3.1 I/O 模型相关概念

同步/异步:关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状 态的通知。 同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事 情是否处理完成 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态

阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态 阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂 起,干不了别的事情。 非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完 成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。

1.3.2 网络 I/O 模型

阻塞型、非阻塞型、复用型、信号驱动型、异步

1.3.2.1 阻塞型 I/O 模型(blocking IO)

阻塞IO模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞 用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间。内核等到数据包到达后,然 后将接收的数据拷贝到用户空间,完成read操作 用户需要等待read将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线 程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够

优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源 缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销 较apache 的preforck使用的是这种模式。 同步阻塞:程序向内核发送I/O请求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回,则进 程将一直等待并不再接受新的请求,并由进程轮询查看I/O是否完成,完成后进程将I/O结果返回给 Client,在IO没有返回期间进程不能接受其他客户的请求,而且是有进程自己去查看I/O是否完成,这种 方式简单,但是比较慢,用的比较少。

1.3.2.2 非阻塞型 I/O 模型 (nonblocking IO)

用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据 到达后,才真正读取到数据,继续执行。即 “轮询”机制存在两个问题:如果有大量文件描述符都要等, 那么就得一个一个的read。这会带来大量的Context Switch(read是系统调用,每调用一次就得在用户 态和核心态切换一次)。轮询的时间不好把握。这里是要猜多久之后数据才能到。等待时间设的太长, 程序响应延迟就过大;设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一 般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。 非阻塞:程序向内核发送请I/O求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回IO结 果,进程将不再等待,而且继续处理其他请求,但是仍然需要进程隔一段时间就要查看内核I/O是否完 成。 查看上图可知,在设置连接为非阻塞时,当应用进程系统调用 recvfrom 没有数据返回时,内核会立即返 回一个 EWOULDBLOCK 错误,而不会一直阻塞到数据准备好。如上图在第四次调用时有一个数据报准 备好了,所以这时数据会被复制到 应用进程缓冲区 ,于是 recvfrom 成功返回数据 当一个应用进程这样循环调用 recvfrom 时,称之为轮询 polling 。这么做往往会耗费大量CPU时间,实 际使用很少

1.3.2.3 多路复用 I/O 型(I/O multiplexing)

上面的模型中,每一个文件描述符对应的IO是由一个线程监控和处理 多路复用IO指一个线程可以同时(实际是交替实现,即并发完成)监控和处理多个文件描述符对应各自 的IO,即复用同一个线程 一个线程之所以能实现同时处理多个IO,是因为这个线程调用了内核中的SELECT,POLL或EPOLL等系统调 用,从而实现多路复用IO

优缺点 优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述 符一个线程),这样可以大大节省系统资源缺点:当连接数较少时效率相比多线程+阻塞 I/O 模型效率较低,可能延迟更大,因为单个连接处理 需要 2 次系统调用,占用时间会有增加

IO多路复用适用如下场合: 当客户端处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用 当一个客户端同时处理多个套接字时,此情况可能的但很少出现 当一个服务器既要处理监听套接字,又要处理已连接套接字,一般也要用到I/O复用 当一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用 当一个服务器要处理多个服务或多个协议,一般要使用I/O复用

1.3.2.4 信号驱动式 I/O 模型 (signal-driven IO)

信号驱动I/O的意思就是进程现在不用傻等着,也不用去轮询。而是让内核在数据就绪时,发送信号通知 进程。 调用的步骤是,通过系统调用 sigaction ,并注册一个信号处理的回调函数,该调用会立即返回,然后主 程序可以继续向下执行,当有I/O操作准备就绪,即内核数据就绪时,内核会为该进程产生一个 SIGIO信 号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用 recvfrom 获取数据,将用户进 程所需要的数据从内核空间拷贝到用户空间

1.3.2.5 异步 I/O 模型 (asynchronous IO)

异步I/O 与 信号驱动I/O最大区别在于,信号驱动是内核通知用户进程何时开始一个I/O操作,而异步I/O 是由内核通知用户进程I/O操作何时完成,两者有本质区别,相当于不用去饭店场吃饭,直接点个外卖,把 等待上菜的时间也给省了 相对于同步I/O,异步I/O不是顺序执行。用户进程进行aio_read系统调用之后,无论内核数据是否准备 好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到socket数据准备好了,内核直 接复制数据给进程,然后从内核向进程发送通知。IO两个阶段,进程都是非阻塞的。 信号驱动IO当内核通知触发信号处理程序时,信号处理程序还需要阻塞在从内核空间缓冲区拷贝数据到 用户空间缓冲区这个阶段,而异步IO直接是在第二个阶段完成后,内核直接通知用户线程可以进行后续 操作了

1.3.3 五种 IO 对比

这五种 I/O 模型中,越往后,阻塞越少,理论上效率也是最优前四种属于同步 I/O,因为其中真正的 I/O 操作(recvfrom)将阻塞进程/线程,只有异步 I/O 模型才与 POSIX 定义的异步 I/O 相匹配

二 环境安装与配置

2.1编译安装 Nginx

官方源码包下载地址:

https://nginx.org/en/download.html

编译安装示例:

[root@Nginx ~]# dnf install gcc pcre-devel zlib-devel openssl-devel -y
[root@Nginx nginx-1.24.0]# useradd -s /sbin/nologin -M nginx
我是上传的所以解压安装包
[root@Nginx nginx]# tar zxf nginx-1.24.0.tar.gz
[root@Nginx nginx]# cd nginx-1.24.0/
[root@Nginx nginx-1.24.0]# useradd -s /sbin/nologin -M nginx

[root@Nginx nginx-1.24.0]# ./configure --prefix=/usr/local/nginx \

[root@Nginx nginx-1.24.0]# make && make install

nginx完成安装以后,有四个主要的目录

关闭debug

[root@nginxnode1 nginx-1.24.0]# vim auto/cc/gcc

验证版本及编译参数

[root@Nginx ~]# vim ~/.bash_profile

2.2Nginx 启动文件

[root@Nginx ~]# vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
​
[root@Nginx ~]# systemctl daemon-reload
[root@Nginx ~]# systemctl start nginx 
配置完成后就可以使用
[root@nginx_node1 sbin]# systemctl enable --now nginx来启动nginx服务

2.3使用安装完成的二进制文件nginx

[root@Nginx ~]# nginx -v
nginx version: nginx/1.18.0
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
  
-?,-h         : this help
  
-v           : show version and exit
  
-V           : show version and configure options then exit #显示版本和编译参数
  
-t           : test configuration and exit #测试配置文件是否异
 
-T           : test configuration, dump it and exit #测试并打印
  
-q           : suppress non-error messages during configuration testing #静默
模式
  
-s signal     : send signal to a master process: stop, quit, reopen, reload #
发送信号,reload信号 会生成新的worker,但master不会重新生成
  
-p prefix     : set prefix path (default: /etc/nginx/) #指定Nginx 目录
  
-c filename   : set configuration file (default: /etc/nginx/nginx.conf) #
配置文件路径
  
-g directives : set global directives out of configuration file #设置全局指令,注意和
配置文件不要同时配置,否则冲突
​

2.4平滑升级和回滚

有时候我们需要对Nginx版本进行升级以满足对其功能的需求,例如添加新模块,需要新功能,而此时 Nginx又在跑着业务无法停掉,这时我们就可能选择平滑升级

2.4.1平滑升级流程

将旧Nginx二进制文件换成新Nginx程序文件(注意先备份)
向master进程发送USR2信号
master进程修改pid文件名加上后缀.oldbin,成为nginx.pid.oldbin
master进程用新Nginx文件启动新master进程成为旧master的子进程,系统中将有新旧两个Nginx主
进程共同提供Web服务,当前新的请求仍然由旧Nginx的worker进程进行处理,将新生成的master进
程的PID存放至新生成的pid文件nginx.pid
向旧的Nginx服务进程发送WINCH信号,使旧的Nginx worker进程平滑停止
向旧master进程发送QUIT信号,关闭老master,并删除Nginx.pid.oldbin文件
如果发现升级有问题,可以回滚∶向老master发送HUP,向新master发送QUIT

2.4.2平滑升级和回滚案例

[root@Nginx nginx]# tar zxf nginx-1.26.1.tar.gz
[root@Nginx nginx]# cd nginx-1.26.1/
#开始编译新版本
[root@Nginx nginx-1.26.1]# ./configure --with-http_ssl_module --withhttp_v2_module
 --with-http_realip_module --with-http_stub_status_module --withhttp_gzip_static_module
 --with-pcre --with-stream --with-stream_ssl_module --
with-stream_realip_module
#只要make无需要make install

[root@Nginx nginx-1.26.1]# make
#查看两个版本
[root@Nginx nginx-1.26.1]# ll objs/nginx /usr/local/nginx/sbin/nginx

#把之前的旧版的nginx命令备份
[root@Nginx ~]# cd /usr/local/nginx/sbin/
[root@Nginx sbin]# cp nginx nginx.24
#把新版本的nginx命令复制过去
[root@Nginx sbin]# \cp -f /root/nginx/nginx-1.26.1/objs/nginx  /usr/local/nginx/sbin

#检测一下有没有问题

[root@Nginx sbin]# kill -USR2 2360 #nginx worker ID
#USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的
nginx
#此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80
#此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进
程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理

#回收旧版本
[root@Nginx sbin]# kill -WINCH 2360
#检测版本信息
[root@Nginx sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.26.1 #新版本生效
Date: Thu, 18 Jul 2024 07:59:45 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 18 Jul 2024 03:41:13 GMT
Connection: keep-alive
ETag: "66988ed9-267"
Accept-Ranges: bytes
#回滚
#如果升级的版本发现问题需要回滚,可以重新拉起旧版本的worker
[root@Nginx sbin]# cp nginx nginx.26
[root@Nginx sbin]# ls
nginx nginx.24 nginx.26
[root@Nginx sbin]# mv nginx.24 nginx
mv: overwrite 'nginx'? y
​
​
[root@Nginx sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.24.0 ##版本回滚完成
Date: Thu, 18 Jul 2024 08:31:51 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 18 Jul 2024 03:41:13 GMT
Connection: keep-alive
ETag: "66988ed9-267"
Accept-Ranges: bytes

三 Nginx 核心配置详解

3.1 配置文件说明

nginx 官方帮助文档:nginx documentation Nginx的配置文件的组成部分: 主配置文件:nginx.conf 子配置文件: include conf.d/*.conf fastcgi, uwsgi,scgi 等协议相关的配置文件 mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮 件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某 种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动 使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。 Nginx 主配置文件的配置指令方式:

directive value [value2 ...];
注意
(1) 指令必须以分号结尾
(2) 支持使用配置变量
 内建变量:由Nginx模块引入,可直接引用
 自定义变量:由用户使用set命令定义,格式: set variable_name value;
 引用变量:$variable_name
​

主配置文件结构:四部分

main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
 ...
}  
#http/https 协议相关配置段
http {
...
} 
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
 ...
}
#stream 服务器相关配置段
stream {
 ...
} 

3.2 全局配置

Main 全局配置段常见的配置指令分类 正常运行必备的配置 优化性能相关的配置 用于调试及定位问题相关的配置 事件驱动相关的配置

user nginx nginx; #启动Nginx工作进程的用户和组
worker_processes [number | auto]; #启动Nginx工作进程的数量,一般设为和CPU核心数相同
worker_cpu_affinity 00000001 00000010 00000100 00001000 | auto ; 
#将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进
程独占以一核心CPU,但是可以保证此进程不运行在其他核心上,这就极大减少了nginx的工作进程在不同的
cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务
器的性能。
CPU MASK: 00000001:0号CPU
 00000010:1号CPU
 10000000:7号CPU
 
#示例
worker_cpu_affinity 0001 0010 0100 1000;第0号---第3号CPU
worker_cpu_affinity 0101 1010; 
#示例
worker_processes  4;
worker_cpu_affinity 00000010 00001000 00100000 10000000;
[root@centos8 ~]# ps axo pid,cmd,psr | grep nginx
31093 nginx: master process /apps   1
34474 nginx: worker process         1
34475 nginx: worker process         3
34476 nginx: worker process         5
34477 nginx: worker process         7
#错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit 
| alert | emerg]
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log /usr/local/nginx/logs/error.log error; 
#pid文件保存路径
pid       /usr/local/nginx/logs/nginx.pid;
worker_priority 0; #工作进程优先级,-20~20(19)
worker_rlimit_nofile 65536; #所有worker进程能打开的文件数量上限,
 #包括:Nginx的所有连接(例如与代理服务器的连接等)
 #而不仅仅是与客户端的连接
 #另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件
数的限制
 #最好与ulimit -n 或者limits.conf的值保持一致,
#修改pam限制
[root@Nginx ~]# sudo -u nginx ulimit -n
1024
[root@Nginx ~]# vim /etc/security/limits.conf
*               -       nofile         100000
[root@Nginx ~]# sudo -u nginx ulimit -n
100000
daemon off;   #前台运行Nginx服务用于测试、docker等环境。
master_process off|on; #是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为
on
events {
worker_connections 65535;   #设置单个工作进程的最大并发连接数
   use epoll; #使用epoll事件驱动,
   #Nginx支持众多的事件驱动,
   #比如:select、poll、epoll,只能设置在events模块中
设置
    
   accept_mutex on;   #on为同一时刻一个请求轮流由work进程处理,
   #而防止被同时唤醒所有worker
   #避免多个睡眠进程被唤醒的设置,默认为off
   #新请求会唤醒所有worker进程,此过程也称为"惊群"
   #因此nginx刚安装完以后要进行适当的优化。建议设置为on
   
   multi_accept on; #on时Nginx服务器的每个工作进程可以同时接受多个新的网
络连接
   #此指令默认为off,
   #即默认为一个工作进程只能一次接受一个新的网络连接
   #打开后几个同接受多个。建议设置为on
   
}
​

示例:

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

示例: 实现 nginx 的高并发配置

[root@Nginx ~]# ulimit -n 102400
[root@Nginx ~]# ab -c 5000 -n 10000 http://172.25.254.100/index.html
#修改配置
[root@Nginx ~]# vim /etc/security/limits.conf 
*   - nproc 100000
[root@Nginx ~]# vim /apps/nginx/conf/nginx.conf
worker_rlimit_nofile 100000; 
[root@Nginx ~]# systemctl restart nginx

http 配置块

#在响应报文中将指定的文件扩展名映射至MIME对应的类型
include           /etc/nginx/mime.types;
default_type     application/octet-stream; #除mime.types中的类型外
 #指定其它文件的默认MIME类型,浏览
器一般会提示下载
types {
   text/html html;
   image/gif gif;
   image/jpeg jpg;
}

示例:识别php文件为text/html

[root@Nginx ~]# vim /usr/local/nginx/html/lee.php

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

3.3核心配置示例

基于不同的IP、不同的端口以及不用得域名实现不同的虚拟主机,依赖于核心模块 ngx_http_core_module实现。

3.3.1 新建一个 PC web 站点

#定义子配置文件路径
[root@Nginx ~]# mkdir /usr/local/nginx/conf.d/
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf

#创建虚拟主机网站配置
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf

3.3.2root 与 alias

root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location root示例:

alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于 location上下文,此指令使用较少 alias示例:

3.4location 的详细使用

在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射; ngnix会根据用户请求的URI来检查定义的所有location,按一定的优先级找出一个最佳匹配, 而后应用其配置在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最 高的一个uri uri是用户请求的字符串,即域名后面的web文件路径 然后使用该location模块中的正则url和字符串,如果匹配成功就结束搜索,并使用此location处理 此请求。

#语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }
= #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立
即处理请求
^~   #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头
 #对uri的最左边部分做匹配检查,不区分字符大小写
 
~   #用于标准uri前,表示包含正则表达式,并且区分大小写
~*   #用于标准uri前,表示包含正则表达式,并且不区分大写
不带符号 #匹配起始于此uri的所有的uri
\   #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号
#匹配优先级从高到低:
对目录匹配:(~等于~*)>不带符号>^~>=   #必须要跟文件
对文件匹配:= >

3.5Nginx 账户认证功能

由 ngx_http_auth_basic_module 模块提供此功能 示例:

[root@nginx_node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf

3.6自定义错误页面

自 定义错误页,同时也可以用指定的响应状态码进行响应, 可用位置:http, server, location, if in location

[root@nginx_node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf

3.7自定义错误日志

可以自定义错误日志

3.8检测文件是否存在

try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如 果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一 个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内 部500错误。

3.9长连接配置

keepalive_timeout timeout [header_timeout];     #设定保持连接超时时长,0表示禁止长连接,
默认为75s
 #通常配置在http字段作为站点全局配置
keepalive_requests 数字;   #在一次长连接上所允许请求的资源的最大数量
 #默认为100次,建议适当调大,比如:500
​
[root@nginx_node1 ~]# yum install telnet -y
[root@nginx_node1 ~]# vim /usr/local/nginx/conf/nginx.conf

3.10作为下载服务器配置

ngx_http_autoindex_module 模块处理以斜杠字符 "/" 结尾的请求,并生成目录列表,可以做为下载服务 配置使用 相关指令:

autoindex on | off; #自动文件索引功能,默为off
autoindex_exact_size on | off;  #计算文件确切大小(单位bytes),off 显示大概大小(单位K、
M),默认on
autoindex_localtime on | off ; #显示本机时间而非GMT(格林威治)时间,默认off
autoindex_format html | xml | json | jsonp; #显示索引的页面文件风格,默认html
limit_rate rate; #限制响应客户端传输速率(除GET和HEAD以外的所有方法),单位
B/s,bytes/second, #默认值0,表示无限制,此指令由
ngx_http_core_module提供
set $limit_rate 4k; #也可以通变量限速,单位B/s,同时设置,此项优级高.

[root@nginx_node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf

在浏览器中测试

四 Nginx 高级配置

4.1 Nginx 状态页

基于nginx 模块 ngx_http_stub_status_module 实现, 在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module 否则配置完成之后监测会是提示法错误

4.2 Nginx 压缩功能

Nginx支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文 件大小将比源文件显著变小,样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相 应的CPU资源。 Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module,默认是内置模块 配置指令如下:

#启用或禁用gzip压缩,默认关闭
gzip on | off; 
#压缩比由低到高从1到9,默认为1,值越高压缩后文件越小,但是消耗cpu比较高。基本设定未4或者5
gzip_comp_level 4;
#禁用IE6 gzip功能,早期的IE6之前的版本不支持压缩
gzip_disable "MSIE [1-6]\."; 
#gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k; 
#启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1; 
#指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;  
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...; 
#如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”,一般建议打开
gzip_vary on | off; 
#预压缩,即直接从磁盘找到对应文件的gz后缀的式的压缩文件返回给用户,无需消耗服务器CPU
#注意: 来自于ngx_http_gzip_static_module模块
gzip_static on | off;
​
[root@nginx_node1 ~]# vim /usr/local/nginx/conf/nginx.conf

测试

4.3Nginx 变量使用

nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用 变量可以分为内置变量和自定义变量 内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。 内置变量 官方文档

http://nginx.org/en/docs/varindex.html

五 Nginx Rewrite 相关功能

Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求 此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库 rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能 比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的 链接,就可以设置为访问 另外还可以在一定程度上提高网站的安全性。

5.1 ngx_http_rewrite_module 模块指令

官方文档: Module ngx_http_rewrite_module

5.1.1 if 指令

官方文档:Module ngx_http_rewrite_module 用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行 配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:

if (条件匹配) { 
 action
}

使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间 使用以下符号链接:

= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false

测试:
[root@client ~]# curl 172.25.254.100/test/
if ---------> http
[root@client ~]# curl 172.25.254.100/test2/test
/data/nginx/timinglee.org/lee/test2/test is not exist

5.1.2 set 指令

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

5.1.3 break 指令

用于中断当前相同作用域(location)中的其他Nginx配置 与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效 位于后面的 ngx_http_rewrite_module 模块中指令就不再执行 Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,、 该指令可以在server块和locationif块中使用 Note 注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行 使用语法如下:

[root@client ~]# curl lee.timinglee.org/break #当未添加break时
lee
80
[root@client ~]# curl lee.timinglee.org/break #添加break后
lee
​

5.1.4return 指令

return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重 定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配 置都将不被执行,return可以在server、if 和 location块进行配置 语法格式:

return code; #返回给客户端指定的HTTP状态码
return code [text]; #返回给客户端的状态码及响应报文的实体内容
 #可以调用变量,其中text如果有空格,需要用单或双引号
return code URL; #返回给客户端的URL地址

5.2 rewrite 指令

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

语法格式 :

rewrite regex replacement [flag];
. #匹配除换行符以外的任意字符
\w #匹配字母或数字或下划线或汉字
\s #匹配任意的空白符
\d #匹配数字
\b #匹配单词的开始或结束
^ #匹配字付串的开始
$ #匹配字符串的结束
* #匹配重复零次或更多次
+ #匹配重复一次或更多次
? #匹配重复零次或一次
(n) #匹配重复n次
{n,} #匹配重复n次或更多次
{n,m} #匹配重复n到m次
*? #匹配重复任意次,但尽可能少重复
+? #匹配重复1次或更多次,但尽可能少重复
?? #匹配重复0次或1次,但尽可能少重复
{n,m}? #匹配重复n到m次,但尽可能少重复
{n,}? #匹配重复n次以上,但尽可能少重复
\W   #匹配任意不是字母,数字,下划线,汉字的字符
\S #匹配任意不是空白符的字符
\D #匹配任意非数字的字符
\B #匹配不是单词开头或结束的位置
[^x] #匹配除了x以外的任意字符
[^lee] #匹配除了magedu 这几个字母以外的任意字符

5.2.1 rewrite flag 使用介绍

利用nginx的rewrite的指令,可以实现url的重新跳转,rewrite有四种不同的flag,分别是redirect(临时 重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型 跳转型指由客户端浏览器重新对新地址进行请求 代理型是在WEB服务器内部实现跳转 rewrite 格式

Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据
包。
Default: —
Context: server, location, if

flag 说明

redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求,状态码:301
break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作
#而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,
#而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户

5.2.2 rewrite案例: 域名永久与临时重定向

域名的临时的调整,后期可能会变,之前的域名或者URL可能还用、或者跳转的目的域名和URL还会跳 转,这种情况浏览器不会缓存跳转,临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存。 示例: 因业务需要,将访问源域名 www.timinglee.org 的请求永久重定向到 www.timinglee.com

5.2.3永久重定向301

域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到 客户端浏览器 永久重定向会缓存DNS解析记录, 浏览器中有 from disk cache 信息,即使nginx服务器无法访问,浏览器也 会利用缓存进行重定向 比如: 京东早期的域名 www.360buy.com 由于与360公司类似,于是后期永久重定向到了 www.jd.com

5.3rewrite 案例: break 与 last

测试: 访问break请求被rewrite至test1,而访问test1转递请求再次被rewrite发送至test2,此测试last和break 分别有什么区别

5.3.1 break和last区别案例

[root@client ~]# curl -L 172.25.254.100/break/index.html
test1

5.3.2rewrite案例: 自动跳转 https

案例:基于通信安全考虑公司网站要求全站 https,因此要求将在不影响用户请求的情况下将http请求全 部自动跳转至 https,另外也可以实现部分 location 跳转

cd /usr/local/nginx/
mkdir certs
openssl req  -newkey  rsa:2048 -nodes -sha256 -keyout /usr/local/nginx/certs/timinglee.org.key \
-x509  -days 365 -out /usr/local/nginx/certs/timinglee.org.crt
vim /usr/local/nginx/conf.d/vhosts.conf

5.3.3rewrite 案例: 判断文件是否存在

案例:当用户访问到公司网站的时输入了一个错误的URL,可以将用户重定向至官网首页

5.4Nginx 防盗链

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

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

六 Nginx 反向代理功能

反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的 一种方式,这是用的比较多的一种方式。 Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预 定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主 要在不同的场景使用以下模块实现不同的功能

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

访问逻辑图:

同构代理:用户不需要其他程序的参与,直接通过http协议或者tcp协议访问后端服务器 异构代理:用户访问的资源时需要经过处理后才能返回的,比如php,python,等等,这种访问资源需 要经过处理才能被访问

6.1 实现 http 反向代理

官方文档: Module ngx_http_proxy_module,

6.1.1 http 协议反向代理

6.1.1.1 反向代理配置参数
#官方文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass 
proxy_pass; #用来设置将客户端请求转发给的后端服务器的主机
 #可以是主机名(将转发至后端服务做为主机头首部)、IP地址:端口的方式
 #也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
#示例:
 location /web {
   index index.html;
   proxy_pass http://172.25.254.30:8080; #8080后面无uri,即无 / 符号,
   #需要将location后面url 附加到proxy_pass指定的
url后面
   #此行为类似于root
   #proxy_pass指定的uri不带斜线将访问的/web
   #等于访问后端服务器
   proxy_pass http://172.25.254.40:8080/;   #8080后面有uri,即有 / 符号
   #相当于置换,即访问/web时实际返回proxy_pass后面
uri内容
   #此行为类似于alias 
     #proxy_pass指定的uri带斜线
     #等于访问后端服务器的
     #http://172.25.254.40:8080/index.html
     #内容返回给客户端
 }   # http://nginx/web/index.html ==> 
http://1:8080
#重启Nginx测试访问效果:
#curl -L http://www.timinglee.org/web
#如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能
使用uri
#即不能有/ ,用户请求时传递的uri将直接附加至后端服务器之后
server {
 ...
 server_name HOSTNAME;
 location ~|~* /uri/ {
 proxy_pass http://host:port; #proxy_pass后面的url 不能加/
 }
 ...
 }
 http://HOSTNAME/uri/ --> http://host/uri/
proxy_hide_header field; #用于nginx作为反向代理的时候
 #在返回给客户端http响应时
 #隐藏后端服务器相应头部的信息
 #可以设置在http,server或location块
#示例: 隐藏后端服务器ETag首部字段
 location /web {
   index index.html;
   proxy_pass http://10.0.0.18:8080/; 
   proxy_hide_header ETag;
 }
 proxy_pass_header field; #透传
#默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数
#如果要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端
#field 首部字段大小不敏感
#示例:透传后端服务器的Server和Date首部给客户端,同时不再响应报中显示前端服务器的Server字段
proxy_pass_header Server;
proxy_pass_header Date;
proxy_pass_request_body on | off; 
#是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启
​
proxy_pass_request_headers on | off; 
#是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启
proxy_set_header; 
#可更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实IP的
时候,就要更改每一个报文的头部
#示例: 
 location ~ /web {
   proxy_pass http://172.25.254.20:80;
   proxy_hide_header ETag;
   proxy_pass_header Server;
   proxy_pass_request_body on;
   proxy_pass_request_headers on;
   proxy_set_header X-Forwarded-For $remote_addr;
 }
[root@apache20 ~]# vim /etc/httpd/conf/httpd.conf
 LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%
{User-Agent}i\"" combined
访问后看后端服务器日志
proxy_connect_timeout time;
#配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60秒
用法如下:proxy_connect_timeout 6s; 
#60s为自定义nginx与后端服务器建立连接的超时时间,超时会返回客户端504响应码
proxy_read_timeout time;
#配置nginx服务器向后端服务器或服务器组发起read请求后,等待的超时时间,默认60s
proxy_send_timeout time; 
#配置nginx项后端服务器或服务器组发起write请求后,等待的超时 时间,默认60s
proxy_http_version 1.0; 
#用于设置nginx提供代理服务的HTTP协议的版本,默认http 1.0
proxy_ignore_client_abort off; 
#当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求。即如果此项设置为on开启,则服务器、
会忽略客户端中断并一直等着代理服务执行返回,如果设置为off,则客户端中断后Nginx也会中断客户端请求
并立即记录499日志,默认为off。
6.1.1.2 实战案例: 反向代理单台 web 服务器

要求:将用户对域 www.timinglee.org 的请求转发给后端服务器处理

设置两台主机10.20并安装http服务

在nginx测试

构建代理

[root@nginx_node1 ~]# cd  /usr/local/nginx/conf.d
[root@nginx_node1 conf.d]# vim vhosts.conf

proxy只能访问一台机子

6.1.1.3 实战案例: 指定 location 实现反向代理
6.1.1.3.1 针对指定的 location

[root@node2 ~]# vim /etc/httpd/conf/httpd.conf   之后重启10号机的http服务

 两台机子都可以访问了

6.1.1.3.2 针对特定的资源实现代理

动静分离使用php来实现访问

在10上安装php

[root@node1 ~]# systemctl restart  httpd
[root@node1 ~]# vim /var/www/html/index.php

6.1.1.4 反向代理示例: 缓存功能

缓存功能默认关闭状态,需要先动配置才能启用

proxy_cache zone_name | off; 默认off
#指明调用的缓存,或关闭缓存机制;Context:http, server, location
#zone_name 表示缓存的名称.需要由proxy_cache_path事先定义
proxy_cache_key string;
#缓存中用于“键”的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
#定义对特定响应码的响应内容的缓存时长,定义在http{...}中
 示例:
 proxy_cache_valid 200 302 10m;
 proxy_cache_valid 404 1m;
proxy_cache_path;
#定义可用于proxy功能的缓存;Context:http 
proxy_cache_path path [levels=levels] [use_temp_path=on|off] 
keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number] 
[manager_sleep=time] [manager_threshold=time] [loader_files=number] 
[loader_sleep=time] [loader_threshold=time] [purger=on|off] 
[purger_files=number] [purger_sleep=time] [purger_threshold=time];
#示例:在http配置定义缓存信息
proxy_cache_path /var/cache/nginx/proxy_cache #定义缓存保存路径,proxy_cache会自动创建
   levels=1:2:2 #定义缓存目录结构层次
   #1:2:2可以生成
2^4x2^8x2^8=2^20=1048576个目录
   keys_zone=proxycache:20m     #指内存中缓存的大小,主要用于存放key和metadata
(如:使用次数)
   #一般1M可存放8000个左右的key
   
   inactive=120s       #缓存有效时间
   max_size=10g;     #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
​
#调用缓存功能,需要定义在相应的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key
proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 1m;   #除指定的状态码返回的数据以外的缓存多长时间,必须设置,
否则不会缓存
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | 
http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off
#在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端
#示例
proxy_cache_use_stale error http_502 http_503;
proxy_cache_methods GET | HEAD | POST ...;
#对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
​
6.1.1.4.1 非缓存场景压测
#准备后端httpd服务器
ab -n1000 -c100 http://172.25.254.100/static/index.html

6.1.1.4.2 准备缓存配置
[root@Nginx ~]# vim /apps/nginx/conf/nginx.conf
在http下的gzip on下添加
proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m inactive=120s max_size=1g;
​

image-20240818193240333

[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf

6.1.1.4.3 访问并验证缓存文件

#验证缓存目录结构及文件大小
[root@Nginx ~]# tree /usr/local/nginx/proxy_cache/
/apps/nginx/proxy_cache/
└── e
   └── 50
       └── 99
           └── 319432ef3663735a9d3cb4e0c1d9950e
3 directories, 0 files

6.1.2 http 反向代理负载均衡

在上一个节中Nginx可以将客户端的请求转发至单台后端服务器但是无法转发至特定的一组的服务器,而 且不能对后端服务器提供相应的服务器状态监测,Nginx 可以基于ngx_http_upstream_module模块提 供服务器分组转发、权重分配、状态监测、调度算法等高级功能 官方文档: Module ngx_http_upstream_module

6.1.2.1 http upstream配置参数
#自定义一组服务器,配置在http块内
upstream name { 
 server .....
 ......
}
#示例
upstream backend {
   server backend1.example.com weight=5;
   server 127.0.0.1:8080  max_fails=3 fail_timeout=30s;
   server unix:/tmp/backend3;
   server backup1.example.com backup;
}
server address [parameters];
#配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。
​
#server支持的parameters如下:
weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等
max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制
max_fails=number #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检
测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性
检查,而非周期性的探测
fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再
次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒
backup   #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器
down     #标记为down状态,可以平滑下线后端服务器
resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启
Nginx
​
hash KEY [consistent];
#基于指定请求报文中首部字段或者URI等key做hash计算,使用consistent参数,将使用ketama一致性
hash算法,适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一致
性hash基于取模运算
hash $request_uri consistent; #基于用户请求的uri做hash
hash $cookie_sessionid #基于cookie中的sessionid这个key进行hash调度,实现会话绑定
ip_hash;
#源地址hash调度方法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计算,以实现会话保持
least_conn;
#最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC
6.1.2.2 反向代理示例: 后端多台 web服务器
172.25.254.100  #Nginx 代理服务器
172.25.254.10  #后端web A,Apache部署
172.25.254.20  #后端web B,Apache部署

默认使用轮询调度

[root@nginx_node1 ~]# cd /usr/local/nginx/conf.d
[root@nginx_node1 conf.d]# vim vhosts.conf
[root@nginx_node1 conf.d]# nginx -s reload

测试

ip_hash算法

hash $request_uri consistent; #基于用户请求的uri做hash

测试

实战案例: 基于Cookie 实现会话绑定

6.2 实现 Nginx 四层负载均衡

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

6.2.1 tcp负载均衡配置参数 +DNS

stream { #定义stream相关的服务;
Context:main
   upstream backend { #定义后端服务器
       hash $remote_addr consistent; #定义调度算法
       server backend1.example.com:12345 weight=5; #定义具体server
       server 127.0.0.1:12345      max_fails=3 fail_timeout=30s;
       server unix:/tmp/backend3;
   }
   upstream dns {   #定义后端服务器
       server 10.0.0.1:53;   #定义具体server
       server dns.example.com:53;
   }
   server { #定义server
       listen 12345; #监听IP:PORT
       proxy_connect_timeout 1s; #连接超时时间
       proxy_timeout 3s; #转发超时时间
       proxy_pass backend; #转发到具体服务器组
   }
   server {
       listen 127.0.0.1:53 udp reuseport;
       proxy_timeout 20s;
       proxy_pass dns;
   }
   server {
       listen [::1]:12345;
       proxy_pass unix:/tmp/stream.socket;
   }
}

在 10 20 机上搭建dns

[root@node1 ~]# yum install bind -y
[root@node1 ~]# vim /etc/named.conf

[root@node1 ~]# vim /etc/named.rfc1912.zones

[root@node1 ~]# cd /var/named
[root@node1 named]# cp named.localhost  timinglee.org.zone -p
[root@node1 named]# vim   timinglee.org.zone

[root@node1 named]# systemctl start named
[root@node1 named]# dig www.timinglee.org @172.25.254.10

在node1上配置完成后可以直接传送到node2上

[root@node1 named]# scp -p /tc/name.{conf,rfc1912.zones} root@172.25.254.20:/etc/

[root@node1 named]# scp -p /var/named/timinglee.org.zone root@172.25.254.20:/var/named/timinglee.org.zone
​

在node2中更改

[root@node2 ~]# vim /var/named/timinglee.org.zone

设置代理

 vim /usr/local/nginx/conf/nginx.conf

新建文件
[root@nginx_node1 conf.d]# vim dns.conf

mkdir -p /usr/local/nginx/tcpconf.d
mv dns.conf  /usr/local/nginx/tcpconf.d/

6.2.2 负载均衡实例: MySQL 后端服务器安装 MySQL

[root@node1 named]# yum install mariadb-server -y
[root@node2 named]# yum install mariadb-server -y
[root@node1 ~]# vim /etc/my.cnf
[mysqld]
server-id=10
​
​
[root@node2 ~]# vim /etc/my.cnf
[mysqld]
server-id=20
​
systemctl start mariadb
​
​

设置代理

[root@nginx_node1 tcpconf.d]# vim dns.conf

#测试通过nginx负载连接MySQL:
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
|         20 |
+-------------+
[root@apache30 ~]# mysql -ulee -plee -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
|         30 |
+-------------+

6.3 实现 FastCGI

CGI的由来: 最早的Web服务器只能简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏 览器,也就是静态html文件,但是后期随着网站功能增多网站开发也越来越复杂,以至于出现动态技 术,比如像php(1995年)、java(1995)、python(1991)语言开发的网站,但是nginx/apache服务器并不 能直接运行 php、java这样的文件,apache实现的方式是打补丁,但是nginx缺通过与第三方基于协议实 现,即通过某种特定协议将客户端请求转发给第三方服务处理,第三方服务器会新建新的进程处理用户 的请求,处理完成后返回数据给Nginx并回收进程,最后nginx在返回给客户端,那这个约定就是通用网 关接口(common gateway interface,简称CGI),CGI(协议) 是web服务器和外部应用程序之间的接口 标准,是cgi程序和web服务器之间传递信息的标准化接口。

为什么会有FastCGI? CGI协议虽然解决了语言解析器和 Web Server 之间通讯的问题,但是它的效率很低,因为 Web Server 每收到一个请求都会创建一个CGI进程,PHP解析器都会解析php.ini文件,初始化环境,请求结束的时候 再关闭进程,对于每一个创建的CGI进程都会执行这些操作,所以效率很低,而FastCGI是用来提高CGI性 能的,FastCGI每次处理完请求之后不会关闭掉进程,而是保留这个进程,使这个进程可以处理多个请 求。这样的话每个请求都不用再重新创建一个进程了,大大提升了处理效率。 什么是PHP-FPM? PHP-FPM(FastCGI Process Manager: FastCGI进程管理器)是一个实现了Fastcgi的程序,并且提供进程管理的功能。 进程包括master进程和worker进程。master进程只有一个,负责监听端口,接受来自web server 的请求 worker进程一般会有多个,每个进程中会嵌入一个PHP解析器,进行PHP代码的处理。

6.3.1 FastCGI配置指令

Nginx基于模块ngx_http_fastcgi_module实现通过fastcgi协议将指定的客户端请求转发至php-fpm处 理,其配置指令如下:

fastcgi_pass address:port;
#转发请求到后端服务器,address为后端的fastcgi server的地址,可用位置:location, if in 
location
fastcgi_index name;
#fastcgi默认的主页资源,示例:fastcgi_index index.php;
fastcgi_param parameter value [if_not_empty];
#设置传递给FastCGI服务器的参数值,可以是文本,变量或组合,可用于将Nginx的内置变量赋值给自定义
key
fastcgi_param REMOTE_ADDR        $remote_addr; #客户端源IP
fastcgi_param REMOTE_PORT        $remote_port; #客户端源端口
fastcgi_param SERVER_ADDR        $server_addr; #请求的服务器IP地址
fastcgi_param SERVER_PORT        $server_port; #请求的服务器端口
fastcgi_param SERVER_NAME        $server_name; #请求的server name
Nginx默认配置示例:
   location ~ \.php$ {
     root           /scripts;
     fastcgi_pass   127.0.0.1:9000;
     fastcgi_index index.php;
     fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #默认脚本路径
     #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
     include       fastcgi_params;    #此文件默认系统已提供,存放的相对路径为
prefix/conf
   }

6.3.2 FastCGI实战案例 : Nginx与php-fpm在同一服务器

编译安装更方便自定义参数或选项,所以推荐大家使用源码编译 官方网站:www.php.net

编译安装新的模块

安装php

[root@nginx_node1 ~]# tar zxf php-8.3.9.tar.gz
#利用yum解决php依赖
[root@Nginx ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel 
libpng-devel libcurl-devel oniguruma-devel
​

下载oniguruma-devel

# 服务器能连上网直接通过命令下载oniguruma安装包
wget https://github.com/kkos/oniguruma/archive/v6.9.4.tar.gz -O oniguruma-6.9.4.tar.gz
# 不能连网访问地址:https://github.com/kkos/oniguruma 手动下载oniguruma安装包并上传到服务器
#安装过程
tar -zxvf oniguruma-6.9.4.tar.gz
cd oniguruma-6.9.4 
./autogen.sh && ./configure --prefix=/usr  --libdir=/lib64
make &&; make install 
./autogen.sh && ./configure --prefix=/usr  --libdir=/lib64   #运行时报错提示没有autoreconf命令
 yum install autoconf automake libtool  安装后执行上面操作

编译安装模块

编译完成

make && make install 

php相关配置优化

[root@nginx_node1 ~]# cd /usr/local/php/etc
[root@nginx_node1 etc]# cp php-fpm.conf.default php-fpm.conf
[root@nginx_node1 etc]# vim php-fpm.conf

[root@nginx_node1 etc]# cd php-fpm.d/
[root@nginx_node1 php-fpm.d]# cp www.conf.default www.conf

#生成主配置文件

[root@Nginx php-8.3.9]# cp sapi/fpm/php-fpm.service /lib/systemd/system/
[root@Nginx ~]# vim /usr/local/php/etc/php.ini

​
#生成启动文件
[root@nginx_node1 ~]# cd php-8.3.9
[root@nginx_node1 php-8.3.9]# cd sapi
[root@nginx_node1 sapi]# cd  fpm
[root@nginx_node1 fpm]# ls
config.m4          LICENSE        php-fpm.conf        status.html.in
CREDITS            Makefile.frag  php-fpm.conf.in     tests
fpm                php-fpm        php-fpm.service     www.conf
init.d.php-fpm     php-fpm.8      php-fpm.service.in  www.conf.in
init.d.php-fpm.in  php-fpm.8.in   status.html
[root@nginx_node1 fpm]# vim php-fpm.service
[root@nginx_node1 fpm]# cp php-fpm.service /lib/systemd/system

Nginx配置转发 Nginx安装完成之后默认生成了与fastcgi的相关配置文件,一般保存在nginx的安装路径的conf目录当 中,比如/apps/nginx/conf/fastcgi.conf、/apps/nginx/conf/fastcgi_params。

[root@nginx_node1 ~]# cd /usr/local/nginx/conf.d
[root@nginx_node1 conf.d]# vim vhosts.conf

添加php环境变量

[root@nginx_node1 ~]# cd /usr/local/php/bin
[root@nginx_node1 bin]# vim ~/.bash_profile

准备php测试页面

[root@nginx_node1 ~]# mkdir /data/php -p
[root@nginx_node1 ~]# vim /data/php/index.php

6.3.3 php的动态扩展模块(php的缓存模块)

软件下载:PECL :: Package :: memcache

安装memcache模块

配置php加载memcache模块

[root@nginx_node1 ~]# vim /usr/local/php/etc/php.ini

复制测试文件到nginx发布目录中

[root@Nginx ~]# cd memcache-8.2/
[root@Nginx memcache-8.2]# ls
[root@nginx_node1 memcache-8.2]# cp example.php memcache.php /data/php/
[root@nginx_node1 ~]# vim /data/php/memcache.php

部署memcached

[root@Nginx ~]# yum install memcached -y
[root@Nginx ~]# systemctl enable --now memcached.service
[root@nginx_node1 ~]# vim /etc/sysconfig/memcached

[root@nginx_node1 ~]# netstat -antlupe | grep memcache

访问 http://php.timinglee.org/example.php 不断刷新

访问 http://php.timinglee.org/memcache.php 查看命中效果

6.3.4 php高速缓存

[root@Nginx ~]# cd nginx-1.26.1/
[root@Nginx nginx-1.26.1]# ./configure --prefix=/usr/local/nginx --user=nginx --
group=nginx --with-http_ssl_module --with-http_v2_module --withhttp_realip_module
 --with-http_stub_status_module --with-http_gzip_static_module 
--with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --
add-module=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module0.33
[root@Nginx nginx-1.26.1]# make && make install
[root@nginx_node1 ~]# cd /usr/local/nginx/conf
[root@nginx_node1 conf]# vim vhosts.conf

[root@nginx_node1 ~]# systemctl start nginx.service

测试结果:

[root@apache20 ~]# ab -n500 -c10 www.timinglee.org/index.php
Concurrency Level:     10
Time taken for tests:   0.255 seconds
Complete requests:     500
Failed requests:       0

7 nginx 二次开发版本

7.1 openresty

Nginx 是俄罗斯人发明的, Lua 是巴西几个教授发明的,中国人章亦春把 LuaJIT VM 嵌入到 Nginx 中, 实现了 OpenResty 这个高性能服务端解决方案 OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方 模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服 务和动态网关。 OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言 调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高 性能 Web 应用系统。 OpenResty 由于有功能强大且方便的的API,可扩展性更强,如果需要实现定制功能,OpenResty是个不错的 选择 官网: OpenResty® - 开源官方站

7.2 编译安装 openresty

[root@Nginx ~]#dnf -yq install gcc pcre-devel openssl-devel perl
[root@Nginx ~]#useradd -r -s /sbin/nologin nginx
[root@Nginx ~]#cd /usr/local/src
[root@Nginx src]#wget https://openresty.org/download/openresty-1.17.8.2.tar.gz
[root@Nginx src]#tar xf openresty-1.17.8.2.tar.gz 
[root@Nginx src]#cd openresty-1.17.8.2/
[root@Nginx openresty-1.17.8.2]#./configure \
--prefix=/usr/local/openresty \
--user=nginx --group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module 
--with-pcre --with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
[root@Nginx openresty-1.17.8.2]#make && make install
[root@nginx_node1 openresty-1.25.3.1]# ln -s /usr/local/openresty/bin/* /usr/bin/
[root@nginx_node1 openresty-1.25.3.1]# openresty -v

[root@nginx_node1 ~]# vim .bash_profile

[root@Nginx ~]#curl 172.25.254.100

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2053704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

循环图神经网络教程2——循环图神经网络

介绍 循环图神经网络(Recurrent Graph Neural Network,RGNN)。在标准神经网络中,连续的学习权重层用于从输入张量中逐步提取更高级别的特征。在用于计算机视觉的神经网络中,低级特征(如短直线和曲线)的存在是由较早的…

Java类的卸载

类、类的加载器、类的实例之间的引用关系 类的生命周期 类的加载器如下:

进程部分相关概念

进程 进程是一个程序执行的过程,会去分配内存资源,cpu的调度 进程不仅仅是一个正在运行的程序,它包含了程序执行所需的所有资源和状态信息 资源分配:操作系统会为每个进程分配必要的资源,如内存空间、文件句柄等。这些…

nginx重定向与防盗链

重定向 由于网站的扩容,负荷较大,需要将一部分内容迁移到其他服务器上。但是这个时候又不能更改用户常访问的域名,因此对其进行重定向。 1. 域名重定向 www.sxl1.com/aaa的站点需要重定向到aaa.sxl1.com rewrite ^/aaa$ aaa.sxl1.com/…

letcode 分类练习 513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树

letcode 分类练习 513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树 513.找树左下角的值112. 路径总和106.从中序与后序遍历序列构造二叉树 513.找树左下角的值 遍历二叉树,并记录当前的深度,如果深度大于最大深度,那么…

关于 Vivado HLS 的三大误读

【转载】关于 Vivado HLS 的三大误读 目前,在高层次综合(HLS, High Level Synthesis)领域,Vivado HLS可谓独树一帜。它有效地拉近了软件工程师与FPGA之间的距离,加速了算法开发的进程,缩短了产品上市时间。…

leetcode_52. N 皇后 II

52. N 皇后 II 题目描述:n 皇后问题 研究的是如何将 n 个皇后放置在 n n 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回 n 皇后问题 不同的解决方案的数量。 示例 1: 输入:n 4 输出:2…

C++:病毒系列回归记2/3 (Doge智能系统已上线)

上一期:C:病毒系列回归记1/3 (Doge智能系统已上线) 这一步真的非常爽哦 void Crazy(int n) {if(n 0)system("start ラム.vbs");if(n 1)system("start 今年のトラック.vbs");if(n 2)system("start ロシアのスートン焼却発電.vbs")…

安装并配置开发环境

安装并配置开发环境 获取虚拟机系统 下载vmware虚拟机工具 使用浏览器打开网址 https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html 参考下图箭头所示,点击下载安装 Windows版本的VMware Workstation ,点击 DOWNLOAD …

java基础--day10字符串

视频网址:字符串-01-API和API帮助文档_哔哩哔哩_bilibili 1.API 1.1API概述 什么是PAI API (Application Programming Interface) :应用程序编程接口 java中的API 指的就是 JDK 中提供的各种功能的 Java类,这些类将底层的实现封装了起来&am…

MySQL笔记01: MySQL入门_1.3 MySQL启动停止与登录

1.3 MySQL启动停止与登录 1.3.1 MySQL启动与停止 MySQL数据库分为客户端和服务器端,只有服务器端服务开启以后,才可以通过客户端登录MySQL服务端。 首先,以管理员身份运行“命令提示符”: (1)启动MySQL服务…

AArch64中的寄存器

目录 通用寄存器 其他寄存器 系统寄存器 通用寄存器 大多数A64指令在寄存器上操作。该架构提供了31个通用寄存器。 每个寄存器可以作为64位的X寄存器(X0..X30)使用,或者作为32位的W寄存器(W0..W30)使用。这两种是查…

PyTorch——transforms

接着上一篇,我们这一篇讲transforms 1、什么是transform 首先transform是来自PyTorch的一个扩展库——【torchvision】,【torchvision】这个库提供了许多计算机视觉相关的工具和功能,能够在神经网络中,将图像、数据集、预处理模型…

[Winform] Chart获得当前点的X和Y值

在利用C#控件绘制曲线图后,有时我们需要通过鼠标查看数据点的值信息,常用的方法就是利用chart控件的chart1_GetToolTipText(object sender, ToolTipEventArgs e)事件来获取数据点的信息,如下我用两个label来显示获取的数据点的值 相关代码如下…

【手撕数据结构】链式二叉树

目录 链式二叉树的结构及其声明链式二叉树的四种遍历方式前序遍历中序遍历(中根遍历)后序遍历层序遍历概念思路分析详细代码 求树的节点个数变量累加法(错误)分治递归法 求树的叶子节点个数警惕空指针正确代码 求第k层节点个树思路分析及规则明细代码详细…

POK´ELLMON:在宝可梦战斗中实现人类水平的人工智能

人工智能咨询培训老师叶梓 转载标明出处 最近,由美国乔治亚理工学院的Sihao Hu、Tiansheng Huang和Ling Liu发表的论文介绍了POKELLMON,这是一个开创性的基于大模型(LLM)的具身智能体,它在战术战斗游戏中,特…

【Android 笔记】Android APK编译打包流程

前言 本文将介绍Android从一个项目打包成APK的过程,其中涉及Android Java和Kotlin文件、资源文件、清单文件、依赖jar包和so库等在打包过程中处理。 步骤 总体的打包流程如下图,下面就介绍下详细的打包步骤。 1、将aidl文件编译成java文件 在构建过程中…

2024音频剪辑指南:探索四大高效工具!

音频剪辑不仅仅是技术活,更是一种艺术创作,它能够让声音更加生动、更具感染力。今天,我们就来探索几款优秀的音频剪辑工具。 福昕音频剪辑 链接:www.pdf365.cn/foxit-clip/ 福昕音频剪辑是一款界面简洁、操作直观的音频编辑软件…

详解安卓辅助功能服务AccessibilityService(无障碍服务,微信抢红包助手原理)

前言 在手机的更多设置或者高级设置中,我们会发现有个无障碍的功能,很多人不知道这个功能具体是干嘛的,包括我们开发也很少接触这部分功能,以至于对这块不甚了解。前段时间在同事的安利下去了解了下这部分功能。在这里和大家浅谈下…

scikit-learn特征预处理

特征预处理 什么是特征预处理 通过一些转换函数,将特征数据转换成更适合算法模型的特征数据的过程 数值数据的无量纲化: 归一化标准化 特征预处理API sklearn.preprocessing为什么进行无量纲化 通过欧式距离公式计算两个约会对象是否属于同一类别 …