企业高性能web服务器——Nginx

这里是本文用到的一些脚本/插件,可以自行取用,也可到官网下载自己需要的版本

通过百度网盘分享的文件:nginx的一些插件
链接:https://pan.baidu.com/s/1zN-nqX6RUf3wzZxkxj24Fg?pwd=7use 
提取码:7use 

 下面正文开始

一、Web 服务基础介绍

正常情况下的单次 web 服务访问流程:

1.1 Web 服务介绍 

1.1.1 Apache 经典的 Web 服务端

        Apache起初由美国的伊利诺伊大学香槟分校的国家超级计算机应用中心开发
        目前经历了两大版本分别是1.X 2.X
        其可以通过编译安装实现特定的功能
Apache prefork 模型
  • 预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024
  • 每个子进程有一个独立的线程响应用户请求
  • 相对比较占用内存,但是比较稳定,可以设置最大和最小进程数
  • 是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景
优点:稳定
缺点:每个用户请求需要对应开启一个进程 , 占用资源较多,并发性差 , 不适用于高并发场景

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

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

二、nginx编译安装

2.1 Nginx 概述

2.1.1 Nginx 介绍

Nginx engine X 2002 年开发,分为社区版和商业版 (nginx plus )
2019 3 11 F5 Networks 6.7 亿美元的价格收购
Nginx 是免费的、开源的、高性能的 HTTP 和反向代理服务器、邮件代理服务器、以及 TCP/UDP 代理服务器
解决C10K 问题( 10K Connections
Nginx 官网: http://nginx.org
nginx 的其它的二次发行版:
  • Tengine:由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。从201112月开始,Tengine成为一个开源项目官网: http://tengine.taobao.org/
  • OpenResty:基于 Nginx Lua 语言的高性能 Web 平台, 章亦春团队开发,官网:http://openresty.org/cn/

2.1.2 Nginx 功能介绍

  • 静态的web资源服务器html,图片,jscsstxt等静态资源
  • http/https协议的反向代理
  • 结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
  • tcp/udp协议的请求转发(反向代理)
  • imap4/pop3协议的反向代理

2.2.3 基础特性

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

2.2.4 Web 服务相关的功能

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

2.2 Nginx 架构和进程

2.2.1 Nginx 进程结构

web 请求处理机制
  • 多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求
  • 多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程和此客户端进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。

Nginx是多进程组织模型,而且是一个由Master主进程和Worker工作进程组成。

主进程(master process)的功能:
  • 对外接口:接收外部的操作(信号)
  • 对内转发:根据外部的操作的不同,通过信号管理 Worker
  • 监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
  • 读取Nginx 配置文件并验证其有效性和正确性
  • 建立、绑定和关闭socket连接
  • 按照配置生成、管理和结束工作进程
  • 接受外界指令,比如重启、升级及退出服务器等指令
  • 不中断服务,实现平滑升级,重启服务并应用新的配置
  • 开启日志文件,获取文件描述符
  • 不中断服务,实现平滑升级,升级失败进行回滚处理
  • 编译和处理perl脚本
工作进程(worker process)的功能:
  • 所有 Worker 进程都是平等的
  • 实际处理:网络请求,由 Worker 进程处理
  • Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争
  • CPU资源,
  • 增加上下文切换的损耗
  • 接受处理客户的请求
  • 将请求依次送入各个功能模块进行处理
  • I/O调用,获取响应数据
  • 与后端服务器通信,接收后端服务器的处理结果
  • 缓存数据,访问缓存索引,查询和调用缓存数据
  • 发送请求结果,响应客户的请求
  • 接收主程序指令,比如重启、升级和退出等

2.2.2 Nginx 启动和 HTTP 连接建立

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

2.2.3 HTTP 处理过程

2.3 Nginx 模块介绍

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

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

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

2.4 环境安装

2.4.1 Nginx 编译安装

保证是一个纯净的实验环境

下载源码包

wgte http://nginx.org/download/nginx-1.24.0.tar.gz

下载依赖包

dnf install gcc pcre-devel zlib-devel openssl-devel -y

创建一个不可以远程登录的没有家目录的用户

useradd -s /sbin/nologin -M nginx

解压安装包

 tar zxf nginx-1.24.0.tar.gz

关闭debug

cd nginx-1.24.0/

vim auto/cc/gcc

 

编译安装的程序

./configure --prefix=/usr/local/nginx --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

--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加密

 检测过了会生成一个Makefile文件

安装nginx 安装速度有电脑性能决定

make install

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

[root@nginx nginx]# ls /usr/local/nginx/ 
conf html logs sbin

验证版本及编译参数

把nginx软件的命令执行路径添加到环境变量中

vim ~/.bash_profile

export PATH=$PATH:/usr/local/nginx/sbin

source ~/.bash_profile

执行完后,在启动nginx服务只需要输入nginx就可以了

编译完就可以进入网页 172.25.254.100

这里可以看到nginx版本

curl -I 172.25.254.100

图中展示的版本信息可以被隐藏

进入目录 

cd nginx-1.24.0/src/core/

对,nginx.h文件进行修改即可 

2.4.2 nginx的平滑升级及版本回滚

升级

下载高版本的nginx并解压

wget http://nginx.org/download/nginx-1.26.2.tar.gz

tar zxf nginx-1.26.2.tar.gz

关闭debug

cd nginx-1.26.2/

编译安装的程序,比之前多一条--add-module=/root/echo-nginx-module-0.63

./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --add-module=/root/echo-nginx-module-0.63 --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

安装程序

只要make无需要make install

make

把之前的旧版的nginx命令备份

cd /usr/local/nginx/sbin/ 

cp nginx nginx.bak

把新版本的nginx命令复制过去

\cp -f /root/nginx-1.26.2/objs/nginx  /usr/local/nginx/sbin/nginx

检测一下有没有问题

nginx -t

 查看进程

ps aux | grep nginx

这就是老的版本。

kill -USR2 8599 #nginx worker ID

USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的 nginx

此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80

此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进 程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。

回收旧版本

 kill -WINCH 8598

回滚

[root@nginx sbin]#mv nginx nginx.now

[root@nginx sbin]# mv nginx.bak nginx 

 

 kill -HUP  8598

回收新版本

 kill -WINCH 8605

2.4.3 nginx的io调用及优化原理

服务端 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文件的读写

 磁盘 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
网络 I/O
网络通信就是网络协议栈到用户空间进程的IO就是网络IO

网络I/O 处理过程

  • 获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3
  • 构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4
  • 返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端(5-7
不论磁盘和网络 I/O,每次I/O ,都要经由两个阶段:
  • 第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长。
  • 第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短。
I/O 模型
I/O 模型相关概念
同步 / 异步:关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。
  • 同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成。
  • 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态。

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

网络 I/O 模型
阻塞型

 

 非阻塞型

多路复用型 信号驱动型异步

2.4.4 nginx的启动文件编写

先关闭nginx服务

nginx -s stop

编写启动文件

保存退出后,我们就可以使用systemctl restart nginx等命令 和自启动了

2.4.5 nginx全局配置参数优化调整

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

 

worker_cpu_affinity 00000001 00000010 00000100 00001000 | auto ; # Nginx 工作进程绑定到指定的 CPU 核心,默认 Nginx 是不进行进程绑定的,绑定并不是意味着当前 nginx 进程独占以一核心CPU ,但是可以保证此进程不运行在其他核心上,这就极大减少了 nginx 的工作进程在不同的cpu核心上的来回跳转,减少了 CPU 对进程的资源分配与回收以及内存管理等,因此可以有效的提升 nginx 服务器的性能。
CPU MASK:
  • 000000010CPU
  • 000000101CPU
  • 100000007CPU
# 示例
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

编辑子配置文件

vim /usr/local/nginx/conf.d/vhost.conf

找到C:\Windows\System32\drivers\etc目录中的hosts文件,以管理员身份打开,修改内容

 测试

映射

vim /usr/local/nginx/conf.d/vhost.conf

location用法详解

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

location [ = | ~ | ~* | ^~ ] uri { ... }

=       #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立 即处理请求 

^~      #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头 #对uri的最左边部分做匹配检查,不区分字符大小写 

~       #用于标准uri前,表示包含正则表达式,并且区分大小写 

~*      #用于标准uri前,表示包含正则表达式,并且不区分大写 不带符号 #匹配起始于此uri的所有的uri 

\       #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号

=      后面跟的是文件不是目录

 这里lee找不到是因为它不是以t开头。只有以t开头才会识别root。

加了 * 表示不区分大小写

输入https://www.timinglee.org/lee/index.hou 后,可以访问,只是识别为下载文件

优先级

 把web4注释掉后,最优先就变成了web5

这两个优先级相同,谁写在前就先读取谁。

把4和5注释掉后,最优先级变为1.

调换位置后仍然先读取1,所以排除4、5后1的优先级最高。

将1注释掉后,3的优先级最高

最终优先级排序

以目录为目标

(~* | ~) >  不带符号  >  ^~  >  =

以文件为目标

=   >   (~* | ~)   >   不带符号   >   ^~

2.4.6 nginx下的用户认证

创建认证文件

测试,输入用户密码后进入页面

自定义错误页面
日志重定向 

所有的日志都会存放在下列列表中

自动检测文件是否存在

vim /usr/local/nginx/conf.d/vhost.conf

长连接配置

主配置文件

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

下载telnet

dnf install telnet -y

 测试

[root@nginx ~]# telnet www.timinglee.org 80
Trying 172.25.254.100...
Connected to www.timinglee.org.
Escape character is '^]'.
GET / HTTP/1.1          ----- 手动写入请求的报文
HOST: www.timinglee.org   ----- 访问的域名,端口
 
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Fri, 16 Aug 2024 12:45:43 GMT
Content-Type: text/html
Content-Length: 19
Last-Modified: Fri, 16 Aug 2024 12:45:12 GMT
Connection: keep-alive
ETag: "66bf49d8-13"
Accept-Ranges: bytes
 
www.timinglee.org
这里设置了两次,请求两次之后就会退出。
 
企业中一般不能断开,要一直请求访问

下载服务器配置 
创建下载文件的目录:
[root@nginx ~]# mkdir /data/web/download -p
[root@nginx ~]# dd if=/dev/zero of=/data/web/download/leefile bs=1M count=100  ---- 做一个大小为100M的文件,并放到刚才创建的目录。创建的一个数据。
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.0394146 s, 2.7 GB/s
[root@nginx ~]# 
 
写一个location,访问路径
[root@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_page 404 /40x.html;
  error_log /var/log/timinglee.org/error.log;
  access_log /var/log/timinglee.org/access.log;
  try_files $uri $uri.html $uri/index.html /error/default.html;
 
  location /lee {
        root /data/web;
        auth_basic "login passwd";
        auth_basic_user_file "/usr/local/nginx/.htpasswd";
  }
  location /40x.html {
        root /data/web/errorpage;
  }
  location /download {
        root /data/web;
        autoindex on;   ----- 让文件可以长列表显示
        autoindex_localtime on;   -----on表示显示本机时间而非GMT(格林威治)时间,默为为off显示GMT时间
        autoindex_exact_size off;  ---- 计算文件确切大小(单位bytes),此为默认值,off只显示大概大小(单位kb、mb、gb)
        limit_rate 1024k; -------- 限速,默认不限速 }
  }
}

[root@nginx ~]# wget www.timinglee.org/download/leefile
--2024-08-16 09:11:02--  http://www.timinglee.org/download/leefile
Resolving www.timinglee.org (www.timinglee.org)... 172.25.254.100
Connecting to www.timinglee.org (www.timinglee.org)|172.25.254.100|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: ‘leefile.1’
 
leefile.1                               26%[===================>                                                         ]  26.00M  1.04MB/s    eta 71s 

三、Nginx的高级配置

3.1 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 conf.d]# vim /usr/local/nginx/conf/nginx.conf
   keepalive_timeout  65 60;
   keepalive_requests 2;
 
   gzip  on;          #打开压缩功能
   gzip_comp_level 5;
   gzip_min_length 1k;
   gzip_http_version 1.1;
   gzip_vary on;
