一文带你了解如何部署高性能Nginx

1. Nginx 概述

1.1 Nginx 介绍

Nginx 诞生于 2002 年,现分为社区版和商业版

Nginx是免费的、开源的、高性能的HTTP和反向代理服务器、邮件代理服务器、以及TCP/UDP代理服务器

Nginx 其他二次发行版:

  • Tengine:由淘宝网发起的Web服务器项目,性能和稳定性已经在大型的网站(淘宝网,天猫商城等)得到了很好的检验
    • 最终目标是打造一个高效、稳定、安全、易用的Web平台
  • OpenResty:基于Nginx 与 Lua 语言的高性能 Web 平台,章亦春团队开发

1.2 Nginx 功能

  • 静态的Web资源服务器HTML,图片,JS,CSS,TXE等静态资源
  • HTTP/HTTPS协议的反向代理
  • 结合 FastCGI / UWSGI / SCGI 等协议反向代理动态资源请求
  • TCP/UDP协议的请求转发(反向代理)
  • imap4/pop3协议的反向代理

基础特性

  • 模块化设计,较好的扩展性
  • 高可靠性
  • 支持热部署文件:不停机更新配置文件,升级版本,更换日志文件
  • 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存

Web 服务相关的功能

  • 虚拟主机
  • 支持 keep-alive 和 管道连接(利用一个连接做多次请求)
  • 访问日志(支持基于日志缓冲提高其性能)
  • URL rewirte
  • 路径别名
  • 基于IP及用户的访问控制
  • 支持速率限制及并发数限制
  • 重新配置和在线升级而不中断客户的工作进程

1.3 Nginx 架构和进程

在这里插入图片描述

1.4 Nginx 进程结构

Web请求处理机制

多进程方式:服务器每接收到一个客户端请求,服务器的主进程生成一个子进程响应客户端,直到用户关闭连接

这样的优势是处理速度快,子进程之间相互独立,但如果访问过大,导致服务器资源耗尽而无法提供请求

多线程方式:与多进程方式类似,但是每收到一个客户端请求,会有服务进程派生出一个线程与客户端进行交互

一个线程的开销远小于一个进程,故多线程方式很大程度减轻web服务器对系统资源的要求,但多线程也有缺点

当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,因此线程之间相互影响

一旦主进程挂掉,则所有子线程都会下线,需要间隔一段时间就重启一次才能稳定


Nginx 是多进程组织模型,由Master 主进程和Worker 工作进程组成

在这里插入图片描述

主进程(Master Process)功能

  • 对外接口:接收外部的操作(信号)
  • 对内转发:根据外部的操作的不同,通过信号管理 Worker
  • 监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
  • 读取Nginx 配置文件并验证其有效性和正确性
  • 建立、绑定和关闭socket连接
  • 按照配置生成、管理和结束工作进程
  • 接受外界指令,比如重启、升级及退出服务器等指令
  • 不中断服务,实现平滑升级,重启服务并应用新的配置
  • 开启日志文件,获取文件描述符
  • 不中断服务,实现平滑升级,升级失败进行回滚处理
  • 编译和处理perl脚本

工作进程(Worker Process))功能

  • 所有 Worker 进程都是平等的
  • 实际处理:网络请求,由 Worker 进程处理
  • Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争CPU资源,增加上下文切换的损耗
  • 接受处理客户的请求
  • 将请求依次送入各个功能模块进行处理
  • I/O调用,获取响应数据
  • 与后端服务器通信,接收后端服务器的处理结果
  • 缓存数据,访问缓存索引,查询和调用缓存数据
  • 发送请求结果,响应客户的请求
  • 接收主程序指令,比如重启、升级和退出等

在这里插入图片描述

1.5 Nginx 进程间通信

工作进程是由主进程生成的,主进程使用fork()函数,在Nginx服务器启动过程中,主进程根据配置文件决定启动工作进程的数量

然后建立一张全局的工作表用于存放当前未退出的所有的工作进程,主进程生成工作进程后,将新生成的工作进程加入到工作进程表中,并建立一个单向的管道并将其传递给工作进程

该管道与普通的管道不同,它是由主进程指向工作进程的单向通道,包含了主进程向工作进程发出的指令、工作进程ID、工作进程在工作进程表中的索引和必要的文件描述符等信息

主进程与外界通过信号机制进行通信,当接收到需要处理的信号时,它通过管道向相关的工作进程发送正确的指令,每个工作进程都有能力捕获管道中的可读事件,当管道中有可读事件的时候,工作进程就会从管道中读取并解析指令,然后采取相应的执行动作,这样就完成了主进程与工作进程的交互

在这里插入图片描述

Nginx 启动和 HTTP 连接建立

在这里插入图片描述

  • Nginx 启动时,Master 进程,加载配置文件
  • Master 进程,初始化监听的 socket
  • Master 进程,fork 出多个 Worker 进程
  • Worker 进程,竞争新的连接,获胜方通过三次握手,建立 Socket 连接,并处理请求

1.6 HTTP 处理过程

在这里插入图片描述

1.7 Nginx 模块

Nginx高度模块化,但其模块早期不支持DSO机制;1.9.11 版本支持动态装载和卸载

模块说明
核心模块是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件
驱动机制 、进程管理等核心功能
标准HTTP模块提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应
头设置 等等
可选HTTP模块主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如: Flash
多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
邮件服务模块主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的
支持
Stream服务模块实现反向代理功能,包括TCP协议代理
第三方模块是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支
持等

模块顺序

核心模块:core module
标准模块:
 HTTP 模块: ngx_http_*
    HTTP Core modules		# 默认功能
    HTTP Optional modules	# 需编译时指定
 Mail 模块: ngx_mail_*
 Stream 模块 ngx_stream_*
第三方模块

在这里插入图片描述

2. Nginx 安装

2.1 Nginx 版本

  • Mainline version 主要开发版本,一般为奇数版本号,比如1.19
  • Stable version 当前最新稳定版,一般为偶数版本,如:1.20
  • Legacy versions 旧的稳定版,一般为偶数版本,如:1.18

2.2 源码安装

安装方式:源码安装

  • Yum的版本比较旧
  • 编译安装可以更方便自定义相关路径
  • 使用源码编译可以自定义相关功能,更方便业务的上的使用

nginx依赖组件

组件(仅需要软件中的库,而不是软件本身)说明
gcc标准的编译器
pcre第三方库,支持rewrite
openssl第三方库,支持gzip模块
zlib第三方库,支持ssl模块

开始安装

wget https://nginx.org/download/nginx-1.24.0.tar.gz	# 建议在Windows主机下载后,上传虚拟机
vim /root/nginx-1.24.0/auto/cc/gcc	# 关闭debug功能,减小内存占用
...
# debug
# CFLAGS="$CFLAGS -g"
...

dnf install gcc pcre-devel openssl-devel zlib-devel -y	# 安装依赖
useradd -s /sbin/nologin -M nginx	# 为Nginx添加用户

./configure --prefix=/usr/local/nginx --add-module=/root/echo-nginx-module-0.63 --add-module=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module-0.33 --user=nginx --group=nginx --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-stream --with-stream_ssl_module --with-http_ssl_module --with-stream_realip_module --with-pcre	#	添加模块、检查依赖(环境检测)

