一.Web 服务基础介绍
1.2 Web 服务介绍
1.2.1 Apache 经典的 Web 服务端
Apache起初由美国的伊利诺伊大学香槟分校的国家超级计算机应用中心开发
目前经历了两大版本分别是1.X和2.X
其可以通过编译安装实现特定的功能
1.2.1.1 Apache prefork 模型
- 预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024
- 每个子进程有一个独立的线程响应用户请求
- 相对比较占用内存,但是比较稳定,可以设置最大和最小进程数
- 是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景
优点:稳定
缺点:每个用户请求需要对应开启一个进程,占用资源较多,并发性差,不适用于高并发场景
1.2.1.3 Apache event模型
Apache中最新的模式,2012年发布的apache 2.4.X系列正式支持event 模型,属于事件驱动模型(epoll) 每个进程响应多个请求,在现在版本里的已经是稳定可用的模式
它和worker模式很像,最大的区别在于,它解决了keepalive场景下长期被占用的线程的资源浪费问题 (某些线程因为被keepalive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)event MPM中,会有一个专门的线程来管理这些keepalive类型的线程
当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力
优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keepalive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放
缺点:没有线程安全控制
1.2.2 Nginx-高性能的 Web 服务端
Nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学 伊戈尔·赛索耶夫 为俄罗斯著名搜索网站 rambler.ru开发的,开发工作最早从2002年开始,第一次公开发布时间是2004年10月4日,版本号是0.1.0
2019年3月11日F5 与 NGINX达成协议,F5 将收购 NGINX 的所有已发行股票,总价值约为 6.7 亿美元。6.7亿美金约合44.97亿人民币,nginx核心模块代码长度198430(包括空格、注释),所以一行代码约为2.2万人民币
官网地址 www.nginx.org
Nginx历经十几年的迭代更新(https://nginx.org/en/CHANGES), 目前功能已经非常完善且运行稳 定,另外Nginx的版本分为开发版、稳定版和过期版,nginx以功能丰富著称,它即可以作为http服务器,也可以作为反向代理服务器或者邮件服务器能够快速的响应静态网页的请支持FastCGI/SSL/Virtual Host/URL Rwrite /Gzip / HTTP Basic Auth/http或者TCP的负载均衡(1.9版本以上且开启stream模块)等功能,并且支持第三方的功能扩展。
天猫 淘宝 京东 小米 163 新浪等一线互联网公司都在用Nginx或者进行二次开发基于Nginx的工作场景:
1.2.3 用户访问体验和性能
1.2.3.1 用户访问体验统计
互联网存在用户速度体验的1-3-10原则,即1秒最优,1-3秒较优,3~10秒比较慢,10秒以上用户无法接受。用户放弃一个产品的代价很低,只是换一个URL而已。
1.2.4 服务端 I/O 流程
I/O在计算机中指Input/Output, IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一。IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处理的I/O请求数量为单位,I/O请求通常为读或写数据操作请求。
一次完整的I/O是用户空间的进程数据与内核空间的内核数据的报文的完整交换,但是由于内核空间与用
户空间是严格隔离的,所以其数据交换过程中不能由用户空间的进程直接调用内核空间的内存数据,而是需要经历一次从内核空间中的内存数据copy到用户空间的进程内存当中,所以简单说I/O就是把数据从内核空间中的内存数据复制到用户空间中进程的内存当中。
服务器的I/O
- 磁盘I/O
- 网络I/O : 一切皆文件,本质为对socket文件的读
1.2.4.1 磁盘 I/O
磁盘I/O是进程向内核发起系统调用,请求磁盘上的某个资源比如是html 文件或者图片,然后内核通过相应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存,如果是比较大的数据也需要等待时间
1.2.4.2 网络 I/O
网络通信就是网络协议栈到用户空间进程的IO就是网络IO
网络I/O 处理过程
- 获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3)
- 构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4)
- 返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端(5-7)
不论磁盘和网络I/O
- 每次I/O,都要经由两个阶段:
- 第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长
- 第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短
1.3 I/O 模型
1.3.1 I/O 模型相关概念
同步/异步:关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。
- 同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事 情是否处理完成
- 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态
1.3.2 网络 I/O 模型
1.3.2.1 阻塞型 I/O 模型(blocking IO)
优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源
缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销较apache 的preforck使用的是这种模式。
同步阻塞:程序向内核发送I/O请求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回,则进程将一直等待并不再接受新的请求,并由进程轮询查看I/O是否完成,完成后进程将I/O结果返回给Client,在IO没有返回期间进程不能接受其他客户的请求,而且是有进程自己去查看I/O是否完成,这种方式简单,但是比较慢,用的比较少。
1.3.2.2 非阻塞型 I/O 模型 (nonblocking IO)
1.3.2.3 多路复用 I/O 型(I/O multiplexing)
优缺点
优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述符一个线程),这样可以大大节省系统资源
缺点:当连接数较少时效率相比多线程+阻塞 I/O 模型效率较低,可能延迟更大,因为单个连接处理 需要 2 次系统调用,占用时间会有增加
IO多路复用适用如下场合:
- 当客户端处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用
- 当一个客户端同时处理多个套接字时,此情况可能的但很少出现
- 当一个服务器既要处理监听套接字,又要处理已连接套接字,一般也要用到I/O复用
- 当一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用
- 当一个服务器要处理多个服务或多个协议,一般要使用I/O复用
1.3.2.4 信号驱动式 I/O 模型 (signal-driven IO)
优点:线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此可以提高资源的利用率
缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知
异步阻塞:程序进程向内核发送IO调用后,不用等待内核响应,可以继续接受其他请求,内核收到进程请求后进行的IO如果不能立即返回,就由内核等待结果,直到IO完成后内核再通知进程
1.3.2.5 异步 I/O 模型 (asynchronous IO)
优点:异步 I/O 能够充分利用 DMA 特性,让 I/O 操作与计算重叠
缺点:要实现真正的异步 I/O,操作系统需要做大量的工作。目前 Windows 下通过 IOCP 实现了真正的异步 I/O,在 Linux 系统下,Linux 2.6才引入,目前 AIO 并不完善,因此在 Linux 下实现高并发网络编程时以 IO 复用模型模式+多线程任务的架构基本可以满足需求
Linux提供了AIO库函数实现异步,但是用的很少。目前有很多开源的异步IO库,例如libevent、libev、libuv。
异步非阻塞:程序进程向内核发送IO调用后,不用等待内核响应,可以继续接受其他请求,内核调用的IO如果不能立即返回,内核会继续处理其他事物,直到IO完成后将结果通知给内核,内核在将IO完成的结果返回给进程,期间进程可以接受新的请求,内核也可以处理新的事物,因此相互不影响,可以实现较大的同时并实现较高的IO复用,因此异步非阻塞使用最多的一种通信方式。
1.3.3 五种 IO 对比
1.3.4 I/O 的具体实现方式
1.3.4.1 I/O常见实现
Nginx支持在多种不同的操作系统实现不同的事件驱动模型,但是其在不同的操作系统甚至是不同的系统 版本上面的实现方式不尽相同,主要有以下实现方式:
1、select: select库是在linux和windows平台都基本支持的 事件驱动模型库,并且在接口的定义也基本相同,只是部分参数的含义略有差异,最大并发限制1024,是最早期的事件驱动模型。
2、poll:在Linux 的基本驱动模型,windows不支持此驱动模型,是select的升级版,取消了最大的并发限制,在编译nginx的时候可以使用--with-poll_module和--without-poll_module这两个指定是否编译select库。
3、epoll:epoll是库是Nginx服务器支持的最高性能的事件驱动库之一,是公认的非常优秀的事件驱动模型,它和select和poll有很大的区别,epoll是poll的升级版,但是与poll有很大的区别.epoll的处理方式是创建一个待处理的事件列表,然后把这个列表发给内核,返回的时候在去轮询检查这个表,以判断事件是否发生,epoll支持一个进程打开的最大事件描述符的上限是系统可以打开的文件的最大数,同时epoll库的I/O效率不随描述符数目增加而线性下降,因为它只会对内核上报的“活跃”的描述符进行操作。
4、kqueue:用于支持BSD系列平台的高校事件驱动模型,主要用在FreeBSD 4.1及以上版本、OpenBSD 2.0级以上版本NetBSD级以上版本及Mac OS X 平台上,该模型也是poll库的变种,因此和epoll没有本质上的区别,
都是通过避免轮询操作提供效率。
5、Iocp:Windows系统上的实现方式,对应第5种(异步I/O)模型。
6、rtsig:不是一个常用事件驱动,最大队列1024,不是很常用
7、/dev/poll: 用于支持unix衍生平台的高效事件驱动模型,主要在Solaris 平台、HP/UX,该模型是sun公司在开发Solaris系列平台的时候提出的用于完成事件驱动机制的方案,它使用了虚拟的/dev/poll设备,开发人员将要见识的文件描述符加入这个设备,然后通过ioctl()调用来获取事件通知,因此运行在以上系列平台的时候请使用/dev/poll事件驱动机制。
8、eventport: 该方案也是sun公司在开发Solaris的时候提出的事件驱动库,只是Solaris 10以上的版本,该驱动库看防止内核崩溃等情况的发生。
1.3.4.2 常用I/O模型比较
Select:
POSIX所规定,目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理
缺点
单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定 FD_SETSIZE,再重新编译内核实现,但是这样也会造成效率的降低单个进程可监视的fd数量被限制,默认是1024,修改此值需要重新编译内核对socket是线性扫描,即采用轮询的方法,效率较低select 采取了内存拷贝方法来实现内核将 FD 消息通知给用户空间,这样一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大
poll:
本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态其没有最大连接数的限制,原因是它是基于链表来存储的大量的fd的数组被整体复制于用户态和内核地空间之间,而不管这样的复制是不是有意义poll特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd select是边缘触发即只通知一次
epoll:
在Linux 2.6内核中提出的select和poll的增强版本支持水平触发LT和边缘触发ET,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知
优点:
没有最大并发连接的限制:能打开的FD的上限远大于1024(1G的内存能监听约10万个端口),具体查看/proc/sys/fs/file-max,此值和系统内存大小相关
效率提升:非轮询的方式,不会随着FD数目的增加而效率下降;只有活跃可用的FD才会调用callback函数,即epoll最大的优点就在于它只管理“活跃”的连接,而跟连接总数无关内存拷贝,利用mmap(Memory Mapping)加速与内核空间的消息传递;即epoll使用mmap减少复制开销
总结:
1、epoll只是一组API,比起select这种扫描全部的文件描述符,epoll只读取就绪的文件描述符,再加入基于事件的就绪通知机制,所以性能比较好
2、基于epoll的事件多路复用减少了进程间切换的次数,使得操作系统少做了相对于用户任务来说的无用功。
3、epoll比select等多路复用方式来说,减少了遍历循环及内存拷贝的工作量,因为活跃连接只占总并发连接的很小一部分。
1.4 零拷贝
1.4.1 零拷贝介绍
1.4.1.1 传统 Linux中 I/O 的问题
传统的 Linux 系统的标准 I/O 接口(read、write)是基于数据拷贝的,也就是数据都是 copy_to_user 或者 copy_from_user,这样做的好处是,通过中间缓存的机制,减少磁盘 I/O 的操作,但是坏处也很明显,大量数据的拷贝,用户态和内核态的频繁切换,会消耗大量的 CPU 资源,严重影响数据传输的性能,统计表明,在Linux协议栈中,数据包在内核态和用户态之间的拷贝所用的时间甚至占到了数据包整个处理流程时间的57.1%
1.4.1.2 什么是零拷贝
零拷贝就是上述问题的一个解决方案,通过尽量避免拷贝操作来缓解 CPU 的压力。零拷贝并没有真正做到“0”拷贝,它更多是一种思想,很多的零拷贝技术都是基于这个思想去做的优化
1.4.2 零拷页相关技术
1.4.2.1 MMAP ( Memory Mapping )
mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问。
mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。
实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。
内存映射减少数据在用户空间和内核空间之间的拷贝操作,适合大量数据传输
二.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平台。从2011年12月开始,Tengine成为一个开源项目官网: http://tengine.taobao.org/
- OpenResty:基于 Nginx 与 Lua 语言的高性能 Web 平台, 章亦春团队开发,官网:http://openresty.org/cn/
2.1.2 Nginx 功能介绍
- 静态的web资源服务器html,图片,js,css,txt等静态资源
- http/https协议的反向代理
- 结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
- tcp/udp协议的请求转发(反向代理)
- imap4/pop3协议的反向代理
2.2.3 基础特性
- 模块化设计,较好的扩展性
- 高可靠性
- 支持热部署:不停机更新配置文件,升级版本,更换日志文件
- 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
- event-driven,aio,mmap,sendfile
2.2.4 Web 服务相关的功能
- 虚拟主机(server)
- 支持 keep-alive 和管道连接(利用一个连接做多次请求)
- 访问日志(支持基于日志缓冲提高其性能)url rewirte
- 路径别名
- 基于IP及用户的访问控制
- 支持速率限制及并发数限制
- 重新配置和在线升级而无须中断客户的工作进程
2.2 Nginx 架构和进程
2.2.2 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.3 Nginx 进程间通信
工作进程是由主进程生成的,主进程使用fork()函数,在Nginx服务器启动过程中主进程根据配置文件决定启动工作进程的数量,然后建立一张全局的工作表用于存放当前未退出的所有的工作进程,主进程生成工作进程后会将新生成的工作进程加入到工作进程表中,并建立一个单向的管道并将其传递给工作进程,该管道与普通的管道不同,它是由主进程指向工作进程的单向通道,包含了主进程向工作进程发出的指令、工作进程ID、工作进程在工作进程表中的索引和必要的文件描述符等信息。
主进程与外界通过信号机制进行通信,当接收到需要处理的信号时,它通过管道向相关的工作进程发送正确的指令,每个工作进程都有能力捕获管道中的可读事件,当管道中有可读事件的时候,工作进程就会从管道中读取并解析指令,然后采取相应的执行动作,这样就完成了主进程与工作进程的交互。
2.2.4 Nginx 启动和 HTTP 连接建立
2.2.5 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 版本支持动态装载和卸载
三 Nginx 核心配置详解
3.1 配置文件说明
nginx 官方帮助文档:http://nginx.org/en/docs/
Nginx的配置文件的组成部分:
- 主配置文件:nginx.conf
- 子配置文件: include conf.d/*.conf
- fastcgi, uwsgi,scgi 等协议相关的配置文件
- mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
nginx 配置文件格式说明:
- 配置文件由指令与指令块构成
- 每条指令以;分号结尾,指令与值之间以空格符号分隔
- 可以将多条指令放在同一行,用分号分隔即可,但可读性差,不推荐
- 指令块以{ }大括号将多条指令组织在一起,且可以嵌套指令块
- include语句允许组合多个配置文件以提升可维护性
- 使用#符号添加注释,提高可读性
- 使用$符号使用变量
- 部分指令的参数支持正则表达
Nginx 主配置文件的配置指令方式:directive value [value2 ...];
注意
(1) 指令必须以分号结尾
(2) 支持使用配置变量
内建变量:由Nginx模块引入,可直接引用
自定义变量:由用户使用set命令定义,格式: set variable_name value;
引用变量:$variable_name
主配置文件结构:四部分
main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
...
}
#http/https 协议相关配置段
http {
...
}
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}
#stream 服务器相关配置段
stream {
...
}
默认的nginx.conf 配置文件格式说明
3.2 全局配置
- 正常运行必备的配置
- 优化性能相关的配置
- 用于调试及定位问题相关的配置
- 事件驱动相关的配置
user nginx nginx; #启动Nginx工作进程的用户和组
worker_processes [number | auto]; #启动Nginx工作进程的数量,一般设为和CPU核心数相同
worker_cpu_affinity 00000001 00000010 00000100 00001000 | auto ;
#将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进
程独占以一核心CPU,但是可以保证此进程不运行在其他核心上,这就极大减少了nginx的工作进程在不同的
cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务
器的性能。
CPU MASK: 00000001:0号CPU
00000010:1号CPU
10000000:7号CPU
#示例
worker_cpu_affinity 0001 0010 0100 1000;第0号---第3号CPU
worker_cpu_affinity 0101 1010;
#示例
worker_processes 4;
worker_cpu_affinity 00000010 00001000 00100000 10000000;
[root@centos8 ~]# ps axo pid,cmd,psr | grep nginx
31093 nginx: master process /apps 1
34474 nginx: worker process 1
34475 nginx: worker process 3
34476 nginx: worker process 5
34477 nginx: worker process 7
#错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit
| alert | emerg]
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log /usr/local/nginx/logs/error.log error;
#pid文件保存路径
pid /usr/local/nginx/logs/nginx.pid;
worker_priority 0; #工作进程优先级,-20~20(19)
worker_rlimit_nofile 65536; #所有worker进程能打开的文件数量上限,
#包括:Nginx的所有连接(例如与代理服务器的连接等)
#而不仅仅是与客户端的连接
#另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制
#最好与ulimit -n 或者limits.conf的值保持一致,
#修改pam限制
[root@Nginx ~]# sudo -u nginx ulimit -n
1024
[root@Nginx ~]# vim /etc/security/limits.conf
* - nofile 100000
[root@Nginx ~]# sudo -u nginx ulimit -n
100000
daemon off; #前台运行Nginx服务用于测试、docker等环境。
master_process off|on; #是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为on
events {
worker_connections 65535; #设置单个工作进程的最大并发连接数
use epoll; #使用epoll事件驱动,
#Nginx支持众多的事件驱动,
#比如:select、poll、epoll,只能设置在events模块中设置
accept_mutex on; #on为同一时刻一个请求轮流由work进程处理,
#而防止被同时唤醒所有worker
#避免多个睡眠进程被唤醒的设置,默认为off
#新请求会唤醒所有worker进程,此过程也称为"惊群"
#因此nginx刚安装完以后要进行适当的优化。建议设置为on
multi_accept on; #on时Nginx服务器的每个工作进程可以同时接受多个新的网络连接
#此指令默认为off,
#即默认为一个工作进程只能一次接受一个新的网络连接
#打开后几个同接受多个。建议设置为on
}
3.3 实验案例
3.3.1 实验环境
webservera #eth0 172.25.254.10
RS1 #eth0 172.25.254.100
RS2 #eth0 172.25.254.200
3.3.2 编译安装 Nginx


使用安装完成的二进制文件nginx
设置环境变量和启动文件
###设置环境变量,以便后续直接使用nginx指令
[root@webserver nginx-1.24.0]# vim ~/.bash_profile
export PATH=$PATH:/usr/local/nginx/sbin
[root@webserver nginx-1.24.0]# source ~/.bash_profile
[root@webserver nginx-1.24.0]# nginx -V #查看版本信息
nginx version: nginx/1.24.0
built by gcc 11.4.1 20230605 (Red Hat 11.4.1-2) (GCC)
built with OpenSSL 3.0.7 1 Nov 2022
TLS SNI support enabled
configure arguments: --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
###设置启动脚本
[root@webserver nginx-1.24.0]# 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
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root@webserver nginx-1.24.0]# systemctl daemon-reload
[root@webserver nginx-1.24.0]# systemctl start nginx.service
3.4 高并发配置
[root@webserver ~]# cd /usr/local/nginx
[root@webserver nginx]# vim conf/nginx.conf
...
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
worker_rlimit_nofile 100000;
...
events {
...
worker_connections 100000;
use epoll;
...
}
测试:
#测试
[root@webserver nginx]# dnf install httpd-tools-2.4.57-5.el9.x86_64
[root@webserver nginx]# echo webservera > html/index.html
[root@webserver nginx]# systemctl restart nginx
[root@webserver nginx]# ab -c 5000 -n 10000 http://172.25.254.10/
...
Complete requests: 10000
Failed requests: 0
...
3.5 新建一个 PC web 站点
#定义子配置文件路径
[root@Nginx ~]# mkdir /usr/local/nginx/conf.d/
[root@centos8 ~]# vim /usr/local/nginx/conf/nginx.conf
http {
......
include /apps/nginx/conf/conf.d/*.conf; #在配置文件的最后面添加此行
#注意不要放在最前面,会导致前面的命令无法 生效
}
#创建虚拟主机网站配置
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
}
[root@Nginx ~]# mkdir -p /webdata/nginx/timinglee.org/lee/html
[root@Nginx ~]# echo lee.timinglee.org > /webdata/nginx/timinglee.org/lee/html/index.html [root@Nginx ~]# nginx -s reload
#访问测试
[root@node100 ~]# curl lee.timinglee.org #注意在访问主机中设解析
lee.timinglee.org
3.6 root与alias
#
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
location /root {
root /web/;
}
location /alias {
alias /web/root;
}
}
[root@webserver nginx]# nginx -s reload
#测试
[root@webserver nginx]# mkdir /web/root/
[root@webserver nginx]# echo 无论这么访问都是root > /web/root/index.html
[root@webserver nginx]# curl www.timinglee.org/root/
无论这么访问都是root
[root@webserver nginx]# curl www.timinglee.org/alias/
无论这么访问都是root
3.7 location 的详细使用
在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;
ngnix会根据用户请求的URI来检查定义的所有location,按一定的优先级找出一个最佳匹配, 而后应用其配置在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最高的一个uri
uri是用户请求的字符串,即域名后面的web文件路径 然后使用该location模块中的正则url和字符串,如果匹配成功就结束搜索,并使用此location处理此请求。
3.8 Nginx 账户认证功能
[root@webserver nginx]# htpasswd -cmb conf/.htpasswd admin lee
Adding password for user admin
[root@webserver nginx]# htpasswd -mb conf/.htpasswd lee lee
Adding password for user lee
[root@webserver nginx]# mkdir /web/auth/
[root@webserver nginx]# echo login > /web/auth/index.html
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
location /auth {
root /web/
auth_basic "login password";
auth_basic_user_file "/usr/local/nginx/conf/.htpasswd";
}
}
[root@webserver nginx]# nginx -s reload
[root@webserver nginx]# curl www.timinglee.org/auth/ -u lee:lee
login
3.9自定义错误页面
error_page code ... [=[response]] uri;
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
error_page 500 502 503 504 /error.html;
location /error.html {
root /web/error/;
}
}
[root@webserver nginx]# nginx -s reload
[root@webserver nginx]# mkdir /web/error
[root@webserver nginx]# echo error123 > /web/error/error.html
[root@webserver nginx]# curl www.timinglee.org/aa
error123
自定义错误日志
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
[root@webserver nginx]# nginx -s reload
[root@webserver nginx]# mkdir /var/log/nginx -p
[root@webserver nginx]# touch /var/log/nginx/access.log
[root@webserver nginx]# touch /var/log/nginx/error.log
#测试
[root@webserver nginx]# curl 172.25.254.10
webservera
[root@webserver nginx]# curl www.timinglee.org
...
[root@webserver nginx]# cat /var/log/nginx/error.log
2025/08/11 19:13:22 [error] 41686#0: *12245 directory index of "/web/" is forbidden, client: 172.25.254.10, server: www.timinglee.org, request: "GET / HTTP/1.1", host: "www.timinglee.org"
[root@webserver nginx]# cat /var/log/nginx/access.log
172.25.254.10 - - [11/Aug/2025:19:13:22 +0800] "GET / HTTP/1.1" 403 153 "-" "curl/7.76.1"
3.11 检测文件是否存在
try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如 果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内部500错误。
Syntax: try_files file ... uri;
try_files file ... =code; Default: —
Context: server, location
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
error_page 404 /web/error/error.html
try_files $uri.html $uri.html $uri/index.html /web/default.html;
location /error {
root /web/;
}
}
[root@webserver nginx]# nginx -s reload
[root@webserver nginx]# curl www.timinglee.org/a/
3.12 长连接配置
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
keepalive_timeout 65; #65秒后自动断开
#连接请求3次后断开
#开启长连接后,返回客户端的会话保持时间为60s,单次长连接累计请求达到指定次数请求或65秒就会被断
开,第二个数字60为发送给客户端应答报文头部中显示的超时时间设置为60s:如不设置客户端将不显示超时时
间。
keepalive_requests 3;
#浏览器收到的服务器返回的报文
#如果设置为0表示关闭会话保持功能,将如下显示:
#Connection:close 浏览器收到的服务器返回的报文
error_log /var/log/nginx/error.log;
}
[root@webserver nginx]# dnf install telnet -y
[root@webserver nginx]# telnet 172.25.254.10 80
Trying 172.25.254.10...
Connected to 172.25.254.10.
Escape character is '^]'.
GET / HTTP/1.1
Host: www.timinglee.org
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Mon, 11 Aug 2025 13:27:13 GMT
Content-Type: text/html
Content-Length: 9
Last-Modified: Mon, 11 Aug 2025 10:31:31 GMT
Connection: keep-alive
ETag: "6899c683-9"
Accept-Ranges: bytes
web_html
GET / HTTP/1.1
Host: www.timinglee.org
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Mon, 11 Aug 2025 13:27:38 GMT
Content-Type: text/html
Content-Length: 9
Last-Modified: Mon, 11 Aug 2025 10:31:31 GMT
Connection: keep-alive
ETag: "6899c683-9"
Accept-Ranges: bytes
web_html
GET / HTTP/1.1
Host: www.timinglee.org
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Mon, 11 Aug 2025 13:27:46 GMT
Content-Type: text/html
Content-Length: 9
Last-Modified: Mon, 11 Aug 2025 10:31:31 GMT
Connection: close
ETag: "6899c683-9"
Accept-Ranges: bytes
web_html
Connection closed by foreign host.
[root@webserver nginx]#
3.13作为下载服务器配置
#创建下载文件
[root@webserver nginx]# mkdir /web/download
[root@webserver nginx]# dd if=/dev/zero of=/web/download/lee bs=1M count=500
500+0 records in
500+0 records out
524288000 bytes (524 MB, 500 MiB) copied, 3.28797 s, 159 MB/s
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
error_log /var/log/nginx/error.log;
location /download {
root /web/;
autoindex on; #自动索引功能
autoindex_exact_size on; #计算文件确切大小(单位bytes),此为默认值,off只显示大概大小(单位kb、mb、gb)
autoindex_localtime on; #on表示显示本机时间而非GMT(格林威治)时间,默为为off显示GMT时间
limit_rate 1024k; #限速,默认不限速
}
}
[root@webserver nginx]# nginx -s reload
[root@webserver nginx]# 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="lee">lee</a> 11-Aug-2025 21:37 524288000
</pre><hr></body>
</html>
四 Nginx 高级配置
4.1 Nginx 状态页
- 基于nginx 模块 ngx_http_stub_status_module 实现,
- 在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module
- 否则配置完成之后监测会是提示法错误
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
error_log /var/log/nginx/error.log;
location /status {
stub_status;
auth_basic "status page"; #开启状态页
auth_basic_user_file "/usr/local/nginx/conf/.htpasswd"; #用户认证文件
}
}
[root@webserver nginx]# nginx -s reload
4.2 Nginx 压缩功能
Nginx支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相应的CPU资源。
Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module,默认是内置模块
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
error_log /var/log/nginx/error.log;
#启用或禁用gzip压缩,默认关闭
gzip on;
#压缩比由低到高从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.1;
#指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers 16 8k;
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
# gzip_types ...;
#如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”,一般建议打开
gzip_vary on;
#预压缩,即直接从磁盘找到对应文件的gz后缀的式的压缩文件返回给用户,无需消耗服务器CPU
#注意: 来自于ngx_http_gzip_static_module模块
gzip_static on;
}
[root@webserver nginx]# nginx -s reload
cp /usr/local/nginx/logs/access.log /web/html/data.html
[root@webserver nginx]# curl --head --compressed 172.25.254.10/data.html
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Mon, 11 Aug 2025 14:15:49 GMT
Content-Type: text/html
Last-Modified: Mon, 11 Aug 2025 14:13:09 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: W/"6899fa75-4bc2d0"
Content-Encoding: gzip
4.3 Nginx的版本隐藏
[root@Nginx nginx-1.26.1]# vim src/core/nginx.h
#define nginx_version 1026001
#define NGINX_VERSION "1.0"
#define NGINX_VER "HAHA/" NGINX_VERSION
4.4 Nginx 变量使用
- nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用
- 变量可以分为内置变量和自定义变量
- 内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值
$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为任意请求报文首部字段,表示记录请求报文的首部字段,name的对应的首部字段名需要为小写,如果有
横线需要替换为下划线
#示例:
echo $http_user_agent;
echo $http_host;
$sent_http_<name>
#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有
问题
echo $sent_http_server;
$arg_<name>
#此变量存放了URL中的指定参数,name为请求url中指定的参数
echo $arg_id;
代码:
[root@webserver nginx]# cd ~
[root@webserver ~]# ls
anaconda-ks.cfg nginx-1.24.0 nginx-1.26.1
echo-nginx-module-0.63.tar.gz nginx-1.24.0.tar.gz nginx-1.26.1.tar.gz
[root@webserver ~]# tar zxf echo-nginx-module-0.63.tar.gz
[root@webserver ~]# rm -rf nginx-1.26.1
[root@webserver ~]# nginx -V
nginx version: nginx/1.26.1
built by gcc 11.4.1 20230605 (Red Hat 11.4.1-2) (GCC)
built with OpenSSL 3.0.7 1 Nov 2022
TLS SNI support enabled
configure arguments: --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
[root@webserver ~]# tar zxf nginx-1.26.1.tar.gz
[root@webserver ~]# cd nginx-1.26.1/
#在之前的./configure里加上 --add-module=/root/echo-nginx-module-0.63
[root@webserver nginx-1.26.1]# ./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 --add-module=/root/echo-nginx-module-0.63
[root@webserver nginx-1.26.1]# cd objs/
[root@webserver objs]# cp -p nginx /usr/local/nginx/sbin/nginx
[root@webserver objs]# cp /usr/local/nginx/conf/nginx.conf /mnt
[root@webserver objs]# cp -rp /usr/local/nginx/conf.d /mnt
[root@webserver objs]# rm -rf /usr/local/nginx/
[root@webserver objs]# cd ..
[root@webserver nginx-1.26.1]# make install
[root@webserver nginx-1.26.1]# cp /mnt/nginx.conf /usr/local/nginx/conf/nginx.conf
cp: overwrite '/usr/local/nginx/conf/nginx.conf'? y
[root@webserver nginx-1.26.1]# cp -r /mnt/conf.d/ /usr/local/nginx/
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
error_log /var/log/nginx/error.log;
location /test {
default_type text/html;
echo $remote_addr;
echo $args;
echo $document_root;
echo $document_uri;
echo $host;
echo $http_user_agent;
}
}
[root@webserver nginx]# systemctl restart nginx.service
[root@webserver nginx]# nginx -s reload
[root@webserver nginx]# curl www.timinglee.org/test
172.25.254.10
/web/html
/test
www.timinglee.org
curl/7.76.1
五 Nginx Rewrite 相关功能
- Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求
- 此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库
- rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能
- 比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的 链接,就可以设置为访问
- 另外还可以在一定程度上提高网站的安全性
5.1 if 指令
if (条件匹配) { action }
使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接:

location /test {
index index.html;
default_type text/html;
if ( $scheme = http ){
echo "if ---------> $scheme";
}
if ( $scheme = https ){
echo "if ---------> $scheme";
}
}
location /test2 {
if ( !-e $request_filename ){
echo "$request_filename is not exist";
return 409;
}
}
测试:
[root@client ~]# curl lee.timinglee.org/test/
if ---------> http
[root@client ~]# curl lee.timinglee.org/test2/test
/webdata/nginx/timinglee.org/lee/test2/test is not exist
5.2 set 指令
指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key
另外set定义格式为set $key value,value可以是text, variables和两者的组合。
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /test3{
set $name lee;
echo $name;
}
}
测试:
[root@client ~]# curl lee.timinglee.org/test3
lee
5.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
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /break{
default_type text/html;
set $name lee;
echo $name;
break;
set $port $server_port;
echo $port;
}
}
[root@client ~]# curl lee.timinglee.org/break #当未添加break时
lee
80
[root@client ~]# curl lee.timinglee.org/break #添加break后
lee
5.4 return 指令
return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置
语法格式:
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /return {
default_type text/html;
if ( !-e $request_filename){
return 301 http://www.baidu.com;
#return 666 "$request_filename is not exist";
}
echo "$request_filename is exist";
}
}
测试:
[root@client ~]# curl lee.timinglee.org/return
/webdata/nginx/timinglee.org/lee/return is exist
[root@client ~]# curl lee.timinglee.org/return1
/webdata/nginx/timinglee.org/lee/return1 is not exist
#测试return 301 http://www.baidu.com;
可在浏览器直接访问lee.timinglee.org/return1
5.5 rewrite 指令
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配, rewrite主要是针对用户请求的URL或者是URI做具体处理
rewrite regex replacement [flag];
rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制
如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向301
5.5.1 rewrite flag 使用介绍
利用nginx的rewrite的指令,可以实现url的重新跳转,rewrite有四种不同的flag,分别是redirect(临时 重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型
- 跳转型指由客户端浏览器重新对新地址进行请求
- 代理型是在WEB服务器内部实现跳转
rewrite 格式:
Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据包。Default: —
Context: server, location, if
5.6 Nginx 防盗链
防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:
5.6.1 实现盗链
在一个web 站点盗链另一个站点的资源信息,比如:图片、视频等
#RS1模拟盗链客户端
[root@RS1 ~]# dnf install httpd
[root@RS1 ~]# vim /var/www/html/index.html
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>盗链</title>
</head>
<body>
<img src="http://www.timinglee.org/images/lee.png" >
<h1 style="color:red">欢迎大家</h1>
<p><a href=http://www.timinglee.org</a>出门见喜</p>
</body>
</html>
[root@RS1 ~]# vim /etc/hosts
172.25.254.10 www.timinglee.org
[root@RS1 ~]# systemctl start httpd
#准备好照片
[root@webserver nginx]# mkdir /web/html/image
[root@webserver nginx]# cp ~/test.png /web/html/image/
在172.25.254.100的服务器的images文件夹内上传图片1.png。
浏览器输入:http://172.25.254.100可以看到该站点自动连接到100服务器的图片
实现防盗链
#webserver
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
index index.html;
error_log /var/log/nginx/error.log;
location / {
valid_referers none blocked server_names *.timinglee.org ~/.baidu/.;
if ($invalid_referer){
return 404;
}
}
}
[root@webserver nginx]# nginx -s reload
六 Nginx 反向代理功能
反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的 一种方式,这是用的比较多的一种方式。
Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能
6.1 实现 http 反向代理
6.1.1 http 协议反向代理
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协议转发至指定服务器处理
#官方文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
proxy_pass; #用来设置将客户端请求转发给的后端服务器的主机
#可以是主机名(将转发至后端服务做为主机头首部)、IP地址:端口的方式
#也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
#示例:
proxy_pass http://172.25.254.30:8080; #8080后面无uri,即无 / 符号,
#需要将location后面url 附加到proxy_pass指定的url后面
#此行为类似于root
#proxy_pass指定的uri不带斜线将访问的/web
#等于访问后端服务器
proxy_pass http://172.25.254.40:8080/; #8080后面有uri,即有 / 符号
#相当于置换,即访问/web时实际返回proxy_pass后面uri内容
#此行为类似于alias
#proxy_pass指定的uri带斜线
#等于访问后端服务器的
#http://172.25.254.40:8080/index.html
#内容返回给客户端
#如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能
使用uri
#即不能有/ ,用户请求时传递的uri将直接附加至后端服
proxy_hide_header field; #用于nginx作为反向代理的时候
#在返回给客户端http响应时
#隐藏后端服务器相应头部的信息
#可以设置在http,server或location块务器之后
proxy_pass_header field; #透传
#默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数
#如果要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端
#field 首部字段大小不敏感
proxy_pass_request_body on | off;
#是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启
proxy_pass_request_headers on | off;
#是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启
proxy_set_header;
#可更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实IP的时候,就要更改每一个报文的头部
proxy_connect_timeout time;
#配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60秒
用法如下:proxy_connect_timeout 6s;
#60s为自定义nginx与后端服务器建立连接的超时时间,超时会返回客户端504响应码
proxy_read_timeout time;
#配置nginx服务器向后端服务器或服务器组发起read请求后,等待的超时时间,默认60s
proxy_send_timeout time;
#配置nginx项后端服务器或服务器组发起write请求后,等待的超时 时间,默认60s
proxy_http_version 1.0;
#用于设置nginx提供代理服务的HTTP协议的版本,默认http 1.0
proxy_ignore_client_abort off;
#当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求。即如果此项设置为on开启,则服务器、会忽略客户端中断并一直等着代理服务执行返回,如果设置为off,则客户端中断后Nginx也会中断客户端请求并立即记录499日志,默认为off。
6.1.2 反向代理示例: 缓存功能
缓存功能默认关闭状态,需要先动配置才能启用
proxy_cache zone_name | off; 默认off
#指明调用的缓存,或关闭缓存机制;Context:http, server, location
#zone_name 表示缓存的名称.需要由proxy_cache_path事先定义
proxy_cache_key string;
#缓存中用于“键”的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
#定义对特定响应码的响应内容的缓存
示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;时长,定义在http{...}中
proxy_cache_path;
#定义可用于proxy功能的缓存;Context:http
proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number]
[manager_sleep=time] [manager_threshold=time] [loader_files=number]
[loader_sleep=time] [loader_threshold=time] [purger=on|off]
[purger_files=number] [purger_sleep=time] [purger_threshold=time];
proxy_cache_path /var/cache/nginx/proxy_cache #定义缓存保存路径,proxy_cache会自动创建
levels=1:2:2 #定义缓存目录结构层次
#1:2:2可以生成
keys_zone=proxycache:20m #指内存中缓存的大小,主要用于存放key和metadata
(如:使用次数)
#一般1M可存放8000个左右的key
inactive=120s #缓存有效时间
max_size=10g; #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
#调用缓存功能,需要定义在相应的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key
proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 1m; #除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 |
http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off
#在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端
示例
proxy_cache_use_stale error http_502 http_503;
proxy_cache_methods GET | HEAD | POST ...;
#对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
实验:
#webserver
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /web/html;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://www.lee.org;
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 10m;
proxy_cache_valid any 1m;
}
location ~ \.(php|jpg|gif)$ {
proxy_pass http://172.25.254.200:80;
}
}
[root@webserver nginx]# vim conf/nginx.conf
http{
...
proxy_cache_path /usr/local/nginx/cache levels=1:2:2 keys_zone=proxycache:20m inactive=120s max_size=10g;
...
}
#加缓存之前
[root@RS2 ~]# ab -c 500 -n 10000 http://www.timinglee.org/index.html
Time per request: 1846.322 [ms] (mean)
#加缓存之后
[root@RS2 ~]# ab -c 500 -n 10000 http://www.timinglee.org/index.html
Time per request: 230.727 [ms] (mean)
6.2 实现 Nginx 四层负载均衡
Nginx在1.9.0版本开始支持tcp模式的负载均衡,在1.9.13版本开始支持udp协议的负载,udp主要用于DNS的域名解析,其配置方式和指令和http 代理类似,其基于ngx_stream_proxy_module模块实现tcp负载,另外基于模块ngx_stream_upstream_module实现后端服务器分组转发、权重分配、状态监测、调度算法等高级功能。
如果编译安装,需要指定 --with-stream 选项才能支持ngx_stream_proxy_module模块
6.2.1 tcp负载均衡配置参数
6.2.2 负载均衡实例: bind
#RS1 和 RS2
[root@RS1 ~]# dnf install bind -y
[root@RS1 ~]# vim /etc/named.conf
options {
// listen-on port 53 { 127.0.0.1; };
// listen-on-v6 port 53 { ::1; };
...
// allow-query { localhost; };
...
dnssec-validation no;
}
[root@RS1 ~]# cd /var/named
[root@RS1 named]# cp -p named.localhost "timinglee.org.zone"
[root@RS1 named]# vim timinglee.org.zone #RS2下面的ip是200
$TTL 1D
@ IN SOA dns.timinglee.org. root.timinglee.org. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS dns.timinglee.org.
dns A 172.25.254.100
[root@RS1 named]# vim /etc/named.rfc1912.zones
...
zone "timinglee.org" IN {
type master;
file "timinglee.org.zone";
allow-update { none; };
};
...
[root@RS1 named]# systemctl restart named
#webserver
[root@webserver nginx]# mkdir tcp.d
[root@webserver nginx]# vim tcp.d/dns.conf
[root@webserver nginx]# vim conf/nginx.conf
include "/usr/local/nginx/tcp.d/*.conf" ; #不能写在http语句块中
[root@webserver nginx]# vim tcp.d/dns.conf
stream {
upstream dns {
server 172.25.254.100:53 max_fails=3 fail_timeout=5;
server 172.25.254.200:53 max_fails=3 fail_timeout=5;
}
server {
listen 53 udp;
proxy_pass dns;
}
}
[root@webserver nginx]# nginx -s reload
6.3 实现 FastCGI
6.3.1 FastCGI配置指令
Nginx基于模块ngx_http_fastcgi_module实现通过fastcgi协议将指定的客户端请求转发至php-fpm处理,其配置指令如下:
6.3.2 FastCGI实战案例 : Nginx与php-fpm在同一服务器
###源码编译php
[root@webserver ~]# cd ~
[root@webserver ~]# dnf install -y bzip2 systemd-devel libxml2-devel sqlite-devel
[root@webserver ~]# dnf install -y libpng-devel libcurl-devel
[root@webserver ~]# ls
anaconda-ks.cfg nginx-1.24.0 nginx-1.26.1.tar.gz php-8.3.9
echo-nginx-module-0.63 nginx-1.24.0.tar.gz oniguruma-6.9.6-1.el9.6.x86_64.rpm php-8.3.9.tar.gz
echo-nginx-module-0.63.tar.gz nginx-1.26.1 oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm test.png
#两个包,不一样
[root@webserver ~]# dnf update oniguruma-6.9.6-1.el9.6.x86_64.rpm
[root@webserver ~]# dnf install oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm
[root@webserver ~]# tar zxf php-8.3.9.tar.gz
[root@webserver ~]# cd php-8.3.9/
./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --enable-fpm --with-fpm-user=nginx --with-fpm-group=nginx --with-curl --with-iconv --with-mhash --with-zlib --with-openssl --enable-mysqlnd --with-mysqli --with-pdo-mysql --disable-debug --enable-sockets --enable-soap --enable-xml --enable-ftp --enable-gd --enable-exif --enable-mbstring --enable-bcmath --with-fpm-systemd
[root@webserver ~]# make && make install
#等待ing~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[root@webserver php-8.3.9]# cd /usr/local/php/
[root@webserver php]# cd etc/
[root@webserver etc]# cp -p php-fpm.conf.default php-fpm.conf
[root@webserver etc]# vim php-fpm.conf
pid = run/php-fpm.pid #指定pid文件存放位置,给代码去掉注释
[root@webserver etc]# cd php-fpm.d/
[root@webserver php-fpm.d]# cp www.conf.default www.conf -p
[root@webserver php-fpm.d]# vim www.conf
listen = 0.0.0.0:9000
[root@webserver php-fpm.d]# cd ~/php-8.3.9/
[root@webserver php-8.3.9]# cp php.ini-production /usr/local/php/etc/php-ini
[root@webserver php-8.3.9]# cd sapi/fpm/
[root@webserver fpm]# cp php-fpm.service /lib/systemd/system
[root@webserver fpm]# cd /lib/systemd/system
[root@webserver system]# vim php-fpm.service
...
#ProtectSystem=full
[root@webserver system]# systemctl daemon-reload
[root@webserver system]# systemctl enable --now php-fpm.service
[root@webserver nginx]# cd /usr/local/nginx/
[root@webserver nginx]# vim html/index.php
<?php
phpinfo ();
?>
[root@webserver nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
error_log /var/log/nginx/error.log;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf;
}
}
[root@webserver nginx]# nginx -s reload
6.3.3 php的动态扩展模块(php的缓存模块)
软件下载:http://pecl.php.net/package/memcache
###memcache整合php
[root@webserver nginx]# dnf install memcached -y
[root@webserver nginx]# vim /etc/sysconfig/memcached
...
OPTIONS="-l 0.0.0.0,::1"
[root@webserver nginx]# systemctl enable --now memcached.service
[root@webserver ~]# ls
anaconda-ks.cfg nginx-1.24.0 oniguruma-6.9.6-1.el9.6.x86_64.rpm test.png
echo-nginx-module-0.63 nginx-1.24.0.tar.gz oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm
echo-nginx-module-0.63.tar.gz nginx-1.26.1 php-8.3.9
memcache-8.2.tgz nginx-1.26.1.tar.gz php-8.3.9.tar.gz
[root@webserver ~]# tar zxf memcache-8.2.tgz
[root@webserver ~]# cd memcache-8.2/
[root@webserver memcache-8.2]# cp example.php memcache.php /usr/local//nginx/html/
[root@webserver memcache-8.2]# cd /usr/local/nginx/
[root@webserver nginx]# ls html/
50x.html example.php index.html index.php memcache.php
[root@webserver nginx]# vim html/memcache.php
...
define('ADMIN_USERNAME','admin'); // Admin Username
define('ADMIN_PASSWORD','lee'); // Admin Password
#$MEMCACHE_SERVERS[] = 'mymemcache-server1:11211'; // add more as an array
$MEMCACHE_SERVERS[] = '127.0.0.1:11211'; // add more as an array
...
###php整合memcache
[root@webserver nginx]# vim ~/.bash_profile
export PATH=$PATH:/usr/local/nginx/sbin:/usr/local/php/bin:/usr/local/php/sbin
[root@webserver nginx]# source ~/.bash_profile
[root@webserver nginx]# cd ~/memcache-8.2/
[root@webserver memcache-8.2]# dnf install autoconf -y
[root@webserver memcache-8.2]# phpize
[root@webserver memcache-8.2]# ./configure && make && make install
[root@webserver memcache-8.2]# cd /usr/local/php/lib/php/extensions/no-debug-non-zts-20230831/
[root@webserver no-debug-non-zts-20230831]# ls
memcache.so opcache.so
[root@webserver no-debug-non-zts-20230831]# systemctl restart php-fpm.service
[root@webserver no-debug-non-zts-20230831]# cd /usr/local/php/etc/
[root@webserver etc]# vim php-ini
...
975 extension=memcache
...
990 date.timezone = Asia/Shangha
...
6.3.4 php高速缓存
部署方法
在我们安装的nginx中默认不支持memc和srcache功能,需要借助第三方模块来让nginx支持此功能,所以nginx需要重新编译
[root@Nginx ~]# rm -fr /apps/nginx/
[root@webserver nginx]# mv conf.d /mnt
[root@webserver nginx]# mv conf/nginx.conf /mnt
[root@webserver nginx]# rm -rf /usr/local/nginx/
[root@webserver nginx]# cd ~
[root@webserver ~]# tar zxf memc-nginx-module-0.20.tar.gz
[root@webserver ~]# tar zxf srcache-nginx-module-0.33.tar.gz
[root@webserver ~]# cd nginx-1.26.1/
[root@webserver nginx-1.26.1]# ./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 --add-module=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module-0.33 --add-module=/root/echo-nginx-module-0.63
[root@webserver nginx]# cp /mnt/nginx.conf conf/nginx.conf
[root@webserver nginx]# vim conf.d/vhost.conf
upstream memcache {
server 127.0.0.1:11211;
keepalive 512;
}
server {
listen 80;
server_name www.timinglee.org;
error_log /var/log/nginx/error.log;
location /memc {
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;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf;
}
}
[root@webserver nginx]# nginx -s reload
[root@webserver nginx]# vim html/index.php
#测试
[root@webserver nginx]# ab -n1000 -c50 http://www.timinglee.org/index.php
...
Complete requests: 1000
Failed requests: 0 #not have 失败
...
7 nginx 二次开发版本
7.1 openresty
Nginx 是俄罗斯人发明的, Lua 是巴西几个教授发明的,中国人章亦春把 LuaJIT VM 嵌入到 Nginx 中, 实现了 OpenResty 这个高性能服务端解决方案
OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将Nginx有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。
OpenResty 由于有功能强大且方便的的API,可扩展性更强,如果需要实现定制功能,OpenResty是个不错的选择
7.2 编译安装 openresty
[root@webserver nginx]# systemctl stop nginx.service
[root@webserver nginx]# cd ~
[root@webserver ~]# rm -rf /usr/local/nginx/
[root@webserver ~]# ls
anaconda-ks.cfg memc-nginx-module-0.20.tar.gz package.xml
echo-nginx-module-0.63 nginx-1.26.1 php-8.3.9
echo-nginx-module-0.63.tar.gz nginx-1.26.1.tar.gz php-8.3.9.tar.gz
memcache-8.2 oniguruma-6.9.6-1.el9.6.x86_64.rpm srcache-nginx-module-0.33
memcache-8.2.tgz oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm srcache-nginx-module-0.33.tar.gz
memc-nginx-module-0.20 openresty-1.25.3.1.tar.gz
[root@webserver ~]# tar zxf openresty-1.25.3.1.tar.gz
[root@webserver ~]# cd openresty-1.25.3.1/
[root@webserver openresty-1.25.3.1]# dnf -y install gcc pcre-devel openssl-develperl
[root@webserver openresty-1.25.3.1]# useradd -r -s /sbin/nologin nginx
[root@webserver openresty-1.25.3.1]# ./configure --prefix=/usr/local/openresty --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module
[root@webserver openresty-1.25.3.1]# make && make install
[root@webserver openresty-1.25.3.1]# openresty -t
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
[root@webserver openresty-1.25.3.1]# openresty