[root@Nginx conf.d]# echo hello timinglee > /data/web/html/small.html
[root@Nginx conf.d]# cat /usr/local/nginx/logs/access.log > /data/web/html/big.html

3.2 Nginx的变量

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

3.2.1 内置变量

常用的内置变量

$remote_addr;
#存放了客户端的地址,注意是客户端的公网IP
 
$args;
#变量中存放了URL中的所有参数
#例如:https://search.jd.com/Search?keyword=手机&enc=utf-8
#返回结果为: keyword=手机&enc=utf-8
 
$is_args
#如果有参数为? 否则为空
 
$document_root;
#保存了针对当前资源的请求的系统根目录,例如:/webdata/nginx/timinglee.org/lee。
 
$document_uri;
#保存了当前请求中不包含参数的URI,注意是不包含请求的指令
#比如:http://lee.timinglee.org/var?\id=11111会被定义为/var
#返回结果为:/var
 
$host;
#存放了请求的host名称
 
limit_rate 10240;
echo $limit_rate;
#如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
 
$remote_port;
#客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
 
$remote_user;
#已经经过Auth Basic Module验证的用户名
 
$request_body_file;
#做反向代理时发给后端服务器的本地资源的名称
 
$request_method;
#请求资源的方式,GET/PUT/DELETE等
 