make && make install	# 进行编译

vim ~/.bash_profile		# 添加nginx命令路径,方便使用
# User specific environment and startup programs
export PATH=$PATH:/usr/local/nginx/sbin

source ~/.bash_profile
/usr/local/nginx/sbin/nginx	# 启动nginx

效果演示

[root@ngxinx ~]# curl -I 172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 20 Aug 2024 05:43:33 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 20 Aug 2024 05:37:17 GMT
Connection: keep-alive
ETag: "66c42b8d-267"
Accept-Ranges: bytes

模块介绍

模块说明
–prefix=/usr/local/nginx指定nginx安装路径
–user=nginx指定nginx运行用户
–group=nginx指定nginx运行组
–with-http_ssl_module支持https://
–with-http_v2_module支持http版本2
–with-http_realip_module支持ip透传
–with-http_stub_status_module支持状态页面
–with-http_gzip_static_module支持压缩
–with-pcre支持正则
–with-stream支持tcp反向代理
–with-stream_ssl_module支持tcp的ssl加密
–add-module=/root/echo-nginx-module-0.63nginx调试模块
–add-module=/root/memc-nginx-module-0.20扩展memcache模块
–add-module=/root/srcache-nginx-module-0.33增加基于subrequest的缓存层

重新检测:make clean(在nginx-1.24.0目录下)

make install : 将环境检测完成后的objs目录拷贝到指定的路径下(prefix=xxx)

卸载nginx(删除指定的路径prefix=xxx且在nginx-1.24.0目录下执行make clean)

目录介绍

ls /usr/local/nginx/
conf	html	logs	sbin 
目录说明
conf保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他
的.conf则是用来配置nginx相关的功能的
html保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web
文件是默认的错误页面提示页面
logs用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径
sbin保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能

查看nginx版本及模块

vim ~/.bash_profile
export PATH=$PATH:/usr/local/nginx/sbin

source  ~/.bash_profile
nginx -V	# 显示nginx版本及添加的模块

3. nginx 简单应用

3.1 Nginx 平滑升级

流程及原理

在这里插入图片描述在这里插入图片描述

  • 将旧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

配置

wget https://nginx.org/download/nginx-1.26.2.tar.gz
tar zxf nginx-1.26.2.tar.gz

vim auto/cc/gcc	# 关闭debug功能
# debug
# CFLAGS="$CFLAGS -g"

cd /root/nginx-1.26.2
./configure --prefix=/usr/local/nginx --add-module=/root/echo-nginx-module-0.63 --add-module=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module-0.33 --user=nginx --group=nginx --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-stream --with-stream_ssl_module --with-http_ssl_module --with-stream_realip_module --with-pcre

make	# 不能make install!!!
ll objs/nginx /usr/local/nginx/sbin/nginx
-rwxr-xr-x 1 root root 6144176 Aug 15 12:52 objs/nginx	# 新版本Nginx
-rwxr-xr-x 1 root root 1229024 Aug 15 12:25 /usr/local/nginx/sbin/nginx	# 旧版本且正在运行的Nginx
cd /usr/local/nginx/sbin/	# 将旧版本的Nginx进行备份,防止误操作
cp nginx nginx.1.24.0.old

\cp -f /root/nginx-1.26.2/objs/nginx /usr/local/nginx/sbin/	# 将新版本的Nginx 复制并覆盖 旧版本的Nginx

ps aux | grep nginx	# 查看当前旧版本Nginx运行的 进程号
root       40034  0.0  0.0   9864  2052 ?        Ss   12:31   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      40035  0.0  0.1  14196  5252 ?        S    12:31   0:00 nginx: worker process
root       43517  0.0  0.0   6408  2048 pts/1    S+   12:58   0:00 grep --color=auto nginx

kill -USR2 40034	# 40034 为nginx: worker process的进程号
ps aux | grep nginx	# 查看新旧版本的进程号,此时有两个master process和worker process,但只有新Nginx在监听端口;此时旧Nginx的进程不会退出,只是当接收到新的请求不作处理而是交给新Nginx进程处理
root       40034  0.0  0.0   9864  2436 ?        Ss   12:31   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      40035  0.0  0.1  14196  5252 ?        S    12:31   0:00 nginx: worker process
root       43518  0.0  0.1   9764  6528 ?        S    12:59   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      43519  0.0  0.1  14228  5004 ?        S    12:59   0:00 nginx: worker process
root       43521  0.0  0.0   6408  2176 pts/1    S+   12:59   0:00 grep --color=auto nginx
[root@nginx objs]# kill -WINCH 40034	# 将旧Nginx进程的worker process进行回收
[root@nginx objs]# ps aux | grep nginx
root       40034  0.0  0.0   9864  2436 ?        Ss   12:31   0:00 nginx: master process /usr/local/nginx/sbin/nginx
root       43518  0.0  0.1   9764  6528 ?        S    12:59   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      43519  0.0  0.1  14228  5004 ?        S    12:59   0:00 nginx: worker process
root       43541  0.0  0.0   6408  2176 pts/1    S+   13:01   0:00 grep --color=auto nginx

# 确认使用新版本的Nginx,可以使用kill -9 43518,将旧Nginx的master process杀掉,此时就只剩下新Nginx的进程

效果演示

[root@ngxinx ~]# curl -I 172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.26.2
Date: Tue, 20 Aug 2024 06:08:38 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 20 Aug 2024 05:37:17 GMT
Connection: keep-alive
ETag: "66c42b8d-267"
Accept-Ranges: bytes

3.2 Nginx 平滑回滚

cd /usr/local/nginx/sbin/
cp nginx nginx.1.26.2.new	# 备份当前使用的nginx
\cp -f nginx.1.24.0.old nginx	# 旧版本nginx覆盖新版本nginx
ps aux | grep nginx	# 查看旧nginx的进程号
kill -USR2 xxx	# xxx:旧nginx的进程号
ps aux | grep nginx	# 查看是否生成新nginx的master process
kill -WINCH xxx	# xxx:旧nginx的进程号;回收旧nginx的worker process
ps aux | grep nginx	# 查看是否成功回收
kill -9 xxx	# xxx:旧nginx的进程号
ps aux | grep nginx	# 查看是否杀死旧nginx

效果演示

[root@ngxinx ~]# curl -I 172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 20 Aug 2024 06:18:23 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 20 Aug 2024 05:37:17 GMT
Connection: keep-alive
ETag: "66c42b8d-267"
Accept-Ranges: bytes

3.3 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

systemctl daemon-reload	# 加载配置
nginx -s stop
systemctl enable --now nginx	# 设置开机启动

4. nginx 核心配置

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