$request_filename;
#当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径,
#如:webdata/nginx/timinglee.org/lee/var/index.html
 
$request_uri;
#包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args,
#例如:/main/index.do?id=20190221&partner=search
 
$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的对应的首部字段名需要为小写,如果有横线需要替换为下划线
[root@Nginx conf.d]# vim vars.conf
server {
    listen 80;
    server_name var.timinglee.org.org;
    root /data/web/html;
    index index.html;
 
    location /var {
        default_type text/html;
        echo $remote_addr;
        echo $args;
        echo $is_args;
        echo $document_root;
        echo $document_uri;
        echo $host;
        echo $remote_port;
        echo $remote_user;
        echo $request_method;
        echo $request_filename;
        echo $request_uri;
        echo $scheme;
        echo $server_protocol;
        echo $server_addr;
        echo $server_name;
        echo $server_port;
        echo $http_user_agent;
        echo $http_cookie;
        echo $cookie_key2;
    }
}

3.2.2 自定义变量

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

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

3.3 Nginx Rewrite 相关功能

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

        此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库

        rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能 比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的 链接,就可以设置为访问

        另外还可以在一定程度上提高网站的安全性

3.3.1 IF指令

        用于条件匹配判断,并根据条件判断结果选择不同的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@Nginx conf.d]# vim vars.conf
server {
    listen 80;
    server_name var.timinglee.org.org;
    root /data/web/html;
    index index.html;
 
    location /var {
        default_type text/html;
        echo $remote_addr;
        echo $args;
        echo $is_args;
        echo $document_root;
        echo $document_uri;
        echo $host;
        echo $remote_port;
        echo $remote_user;
        echo $request_method;
        echo $request_filename;
        echo $request_uri;
        echo $scheme;
        echo $server_protocol;
        echo $server_addr;
        echo $server_name;
        echo $server_port;
        echo $http_user_agent;
        echo $http_cookie;
        echo $cookie_key2;
    }
    location /test2 {
    if ( !-e $request_filename ){
        echo "$request_filename is not exist";
     }
    }
}

3.3.2 set指令

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

        另外set定义格式为set $key value,value可以是text, variables和两者的组合

location /break {
        default_type text/html;
        set $name lee;
        echo $name;
        break;
        set $id 666;
        echo $id;
    }

3.3.3 break指令

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

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

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

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

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

注意:

        如果break指令在location块中后续指令还会继续执行,只是不执行ngx_http_rewrite_module 模块的指令,其它指令还会执行

[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
#内容
location /break {
    default_type text/html;
    set $name lee;
    echo $name;
    if ( $http_user_agent = curl ) {
        break;
    }
    break;
    set $id 666;
    echo $id;
}

3.3.4 return指令

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

#语法
return code;             #返回给客户端指定的HTTP状态码
 
return code [text];      #返回给客户端的状态码及响应报文的实体内容
                         #可以调用变量,其中text如果有空格,需要用单或双引号
 
return code URL;         #返回给客户端的URL地址
location /return {
    default_type text/html;
    if ( !-e $request_filename){
        return 301 http://www.baidu.com;
    }
    echo "$request_filename is exist";
}

3.3.5 rewritr指令

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

#语法
rewrite regex replacement [flag];

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

注意:

        如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成 后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的 标志位用于控制此循环机制

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

正则表达式格式

.          #匹配除换行符以外的任意字符
\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 这几个字母以外的任意字符

3.4 永久重定向301

[root@Nginx conf.d]# vim vars.conf
#写入内容
server {
    listen 80;
    server_name var.timinglee.org;
    root /data/web/html;
    index index.html;
 
    location / {
        root /data/web/var;
        index index.html;    
    }
}

3.5 加密

[root@Nginx conf.d]# cd /usr/local/nginx/
[root@Nginx nginx]# vim /usr/local/nginx/conf.d/vhost.conf 
#内容
server {
    listen 80;
    listen 443 ssl;
    server_name www.timinglee.org;
    root /data/web/html;
    index index.html;
    ssl_certificate /usr/local/nginx/certs/timinglee.org.crt;
    ssl_certificate_key /usr/local/nginx/certs/timinglee.org.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
 
    location / {
        if ( $scheme = http ){
            rewrite /(.*) https://$host/$1 redirect;
        }
 
        if ( !-e $request_filename ){
            rewrite /(.*) https://$host/index.html redirect;
        }
    }
}

3.6 nginx防盗链

        防盗链基于客户端携带的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支持通过ngx_http_referer_module模块,检查访问请求的referer信息是否有效 实现防盗链功能

#定义防盗链
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
#内容
server {
    listen 80;
    server_name www.timinglee.org;
    root /webdata/nginx/timinglee.org/lee;
    location /images {
        valid_referers none blocked server_names *.timinglee.org ~\.baidu\.;
        if ($invalid_referer){
            #return 403;
            rewrite ^/ http://www.timinglee.org/daolian.png permanent;
        }
    }
}

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

3.8 逻辑调用关系

逻辑调用关系主要包含以下关键要点:

  • 客户端请求:客户端发起对目标服务器的请求,但并不知道实际是与 nginx 进行交互。它将请求发送到 nginx 配置的监听端口上。
  • nginx 接收请求:nginx 接收到客户端请求后,根据其配置的反向代理规则来决定如何处理。
  • 请求转发:nginx 依据规则将请求转发到后端真实服务器。这通常涉及到修改请求头部信息,使其看起来像是直接来自 nginx 所在服务器,以隐藏后端服务器的真实信息。
  • 后端服务器响应:后端真实服务器接收到请求并进行处理,然后将响应结果返回给 nginx。
  • nginx 响应客户端:nginx 接收到后端服务器的响应后,再将其转发给客户端。在此过程中,nginx 还可以对响应数据进行缓存、压缩等操作以优化性能

3.8.1 访问逻辑

客户端发起请求

        客户端根据所需访问的域名或 IP 地址及端口,向网络发送请求。在配置了 nginx 反向代理的场景下,客户端实际上是将请求发送到 nginx 服务器的指定监听端口,此时客户端认为它正在与目标服务器直接通信,但并不知道中间有 nginx 代理的存在。

nginx 接收并处理请求

  • 请求解析:nginx 接收到客户端请求后,迅速解析请求的内容,包括请求方法(如 GET、POST 等)、请求的 URL、HTTP 头部信息等
  • 匹配代理规则:根据预先配置好的反向代理规则,nginx 确定将请求转发到哪个后端服务器集群或具体的真实服务器。这些规则可以基于请求的域名、URL 路径、客户端 IP 地址等多种条件进行灵活配置。

请求转发到后端服务器

  • 建立连接:nginx 与选定的后端服务器建立网络连接。通常使用 HTTP 或其他应用层协议与后端服务器进行通信。
  • 请求转发:nginx 将客户端的原始请求进行必要的转换(例如修改请求头部中的某些信息,使其适应后端服务器的要求)后,转发给后端服务器。在这个过程中,nginx 可以对请求进行负载均衡,将请求均匀地分配到不同的后端服务器上,以提高系统的整体性能和可靠性。

后端服务器处理请求并返回响应

  • 处理请求:后端服务器接收到 nginx 转发过来的请求后,像直接接收客户端请求一样进行处理。后端服务器根据请求的具体内容,执行相应的应用程序逻辑,访问数据库或其他资源,生成响应结果。
  • 返回响应:后端服务器将处理后的响应结果发送回 nginx。响应通常包括 HTTP 状态码、响应头部信息和响应主体内容。

nginx 接收后端服务器响应并返回给客户端

  • 响应处理:nginx 接收到后端服务器的响应后,根据需要可以对响应进行一些额外的处理,例如缓存响应结果以供后续相同请求使用、对响应数据进行压缩以减少网络传输量等。
  • 返回给客户端:最后,nginx 将处理后的响应按照 HTTP 协议的要求返回给客户端。客户端接收到响应后,就可以根据响应内容进行页面渲染、数据展示等操作。整个过程中,客户端只知道与它通信的是最初请求的目标地址,而完全不知道 nginx 反向代理的存在以及请求在后台的转发和处理过程

同构代理:

        用户不需要其他程序的参与,直接通过http协议或者tcp协议访问后端服务器。静态

异构代理:

        用户访问的资源时需要经过处理后才能返回的,比如php,python,等等,这种访问资源需要经过处理才能被访问

HTTP反向代理的实现

#准备两台主机
#一台server主机
#一台nginx主机
#server主机
[root@webserver1 ~]# dnf install httpd -y
[root@webserver1 ~]# echo 172.25.254.10 > /var/www/html/index.html
 
#nginx主机
[root@Nginx ~]# cd /usr/local/nginx/conf.d
[root@Nginx ~]# 
[root@Nginx ~]# vim 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:8080;
    }
}