nginx 配置文件的组成

  • 主配置文件:nginx.conf
  • 子配置文件: include conf.d/*.conf
  • fastcgi, uwsgi,scgi 等协议相关的配置文件

nginx 配置文件格式说明

  • 配置文件由指令与指令块构成
  • 每条指令以 ; 分号结尾,指令与值之间以空格符号分隔
  • 可以将多条指令放在同一行,用分号分隔即可
  • 指令块以{ }大括号将多条指令组织在一起
  • include语句允许组合多个配置文件以提升可维护性
  • 使用#符号添加注释,提高可读性
  • 使用$符号使用变量
  • 部分指令的参数支持正则表达式

Nginx 主配置文件的配置指令方式:

directive value [value2 ...];

注意

  • 指令必须以分号结尾
  • 支持使用配置变量
    • 内建变量:由Nginx模块引入,可直接引用
    • 自定义变量:由用户使用set命令定义,格式: set variable_name value;
    • 引用变量:$variable_name

主配置文件结构:四部分

main block:主配置段,即全局配置段,对http,mail都有效

# 事件驱动相关的配置
event {
 ...
}

# http/https 协议相关配置段
http {
 ...
} 

# 默认配置文件不包括下面两个块
# mail 协议相关配置段
mail {
 ...
}

#stream 服务器相关配置段
stream {
 ...
} 

nginx.conf 配置文件说明

#全局配置端,对全局生效,主要设置nginx的启动用户/组,启动的工作进程数量,工作模式,Nginx的PID路径,日志路径等
user nginx nginx;
worker_processes  1;    #启动工作进程数数量
events {	#events设置快,主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多个网络连接,使用哪种事件驱动模型                        

worker_connections  1024;	#处理请求,每个工作进程可以同时支持的最大连接数,是否开启对多工作进程下的网络连接进行序列化等。#设置单个nginx工作进程可以接受的最大并发,作为web服务器的时候最大并发数为                                           # worker_connections * 
worker_processes,作为反向代理的时候为
                                 #(worker_connections * worker_processes)/2
}

http {                          #http块是Nginx服务器配置中的重要部分,缓存、代理和日志格式定义等绝大多数功能和第三方模块都                                #可以在这设置,http块可以包含多个server块,而一个server块中又可以包含多个location块,
                                #server块可以配置文件引入、MIME-Type定义、日志自定义、是否启用sendfile、连接超时时间和                                 #单个链接的请求上限等。
include       mime.types;
default_type application/octet-stream;
sendfile       on;           #作为web服务器的时候打开sendfile加快静态文件传输,指定是否使用
                                #sendfile系统调用来传输文件
                                #sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作)
                                #从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝,硬盘 >> kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈
keepalive_timeout  65;       #长连接超时时间,单位是秒
server {                     #设置一个虚拟机主机,可以包含自己的全局快,同时也可以包含多个location模块
                             #比如本虚拟机监听的端口、本虚拟机的名称和IP配置,多个server 可以使用一个端口如都使用80端口提供web服务
       listen       80;      #配置server监听的端口
       server_name localhost;   #本server的名称,当访问此名称的时候nginx会调用当前serevr内部的配置进程匹配。
       
       location / {             #location其实是server的一个指令,为nginx服务器提供比较多而且灵活的指令
                                #都是在location中体现的,主要是基于nginx接受到的请求字符串
                                #对用户请求的UIL进行匹配,并对特定的指令进行处理
                                #包括地址重定向、数据缓存和应答控制等功能都是在这部分实现
                                #另外很多第三方模块的配置也是在location模块中配置。
                                
           root   html;         #相当于默认页面的目录名称,默认是安装目录的相对路径,可以使用绝对路径配置。
           index index.html index.htm;          #默认的页面文件名称
                 }
       error_page   500 502 503 504 /50x.html;  #错误页面的文件名称
       location = /50x.html {                   #location处理对应的不同错误码的页面定义到/50x.html
                                                #这个跟对应其server中定义的目录下。
           root   html;                         #定义默认页面所在的目录
       }
   }
    
#和邮件相关的配置
#mail {
#               ...
#       }         mail 协议相关配置段

#tcp代理配置,1.9版本以上支持
#stream {
#               ...
#       }       stream 服务器相关配置段
#导入其他路径的配置文件
#include /apps/nginx/conf.d/*.conf
}

4.1 全局配置

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
            
# 错误日志记录配置,语法: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的值保持一致
                            
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
}

4.2 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;
}

5. nginx 进阶实战

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

5.1 首个Nginx-Web 站点

生产中存在多个Web站点,放在一起显得十分杂乱

推荐使用子配置文件,便于配置、维护

vim /usr/local/nginx/conf/nginx.conf	# 添加子配置文件,使用epoll模式
events {
    worker_connections  1024;
    use epoll;
}
...
#gzip  on;
include "/usr/local/nginx/conf.d/*.conf";
...

mkdir -p /usr/local/nginx/conf.d/
vim /usr/local/nginx/conf.d/vhost.conf
server {
        listen 80;
        server_name www.timinglee.org;
        root /data/web/html;
        index index.html;
}

mkdir -p /data/web/html
echo 172.25.254.100 > /data/web/html/index.html	# 设置测试页内容
nginx -s reload

# 在Windows主机上添加IP	www.timinglee.org的解析(C:\Windows\System32\drivers\etc\hosts)

Root 与 Alias

  • Root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location
  • alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于 location上下文,此指令使用较少

root 给定的路径对应于location中的/URL的左侧 /

root /data/web = location / # 将root location / index.html 作为主页

alias #给定的路径对应于location中的/URL的完整路径

alias /data/web/test1 = /data/web/test1

效果演示

浏览器输入www.timinglee.org

在这里插入图片描述

5.2 location 的详细使用

在一个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前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号

#匹配优先级从高到低:
=, ^~, ~/~*, 不带符号

5.3 Nginx 用户认证

由 ngx_http_auth_basic_module 模块提供此功能

yum -y install httpd-tools

htpasswd -cm /usr/local/nginx/.htpasswd admin	# c:创建.htpasswd文件,m:更改
htpasswd -m /usr/local/nginx/.htpasswd xxx	# 当有.htpasswd文件的前提下,参数不用加c
cat /usr/local/nginx/.htpasswd	# 查看是否生成
admin:$apr1$ryQ2HRhF$aq98Hn65S7T5hu679l2jN0
xxx:$apr1$fqSKUegg$aTlSf06/HHIwGfOnOJM.x.

vim /usr/local/nginx/conf.d/vhost.conf
server {
    listen 80;
    server_name www.cupest.org;
    root /data/web/html;
    index index.html;

    location /xxx {
        root /data/web;
        auth_basic "login password!!!";
        auth_basic_user_file "/usr/local/nginx/.htpasswd";	# 认证使用的文件
    }
}
mkdir /data/web/xxx
echo user-passwd > /data/web/xxx/index.html
nginx -s reload

效果演示

在这里插入图片描述

在这里插入图片描述

5.4 Nginx 自定义错误页面

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

vim /usr/local/nginx/conf.d/vhost.conf
server{
        listen 80;
        server_name www.timinglee.org;
        root /data/web/html;
        index index.html;
        error_page 404 /40x.html;

        location = /40x.html {
            root /data/web/errorpage;
        }
}

mkdir -p /data/web/errorpage
echo code 404 > /data/web/errorpage/40x.html
nginx -s reload

效果演示

在这里插入图片描述

5.5 Nginx 自定义错误日志

vim /usr/local/nginx/conf.d/vhost.conf
server {
        listen 80;
        server_name www.timinglee.org;
        root /data/web/html;
        index index.html;
        error_log   /var/log/timinglee.org/error.log;
        access_log  /var/log/timinglee.org/access.log;
}

mkdir /var/log/timinglee.org
nginx -s reload

# 浏览器访问www.timinglee.org
cat /var/log/timinglee.org/error.log
cat /var/log/timinglee.org/access.log
# 有内容,即成功配置

5.6 Nginx 检测文件是否存在

try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹)

如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数

只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向

最后一个参数是回退URI且必须存在,否则会出现内部500错误

vim /etc/hosts
172.25.254.100  www.timinglee.org

vim /usr/local/nginx/conf.d/vhost.conf
server {
        listen 80;
        server_name www.timinglee.org;
        root /data/web/html;
        index index.html;
        try_files $uri $uri.html $uri/index.html /error/default.html;
}

nginx -s reload
rm -rf /data/web/html/index.html

curl www.timinglee.org
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.24.0</center>
</body>
</html>

mkdir /data/web/html/error
echo error default > /data/web/html/error/default.html

curl www.timinglee.org
error default

检测文件顺序

5.6 Nginx 长连接配置

keepalive_timeout timeout [header_timeout];     #设定保持连接超时时长,0表示禁止长连接,
默认为75s
                                                #通常配置在http字段作为站点全局配置

keepalive_requests 数字;                      #在一次长连接上所允许请求的资源的最大数量
                                                #默认为100次,建议适当调大,比如:500
vim /usr/local/nginx/conf/nginx.conf
#keepalive_timeout  0;
keepalive_timeout  5;	# 长连接保持时间

nginx -s reload
echo 172.25.254.100 > /data/web/html/index.html
dnf install telnet -y	# 测试工具

# 效果演示
telnet www.timinglee.org 80
GET / HTTP/1.1
HOST: www.timinglee.org	# 输入完毕后,回车两次

HTTP/1.1 200 OK
...
172.25.254.100
Connection closed by foreign host.	# 等待5s后,长连接断开
-------------------------------------------------------
vim /usr/local/nginx/conf/nginx.conf
#keepalive_timeout  0;
keepalive_timeout  65 60;	# 65:长连接保持时间	60:用户看见的长连接保持时间

nginx -s reload

# 效果演示
telnet www.timinglee.org 80
GET / HTTP/1.1
HOST: www.timinglee.org

...
Keep-Alive: timeout=60
...
-------------------------------------------------------
vim /usr/local/nginx/conf/nginx.conf
#keepalive_timeout  0;
keepalive_timeout  65 60;
keepalive_requests 2;	# 发送长连接请求的次数,一般设置在500+

nginx -s reload

# 效果演示
telnet www.timinglee.org 80
GET / HTTP/1.1
HOST: www.timinglee.org

...
172.25.254.100	# 第一次发送长连接结束
GET / HTTP/1.1
HOST: www.timinglee.org

...
172.25.254.100	# 第二次发送长连接结束
Connection closed by foreign host.	# 当两次请求过后,长连接断开

5.7 Nginx 下载服务器配置

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;两个同时设置,此项优先级高
mkdir /data/web/download
dd if=/dev/zero of=/data/web/download/xyzfile bs=1M count=100	#	生成一个100M文件
vim /usr/local/nginx/conf.d/vhost.conf
server {
        listen 80;
        server_name www.timinglee.org;
        root /data/web/html;
        index index.html;
        try_files $uri $uri.html $uri/index.html /error/default.html;

        location /download {
            root /data/web;
            autoindex on;	# 关键参数
        }
}

curl www.timinglee.org/download/	# 没有此页面
error default

nginx -s reload
curl www.timinglee.org/download/	# 重载配置后,有下载文件
<html>
<head><title>Index of /download/</title></head>
<body>
<h1>Index of /download/</h1><hr><pre><a href="../">../</a>
<a href="xyzfile">xyzfile</a>                                            20-Aug-2024 08:10           104857600
</pre><hr></body>
</html>
-------------------------------------------------------
# 可以看见页面的时间是不正确的(格林威治标准时间)
vim /usr/local/nginx/conf.d/vhost.conf
....
        location /download {
            root /data/web;
            autoindex on;
            autoindex_localtime on;	# 显示Linux主机时间
        }
...
nginx -s reload
# 效果演示
curl www.timinglee.org/download/
....20-Aug-2024 16:10	104857600....
-------------------------------------------------------
# 可以看见页面的文件大小的单位,不是很好理解
vim /usr/local/nginx/conf.d/vhost.conf
....
        location /download {
            root /data/web;
            autoindex on;
            autoindex_localtime on;
            autoindex_exact_size off;	# 显示文件的粗略大小,默认开启详细大小
        }
...
nginx -s reload
# 效果演示
curl www.timinglee.org/download/
...20-Aug-2024 16:10    100M...
-------------------------------------------------------
wget www.timinglee.org/download/xyzfile
xyzfile		100%[===================================>] 100.00M   244MB/s    in 0.4s
# 可以看见下载速度非常快,这对服务器的负担非常大
vim /usr/local/nginx/conf.d/vhost.conf
....
        location /download {
            root /data/web;
            autoindex on;
            autoindex_localtime on;
            autoindex_exact_size off;
            limit_rate 1024k;	# 限制下载速度
        }
...
nginx -s reload
# 效果演示
wget www.timinglee.org/download/xyzfile
xyzfile.1		4%[>                                   ]   4.00M  1.01MB/s    eta 95s

6. nginx 高级应用

6.1 Nginx 状态页

基于nginx 模块 ngx_http_stub_status_module 实现

在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module

否则配置完成之后监测会是提示法错误

注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态

nginx -V
... --with-http_stub_status_module ...		# 编译时安装监控页面模块

vim /usr/local/nginx/conf.d/status.conf
server {
        listen 80;
        server_name status.timinglee.org;
        root /data/web/html;
        index index.html;

        location /status {
            stub_status;
            # allow 172.25.254.1;
            # deny all;
            # 还可以添加用户认证,提高安全性
        }
}

vim /etc/hosts	# Windows主机上也需要添加解析
...
172.25.254.100  status.timinglee.org

nginx -s reload
-------------------------------------------------------
# 效果演示
curl status.timinglee.org/status
Active connections: 1
server accepts handled requests
 48 48 46
Reading: 0 Writing: 1 Waiting: 0

# 取消注释
nginx -s reload

curl status.timinglee.org/status
... 403 Forbidden ...

# Linux主机不能访问,而Windows主机正常

在这里插入图片描述

输出信息

信息说明
Active connections当前处于活动状态的客户端连接数
包括连接等待空闲连接数=reading+writing+waiting
accepts:统计总值,Nginx自启动后已经接受的客户端请求连接的总数
handled:统计总值,Nginx自启动后已经处理完成的客户端请求连接总数
通常等于accepts,除非有因worker_connections限制等被拒绝的连接
requests:统计总值,Nginx自启动后客户端发来的总的请求数
Reading:当前状态,正在读取客户端请求报文首部的连接的连接数
数值越大,说明排队现象严重,性能不足
Writing:当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明访问量很大
Waiting:当前状态,正在等待客户端发出请求的空闲连接数
开启 keep-alive的情况下,这个值等于active – (reading+writing)

6.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;
# 此功能依赖于zlib-devel,压缩是指发送给客户时进行压缩,而不是指本地文件进行压缩
vim /usr/local/nginx/conf/nginx.conf
gzip  on;
gzip_comp_level 5;
gzip_min_length 1k;
gzip_http_version 1.1;
gzip_vary on;
39 gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/gif image/png;

nginx -s reload
echo hhh > /data/web/html/small.html
cat xyzfile > /data/web/html/big.html
-------------------------------------------------------
# 效果演示
curl --head --compressed 172.25.254.100/small.html
...
Accept-Ranges: bytes	# 小于1k,不进行压缩
...
curl --head --compressed 172.25.254.100/big.html
...
Content-Encoding: gzip	# 大于1k,以gzip方式进行压缩
...

6.3 Nginx 版本隐藏

用户在访问nginx的时候,我们可以从报文中获得nginx的版本

相对于裸漏版本号的nginx,我们把其隐藏起来更安全

curl -I 172.25.254.100
Server: nginx/1.24.0
...

# 在编译Nginx之前,编辑源码文件
# 若已经编译的Nginx,需要版本隐藏,则先卸载后,再修改源码文件后,再编译
vim /root/nginx-1.24.0/src/core/nginx.h
#define nginx_version      1024000
#define NGINX_VERSION      "1.11.1"
#define NGINX_VER          "ono/" NGINX_VERSION
-------------------------------------------------------
# 效果演示
curl -I 172.25.254.100
Server: ono/1.11.1
...

6.4 Nginx 变量

  • Nginx 的变量可以在配置文件中引用,作为功能判断或者日志等场景使用

  • 内置变量是由Nginx 模块自带,通过变量可以获取到众多的与客户端访问相关的值

  • 变量可以分为内置变量和自定义变量

官方文档http://nginx.org/en/docs/varindex.html

常用内置变量

$remote_addr;
# 存放客户端的地址,返回客户端的公网IP

$args;
# 变量中存放了URL中的所有参数
# 例如:https://search.jd.com/Search?keyword=手机&enc=utf-8
# 返回结果为: keyword=手机

$is_args
# 如果有参数,则返回?,如果没有参数返回空

$document_root;
# 保存了针对当前资源的请求的系统根目录,例如:/webdata/nginx/onowow.org/lee

$document_uri;
# 保存了当前请求中不包含参数的URI,注意是不包含请求的指令
# 比如:http://www.onowow.org/var?\id=xiaoming会被定义为/var
# 返回结果为:/var

$host;
# 存放了请求的host名称

$limit_rate;
# 如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置,则显示0
# limit_rate 10240;

$remote_port;
# 客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口

$remote_user;
# 已经经过Auth Basic Module验证的用户名

$request_body_file;
# 做反向代理时发给后端服务器的本地资源的名称

$request_method;
# 请求资源的方式,GET/PUT/DELETE等

$request_filename;
# 当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径

$request_uri;
# 包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args

$scheme;
# 请求的协议,例如:http,https,ftp等

$server_protocol;
# 保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等

$server_addr;
# 保存了服务器的IP地址

$server_name;
# 虚拟主机的主机名

$server_port;
# 虚拟主机的端口号

$http_user_agent;
# 客户端浏览器的详细信息

$http_cookie;
# 客户端的所有cookie信息

$cookie_<name>
# name为任意请求报文首部字部cookie的key名

$http_<name>
# name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有横线需要替换为下划线
# 示例:
echo $http_user_agent;
echo $http_host;

$sent_http_<name>
# name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有一些问题
echo $sent_http_server;

$arg_<name>
# 此变量存放了URL中的指定参数,name为请求url中指定的参数
echo $arg_id;

自定义变量

用户自定义变量名称和值,需要指令set $variable value;

语法格式

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

7. Nginx Rewrite 功能

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

  • 此功能依靠 PCRE(正则表达式库),因此编译之前要安装PCRE库

  • Rewrite 是Nginx 服务器的重要功能之一,用于实现URL的重写

Rewrite 请求通常指的是对原始请求的 URL 进行重新编写或修改的操作,来提供更好的用户体验、优化网站架构等

7.1 ngx_http_rewrite_module 模块指令

官方文档https://nginx.org/en/docs/http/ngx_http_rewrite_module.html

if 指令

官方文档https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if

用于条件匹配判断,根据条件判断的结果选择不同的Nginx 配置,可以在 server块 或 location块中进行配置

Nginx 的 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

set 指令

指定某个 key 并给其定义一个变量,变量可以调用Nginx 内置变量赋值给 key

定义格式

set $key value	# value可以是 text 或 variables 或两者的组合
vim /usr/local/nginx/conf.d/vhosts.conf
server {
  listen 80;
  server_name www.onowow.org;
  root /webdata/nginx/onowow.org/ovo;
  location /test3{
      set $name ovo;
      echo $name;
  }
}

curl  www.onowow.org/test3
ovo

break 指令

用于中断当前相同作用域(location)中的其他Nginx 配置

与此指令处于同一作用域的Nginx 配置中,位于它前面的配置生效

位于后面的 ngx_http_rewrite_module模块中的指令 将不再执行

Nginx 服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置

此指令可以在 server块 和 locationif块 中使用

注意: location块 读取到break 命令时,其后面的命令还会继续执行,只是不执行 ngx_http_rewrite_module模块中的指令,其它模块指令还会执行

vim /usr/local/nginx/conf.d/vhosts.conf
server {
  listen 80;
  server_name www.onowow.org;
  root /webdata/nginx/onowow.org/ovo;
  location /break {
      default_type text/html;
      set $name ovo;
      echo $name;
      break;
      set $port $server_port;
      echo $port;
   }
}

curl  lee.timinglee.org/break          #当未添加break时
ovo
80

curl  lee.timinglee.org/break          #添加break后
ovo

return 指令

return 用于完成对请求的处理,并直接向客户端返回响应状态码

此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置

语法格式

return code; #返回给客户端指定的HTTP状态码

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

return code URL; #返回给客户端的URL地址
server {
  listen 80;
  server_name www.onowow.org;
  root /webdata/nginx/onowow.org/lee;
  location /return {
      default_type text/html;
      if ( !-e $request_filename){
        return 301 http://www.baidu.com;
      }
      echo "$request_filename is exist";
   }
}

curl www.onowow.org/return
/webdata/nginx/timinglee.org/lee/return is exist

curl www.onowow.org/return1
/webdata/nginx/timinglee.org/lee/return1 is not exist

7.2 rewrite 指令

通过正则表达式的匹配来改变URL,可以同时存在一个或多个指令,按照顺序依次对URL进行匹配

rewrite 主要是针对用户请求的URL或者是URL做具体处理

官方文档https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite

语法格式

rewrite regex replacement [flag];

rewrite 将用户请求的URL基于 regex 所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URL

注意:如果在同一级配置块中存在多个rewrite 规则,那么会自下而下逐个检查

当被某条件规则替换完成后,会重新一轮的替换检查,隐含循环机制,但不超过10次

如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制

如果替换后的URL是以 http:// 或 https:// 开头,则替换结果会直接以重定向返回给客户端,即永久重定向 301

Nginx 正则表达式

表达式说明
.匹配除换行符以外的任意字符
\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以外的任意字符
[^haha]匹配除了magedu 这几个字母以外的任意字符

rewrite flag 使用介绍

利用nginx的rewrite 的指令,可以实现URL的重新跳转

rewrite 有四种不同的flag ,其中前两种是跳转型flag ,后两种是代理型flag

  • redirect——(临时重定向302)
  • permanent——(永久重定向301)
  • break
  • last

跳转型flag 指由客户端浏览器重新对新地址进行请求

代理型flag 是在WEB服务器内部实现跳转

语法格式

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;
# 重写完成后,停止对当前URL在当前location中后续的其它重写操作
# 而后对新的URL启动新一轮重写检查,不建议在location中使用
# 适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误信息给用户

8. nginx 之 rewrite 实战

临时性的域名调整,而后期域名还可能会变,之前的域名或者URL可能还用、或者跳转的目的域名和URL还会跳转

这种情况浏览器不会缓存跳转,临时重定向不会缓存域名解析记录,但永久重定向会缓存域名解析记录

8.1 rewrite 永久重定向 301

永久性域名调整,即域名永远跳转至另外一个新的域名,之前的域名不再使用,跳转记录可以缓存到客户端浏览器

永久重定向会缓存DNS解析记录,即使nginx 服务器无法访问,浏览器也会利用缓存进行重定向

vim /usr/local/nginx/conf.d/vhosts.conf
server {
  listen 80;
  server_name www.onowow.org;
  root /web/data/nginx/onowow.org/ovo;
  location / {
    rewrite / http://www.onowow.com permanent;
  }
}

server {
  listen 80;
  server_name www.onowow.com;
  root /web/data/nginx/onowow.com/ovo;
}   

8.2 rewrite 临时重定向 302

临时性域名重定向,向浏览器说明域名不是固定重定向到当前目标域名,后期可能随时会更改

因此浏览器不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS解析记录

这是临时重定向与永久重定向的本质区别

即当nginx 服务器无法访问时,浏览器不能利用缓存,而导致重定向失败

vim /usr/local/nginx/conf.d/vhosts.conf
server {
  listen 80;
  server_name www.onowow.org;
  root /web/data/nginx/onowow.org/ovo;
  location / {
    rewrite / http://www.onowow.com redirect;
  }
}

server {
  listen 80;
  server_name www.onowow.com;
  root /web/data/nginx/onowow.com/ovo;
}

8.3 break 与 last 的区别

当break 请求被rewrite 至test1,而访问test1 转递请求再次被rewrite 发送至test2,问break 与 last 分别有什么区别

mkdir  /web/data/nginx/onowow.org/ovo/{test1,test2,break}
echo test1 > /web/data/nginx/onowow.org/ovo/test1/index.html
echo test2 > /web/data/nginx/onowow.org/ovo/test2/index.html
echo break > /web/data/nginx/onowow.org/ovo/break/index.html

cat /usr/local/nginx/conf.d/vhosts.conf
server {
  listen 80;
  server_name www.onowow.org;
  root /web/data/nginx/onowow.org/ovo;

  location /break {
    root /web/data/nginx/onowow.org/ovo;
    rewrite ^/break/(.*) /test1/$1 last;
    rewrite ^/test1/(.*) /test2/$1 break;

  }

  location /last {
    root /web/data/nginx/onowow.org/ovo;
    rewrite ^/last/(.*) /test1/$1 last;
    rewrite ^/test1/(.*) /test2/$1 last;
  }

  location /test1 {
      default_type text/html;
      return 666 "new test1";
  }

  location /test2 {
    root /web/data/nginx/onowow.org/ovo;
  }
}

curl  -L www.onowow.org/break/index.html
test1
curl  -L www.onowow.org/last/index.html
new test1

8.4 rewrite 自动跳转 https

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

vim /usr/local/nginx/conf.d/vhosts.conf
server {
		listen 443 ssl;
    listen 80;
    ssl_certificate /usr/local/nginx/certs/www.onowow.org.crt;
    ssl_certificate_key /usr/local/nginx/certs/www.onowow.org.key;
		ssl_session_cache shared:sslcache:20m;
		ssl_session_timeout 10m;
		server_name www.onowow.org;
		location / {    #针对全站跳转
			root /web/data/nginx/html/ovo;
			index index.html;
			if ($scheme = http ){       #如果没有加条件判断,会导致死循环
				rewrite / https://$host redirect;
			}  
		}
		location /login {           #针对特定的URL进行跳转https 
			if ($scheme = http ){       #如果没有加条件判断,会导致死循环
				rewrite / https://$host/login redirect;
			} 
		}
}

#重启Nginx并访问测试
curl -ikL www.onowow.org
...
Location: https://www.xxvovxx.org
HTTP/1.1 200 OK
...

8.5 rewrite 判断文件是否存在

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

vim /usr/local/nginx/conf.d/vhosts.conf
location / {
   root /web/data/nginx/html/ovo;
   index index.html;
   if (!-e $request_filename) {
       rewrite .* http://www.onowow.org/index.html; #实现客户端浏览器的302跳转
   }
}
#重启Nginx并访问测试

8.6 Nginx 实现盗链

防盗链基于客户端携带的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

在一个web 站点盗链另一个站点的资源信息,比如:图片、视频等

#新建一个主机172.25.254.20,盗取另一台主机www.onowow.org/images/logo.png的图片
[root@client ~]# yum install httpd -y
[root@client html]# vim /var/www/html/index.html
# 准备盗链web页面:
<html>
 <head>
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <title>盗链页面</title>
</head>

  <body>
    <img src="http://www.onowow.org/images/logo.png" >
    <h1 style="color:red">注意你的行为</h1>
    <p><a href=http://www.onowow.org/images>不要盗链</a>遵纪守法</p>
  </body>
</html>

#重启apache并访问http://172.25.254.20 测试
#验证两个域名的日志,是否会在被盗链的web站点的日志中出现以下盗链日志信息
cat /usr/local/nginx/logs/access.log
172.25.254.1 - - [22/Aug/2024:09:50:01 +0800] "GET /images/logo.png HTTP/1.1" 304 
0 "http://172.25.254.20/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 
Edg/126.0.0.0"
172.25.254.1 - - [22/Aug/2024:09:50:18 +0800] "GET / HTTP/1.1" 304 0 
"http://172.25.254.20/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 
Edg/126.0.0.0"

8.7 Nginx 实现防盗链

基于访问安全考虑,nginx 支持通过ngx_http_referer_module模块,检查访问请求的referer 信息是否有效实现防盗链功能

官方文档https://nginx.org/en/docs/http/ngx_http_referer_module.html

vim /usr/local/nginx/conf.d/vhosts.conf
server {
  listen 80;
  server_name www.onowow.org;
  root /webdata/nginx/onowow.org/ovo;
  location /images {
    valid_referers none blocked server_names *.onowow.org ~\.baidu\.;
    if ($invalid_referer){
      rewrite ^/ http://www.onowow.org/daolian.png permanent;
    }
  }
}
#重启Nginx并访问测试http://172.25.254.20

9. nginx 反向代理

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

Nginx 除了可以在企业提供高性能的web 服务之外,另外还可以将 Nginx 本身不具备的请求,通过某种预定义的协议转发至其它服务器处理

不同的协议就是Nginx 服务器与其他服务器进行通信的一种规范

9.1 模块功能

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协议转发至指定服务器处理

9.2 逻辑调用关系

在这里插入图片描述

9.3 访问逻辑图

在这里插入图片描述
同构代理:用户不需要其他程序的参与,直接通过HTTP协议或者TCP协议访问后端服务器

异构代理:用户访问的资源时需要经过处理后才能返回的,比如PHP,Python等,这种资源需要经过处理才能被正常访问

在这里插入图片描述

9.4 HTTP 反向代理

官方文档https://nginx.org/en/docs/http/ngx_http_proxy_module.html

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

需要一台PHP:172.25.254.10

需要一台apache:172.25.254.20

# Nginx
vim /usr/local/nginx/conf.d/vhost.conf
server {
        listen 80;
        server_name www.timinglee.org;

        location ~ \.php$ {
            proxy_pass http://172.25.254.10:80;
        }

        location /static {
            proxy_pass http://172.25.254.20:80;
        }
}
nginx -s reload
-------------------------------------------------------
# PHP
yum install httpd -y
dnf install php -y
systemctl enable --now httpd

vim /var/www/html/index.php
<?php
    phpinfo();
?>
-------------------------------------------------------
# Apache
yum install httpd -y
systemctl enable --now httpd
echo this is static page form 172.25.254.20 > /var/www/html/static/index.html

效果演示

PHP

在这里插入图片描述

Apache

在这里插入图片描述

其他配置

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

9.5 HTTP 负载均衡 反向代理

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

# 依赖于--with-stream、--with-stream_ssl_module、--with-stream_realip_module模块
vim /usr/local/nginx/conf.d/vhost.conf
upstream webcluster {
    server 172.25.254.10:80 fail_timeout=15s max_fails=3;
    server 172.25.254.20:80 fail_timeout=15s max_fails=3;
    server 172.25.254.100:80 backup;
}
server {
        listen 80;
        server_name www.timinglee.org;

        location / {
            proxy_pass http://webcluster;
        }
}
nginx -s reload

效果演示

在这里插入图片描述

9.6 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模块

官方文档https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html

配置参数

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;
   }
}

以DNS 为例

# Nginx
vim /usr/local/nginx/conf/nginx.conf
...
include "/usr/local/nginx/tcpconf.d/*.conf";
http {
......

mkdir /usr/local/nginx/tcpconf.d -p
vim /usr/local/nginx/tcpconf.d/dns.conf
stream {
    upstream dns {
        server 172.25.254.10:53 fail_timeout=15s max_fails=3;
        server 172.25.254.20:53 fail_timeout=15s max_fails=3;
    }

    server {
        listen 53 udp reuseport;
        proxy_timeout 20s;
        proxy_pass dns;
    }
}
nginx -s reload
-------------------------------------------------------
# 172.25.254.10
dnf install bind -y
vim /etc/named.conf
 11 //  listen-on port 53 { 127.0.0.1; };
 12 //  listen-on-v6 port 53 { ::1; };
 19 //  allow-query     { localhost; };
 33     dnssec-validation no;
 
vim /etc/named.rfc1912.zones
zone "timinglee.org" IN {
    type master;
    file "timinglee.org.zone";
    allow-update { none; };
};

cd /var/named/
cp named.localhost timinglee.org.zone -p
vim timinglee.org.zone
$TTL 1D
@   IN SOA ns.timinglee.org. root.timinglee.org. (
                    0   ; serial
                    1D  ; refresh
                    1H  ; retry
                    1W  ; expire
                    3H )    ; minimum
    NS  ns.timinglee.org.
ns  A   172.25.254.10
www A   172.25.254.10

systemctl start named
scp -p /etc/named.{conf,rfc1912.zones} root@172.25.254.20:/etc/
scp -p /var/named/timinglee.org.zone  root@172.25.254.20:/var/named/timinglee.org.zone
-------------------------------------------------------
# 172.25.254.20
yum install bind -y

vim /var/named/timinglee.org.zone
$TTL 1D
@   IN SOA ns.timinglee.org. root.timinglee.org. (
                    0   ; serial
                    1D  ; refresh
                    1H  ; retry
                    1W  ; expire
                    3H )    ; minimum
    NS  ns.timinglee.org.
ns  A   172.25.254.20
www A   172.25.254.20

cd /var/named/
chgrp named timinglee.org.zone
ll /var/named/
-rw-r----- 1 root  named  205 Aug 20 21:11 timinglee.org.zone
systemctl restart named

效果演示

172.25.254.10

在这里插入图片描述

172.25.254.20

在这里插入图片描述

DNS负载均衡

在这里插入图片描述

以MySQL 为例

# Nginx
vim /usr/local/nginx/tcpconf.d/dns.conf
stream {
	...
    upstream mysql {
        server 172.25.254.10:3306 fail_timeout=15s max_fails=3;
        server 172.25.254.20:3306 fail_timeout=15s max_fails=3;
    }

    server {
        listen 3306;
        proxy_timeout 60s;
        proxy_pass mysql;
    }
    ...
}
nginx -s reload
-------------------------------------------------------
# 172.25.254.10
dnf install mariadb-server -y
vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=10
datadir=/var/lib/mysql

systemctl start mariadb
mysql
>create user ono@'%' identified by 'aaa';
>grant all on *.* to ono@'%';
>exit
-------------------------------------------------------
# 172.25.254.20
dnf install mariadb-server -y
vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=20
datadir=/var/lib/mysql

systemctl start mariadb
mysql
>create user ono@'%' identified by 'aaa';
>grant all on *.* to ono@'%';
>exit

效果演示

在这里插入图片描述

9.7 引入 Fast CGI

实现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进程都会执行这些操作,所以效率很低

而 Fast CGI 是用来提高CGI性能的,Fast CGI 每次处理完请求之后不会关闭掉进程,而是保留这个进程,使这个进程可以处理多个请求

这样每个请求都不用重新创建一个进程,大大提升了处理效率

PHP-FPM

PHP-FPM(FastCGI Process Manager):

  • Fast CGI 进程管理器:是一个实现了Fastcgi的程序,并且提供进程管理的功能
  • 进程包括master进程和worker进程;master进程只有一个,负责监听端口,接受来自web server的请求
  • worker进程一般会有多个,每个进程中会嵌入一个PHP解析器,进行PHP代码的处理

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
   }

9.8 实现Fast CGI

安装Nginx

yum install gcc pcre-devel openssl-devel zlib-devel -y	# 安装Nginx依赖
useradd -s /sbin/nologin -M nginx	# 为Nginx 创建用户

# 安装Nginx
./configure --prefix=/usr/local/nginx --add-module=/root/echo-nginx-module-0.63 --add-module=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module-0.33 --user=nginx --group=nginx --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-stream --with-stream_ssl_module --with-http_ssl_module --with-stream_realip_module --with-pcre

make && make install

vim ~/.bash_profile
# User specific environment and startup programs
export PATH=$PATH:/usr/local/nginx/sbin

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
systemctl daemon-reload	# 不做,不能开机启动
nginx -s stop
systemctl enable --now nginx	# 设置开机启动

安装PHP

# 安装PHP依赖,其中一个依赖:oniguruma-devel需要从网站下载
# RHEL7
# wget https://mirrors.aliyun.com/epel/7/x86_64/Packages/o/oniguruma-6.8.2-2.el7.x86_64.rpm
# wget https://mirrors.aliyun.com/epel/7/x86_64/Packages/o/oniguruma-devel-6.8.2-2.el7.x86_64.rpm
# yum install oniguruma-6.8.2-2.el7.x86_64.rpm -y
# yum install oniguruma-devel-6.8.2-2.el7.x86_64.rpm -y
# RHEL9
# wget https://mirrors.aliyun.com/rockylinux/9.4/devel/x86_64/kickstart/Packages/o/oniguruma-devel-6.9.6-1.el9.5.x86_64.rpm
# dnf install oniguruma-devel-6.9.6-1.el9.5.x86_64.rpm -y
yum install bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel -y
# 检测PHP
./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --enable-fpm --enable-sockets --enable-soap --enable-xml --enable-ftp --enable-gd --enable-exif --enable-mbstring --enable-bcmath --with-fpm-user=nginx --with-fpm-group=nginx --with-curl --with-iconv --with-mhash --with-zlib --with-openssl --enable-mysql --with-mysqli --with-pdo-mysql --disable-debug

# 源码编译(时间稍长)
make && make install

# 添加PHP环境变量
vim ~/.bash_profile
# User specific environment and startup programs
export PATH=$PATH:/usr/local/nginx/sbin:/usr/local/php/bin:/usr/local/php/sbin
source ~/.bash_profile

# PHP配置优化
cp -p /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf

vim /usr/local/php/etc/php-fpm.con
17 pid = run/php-fpm.pid	# 取消注释,指定PID文件存放位置

# 在www.conf文件中,可以设定PHP的IP、使用端口等信息(0.0.0.0:9000==*:9000,后者不可用)
cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf

# IP 要与 Nginx的配置文件对应,不然会报502 Bad Gateway
# 或者www.conf的IP 写成0.0.0.0,则Nginx的IP随便
# 重启服务时,使用systemctl restart php-fpm.service 和 nginx -s reload
vim /usr/local/php/etc/php-fpm.d/www.conf
41 listen = 172.25.254.100:9000	

# 生成PHP主配置文件
cp /root/php-8.3.9/php.ini-production /usr/local/php/etc/php.ini
vim /usr/local/php/etc/php.ini
989 date.timezone = Asia/Shanghai	# 修改时区,严格区分大小写

# 生成PHP启动文件
cp /root/php-8.3.9/sapi/fpm/php-fpm.service /lib/systemd/system/php-fpm.service
vim /lib/systemd/system/php-fpm.service
21 # ProtectSystem=full	  # 注释此内容
systemctl start php-fpm.service
netstat -antlupe | grep php
tcp        0      0 0.0.0.0:9000            0.0.0.0:*               LISTEN      0          23931     1504/php-fpm: maste

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

vim /usr/local/nginx/conf/nginx.conf	# 设置子配置文件
# 配置在server{...}的范围外
80 include "/usr/local/nginx/conf.d/*.conf";

vim /usr/local/nginx/conf.d/vhost.conf	# 子配置文件
server {
    listen 80;
    server_name www.timinglee.org;
    root /data/web/html;
    index index.html;

    location ~ \.php$ {
        root /data/web/php;
        fastcgi_pass 172.25.254.100:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}

mkdir /data/web/php/ -p
vim /data/web/php/index.php
<?php
    phpinfo();
?>

# 启动或重启PHP、nginx服务
systemctl start php-fpm.service
systemctl start nginx.service
# PHP测试页面
# 浏览器访问"http://www.timinglee.org/index.php"

效果演示

在这里插入图片描述

9.9 PHP的动态扩展模块(PHP缓存模块)

下载地址http://pecl.php.net/package/memcache

在这里插入图片描述

安装memcache模块

tar zxf memcache-8.2.tgz
cd memcache-8.2/
yum install autoconf -y
phpize
./configure && make && make install

ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20230831/
memcache.so  opcache.so

配置PHP加载memcache模块

vim /usr/local/php/etc/php.ini	# 指定配置路径
974 ;extension=zip
975 extension=memcache
976 ;zend_extension=opcache

systemctl reload php-fpm
php -m | grep memcache

部署memcached

yum install memcached -y
systemctl enable --now memcached.service

netstat -antlupe | grep memcached
tcp    0    0 0.0.0.0:11211    0.0.0.0:*    LISTEN    996    21845    988/memcached

cat /etc/sysconfig/memcached	# 无修改
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1,::1"

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

cp /root/memcache-8.2/example.php memcache.php /data/web/php/

vim /data/web/php/memcache.php
define('ADMIN_USERNAME','admin'); // Admin Username
define('ADMIN_PASSWORD','lee'); // Admin Password
....
$MEMCACHE_SERVERS[] = 'localhost:11211'; // add more as an array
#$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array

效果演示

登录访问http://www.timinglee.org/memcache.php,查看命中效果,右边的柱形图

在这里插入图片描述

在这里插入图片描述

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

观察命中效果,右边的柱形图

在这里插入图片描述

9.10 PHP高速缓存

在我们安装的nginx中默认不支持memc和srcache功能,需要借助第三方模块来让nginx支持此功能
在这里插入图片描述

# 修改配置文件
vim /apps/nginx/conf.d/php.conf
upstream memcache {
	server 127.0.0.1:11211;
	keepalive 512;
}
server {
	listen 80;
	server_name php.timinglee.org;
	root /data/php;
	location /memc {
		internal;
		memc_connect_timeout 100ms;
		memc_send_timeout 100ms;
		memc_read_timeout 100ms;
		set $memc_key $query_string; #使用内置变量$query_string来作为key
		set $memc_exptime 300; #缓存失效时间300秒
		memc_pass memcache;
		}

	location ~ \.php$ {
		set $key $uri$args; #设定key的值
		srcache_fetch GET /memc $key; #检测mem中是否有要访问的php
		srcache_store PUT /memc $key; #缓存为加载的php数据
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_index index.php;
		include fastcgi.conf;
	}
}
nginx -s reload
nginx -t

效果演示


10. Nginx 二次开发版本

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 应用系统

10.1 编译安装openresty

[root@Nginx ~]#dnf -yq install gcc pcre-devel openssl-devel perl	# 安装依赖
[root@Nginx ~]#useradd -r -s /sbin/nologin nginx	# 创建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=/apps/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 openresty-1.17.8.2]#ln -s /apps/openresty/bin/* /usr/bin/		#创建链接 方便使用
[root@Nginx openresty-1.17.8.2]#openresty -v	# 查看openresty的版本
nginx version: openresty/1.17.8.2
[root@Nginx openresty-1.17.8.2]#openresty 	# 启动openresty

openresty的用法,与nginx十分相似,有兴趣的小伙伴可以尝试在openresty进行实战

  • 27
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值