HTTP反向代理实现负载均衡

关键原理要点:

请求接收

        反向代理服务器(如常见的 Nginx)监听一个对外的公共 IP 和端口,接收来自客户端的 HTTP 请求。

服务器组管理

        配置一组后端真实服务器(也称为上游服务器)信息,包括它们的 IP 地址和端口等。这些服务器共同组成一个服务器集群来处理客户端请求。

        负载均衡算法基于这些服务器的配置和当前状态进行决策。

负载均衡算法决策

        轮询(Round Robin):按顺序依次将请求分发到不同的后端服务器。例如,第一个请求分配给服务器 A,第二个请求分配给服务器 B,第三个请求分配给服务器 C,然后再从服务器 A 开始循环。

        加权轮询(Weighted Round Robin):根据服务器的性能差异为每个服务器分配一个权重值。性能较好的服务器权重较高,接收到的请求数量相对较多。例如,服务器 A 权重为 3,服务器 B 权重为 2,服务器 C 权重为 1,那么在 6 次请求中,服务器 A 将分配到 3 次请求,服务器 B 分配到 2 次请求,服务器 C 分配到 1 次请求。

        最少连接数(Least Connections):实时统计每个后端服务器当前的活跃连接数,将新的请求分配到连接数最少的服务器上。这样可以确保负载能够更均匀地分配到各个服务器,避免某些服务器因连接过多而超载。

        IP 哈希(IP Hash):根据客户端的 IP 地址计算一个哈希值,然后根据哈希值将请求分配到特定的服务器。这样,相同 IP 地址的客户端请求总是会被分配到同一台服务器,有利于保持会话的一致性。

请求转发

        根据负载均衡算法选定的后端服务器,反向代理服务器将 HTTP 请求转发给对应的服务器。在转发请求时,通常会修改请求的一些头部信息,以确保后端服务器能够正确处理请求并将响应返回给反向代理服务器。

响应返回

        后端服务器处理请求后,将响应结果返回给反向代理服务器。

        反向代理服务器再将响应返回给客户端,对于客户端来说,整个过程就像是直接从反向代理服务器获取响应一样。

[root@Nginx ~]# cd /usr/local/nginx/conf.d
[root@Nginx conf.d]# vim vhost.conf
#内容
upstream webserver {
    server 172.25.254.10:80 fail_timeout=15s max_fails=3;
    server 172.25.254.20:8080 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://webserver;
    }     
}
#测试
[root@Nginx conf.d]# curl www.timinglee.org
172.25.254.10  
[root@Nginx conf.d]# curl www.timinglee.org
172.25.254.20  
[root@Nginx conf.d]# vim vhost.conf
upstream webserver {
    ip_hash;
    server 172.25.254.10:80 fail_timeout=15s max_fails=3;
    server 172.25.254.20:8080 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://webserver;
    }
}
 
#重载测试
[root@Nginx conf.d]# nginx -s reload
[root@Nginx conf.d]# curl www.timinglee.org
172.25.254.10
[root@Nginx conf.d]# curl www.timinglee.org
172.25.254.20 
[root@Nginx conf.d]# vim vhost.conf
upstream webserver {
    #ip_hash;
    hash $request_uri consistent;
    server 172.25.254.10:80 fail_timeout=15s max_fails=3;
    server 172.25.254.20:8080 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://webserver;
    }
}
 
#重载测试
[root@Nginx conf.d]# nginx -s reload
[root@Nginx conf.d]# vim vhost.conf
upstream webserver {
    #ip_hash;
    #hash $request_uri consistent;
    hash #cookie_lee;
    server 172.25.254.10:80 fail_timeout=15s max_fails=3;
    server 172.25.254.20:8080 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://webserver;
    }
}
 
#重载测试
[root@Nginx conf.d]# nginx -s reload

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

tcp负载均衡配置参数

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

实现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代码的处理

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
}

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

源码编译php

#利用yum解决php依赖
[root@Nginx ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel
libpng-devel libcurl-devel oniguruma-devel
 
#解压源码并安装
[root@Nginx ~]# ./configure \
--prefix=/usr/local/php \         #安装路径
--with-config-file-path=/usr/local/php/etc \         #指定配置路径
--enable-fpm \         #用cgi方式启动程序
--with-fpm-user=nginx \         #指定运行用户身份
--with-fpm-group=nginx \
--with-curl \         #打开curl浏览器支持
--with-iconv \         #启用iconv函数,转换字符编码
--with-mhash \         #mhash加密方式扩展库
--with-zlib \         #支持zlib库,用于压缩http压缩传输
--with-openssl \         #支持ssl加密
--enable-mysqlnd \         #mysql数据库
--with-mysqli \
--with-pdo-mysql \
--disable-debug \             #关闭debug功能
--enable-sockets \             #支持套接字访问
--enable-soap \             #支持soap扩展协议
--enable-xml \             #支持xml
--enable-ftp \             #支持ftp
--enable-gd \             #支持gd库
--enable-exif \             #支持图片元数据
--enable-mbstring \             #支持多字节字符串
--enable-bcmath \             #打开图片大小调整,用到zabbix监控的时候用到了这个模块
--with-fpm-systemd             #支持systemctl 管理cgi

php相关配置优化

[root@Nginx ~]# cd /usr/local/php/etc
[root@Nginx etc]# cp php-fpm.conf.default php-fpm.conf
[root@Nginx etc]# vim php-fpm.conf
去掉注释
pid = run/php-fpm.pid #指定pid文件存放位置
 
[root@Nginx etc]# cd php-fpm.d/
[root@Nginx php-fpm.d]# cp www.conf.default www.conf
 
#生成主配置文件
[root@Nginx php-fpm.d]# cd /root/php-8.3.9/
[root@Nginx php-8.3.9]# cp php.ini-production /usr/local/php/etc/php.ini
[root@Nginx ~]# vim /usr/local/php/etc/php.ini
[Date]
; Defines the default timezone used by the date functions
; https://php.net/date.timezone
date.timezone = Asia/Shanghai #修改时区
 
#生成启动文件
[root@Nginx ~]# cd /root/php-8.3.9/
[root@Nginx php-8.3.9]# cp sapi/fpm/php-fpm.service /lib/systemd/system/
# Mounts the /usr, /boot, and /etc directories read-only for processes invoked by
this unit.
#ProtectSystem=full #注释该内容
 
[root@Nginx php-8.3.9]# systemctl start php-fpm.service
[root@Nginx php-8.3.9]# netstat -antlupe | grep php
tcp     0     0 127.0.0.1:9000     0.0.0.0:*     LISTEN     0
        820758 176202/php-fpm: mas

准备php测试页面

[root@Nginx ~]# mkdir /data/php -p
[root@centos8 ~]# cat /data/php/index.php #php测试页面
<?php
phpinfo();
?>

Nginx配置转发

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

[root@Nginx ~]# vim /apps/nginx/conf.d/php.conf
server {
    listen 80;
    server_name www.timinglee.org;
    root /data/php;
 
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}
#重启Nginx并访问web测试
[root@Nginx ~]# nginx -s reload

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

        OpenResty 由于有功能强大且方便的的API,可扩展性更强,如果需要实现定制功能,OpenResty是个不错的选择

官网: http://openresty.org/cn/

编译安装 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=/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
nginx version: openresty/1.17.8.2
 
[root@Nginx openresty-1.17.8.2]#openresty
 
[root@Nginx openresty-1.17.8.2]#ps -ef |grep nginx
 
[root@Nginx ~]#curl 10.0.0.18

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值