目录
5.1 ngx_http_rewrite_module 模块指令
录
企业高性能web服务器
一.Web服务基础介绍
1.1 互联网发展历程回顾
1993年3月2日,中国科学院高能物理研究所租用AT&T公司的国际卫星信道建立的接入美国SLAC国家实
验室的64K专线正式开通,成为我国连入Internet的第一根专线。
1995年马云开始创业并推出了一个web网站 中国黄页
1999年创建阿里巴巴www.alibabagroup.com
2003年5月10日创立淘宝网
2004年12月,马云创立第三方网上支付平台支付宝(蚂蚁金服旗下,共有蚂蚁金服支付宝、余额宝、招
财宝、蚂蚁聚宝、网商银行、蚂蚁花呗、芝麻信用等子业务板块)
2009年开始举办双十一购物狂欢节,以下是历年交易成交额
2009年双十一:5000万元 2010年双十一:9.36亿元 2011年双十一:33.6亿元 2012年双十一:191亿元 2013年双十一:350亿元 2014年双十一:571亿元 2015年双十一:912.17亿元 2016年双十一:1207亿元 2017年双十一:1682.69亿元 2018年双十一:2135亿元 2019年双十一:2684亿元 2020年双十一:4982亿元 2021年双十一:5403亿元 2022年双十一:5571亿元
2012年1月11日淘宝商城正式更名为“天猫”
2014年9月19日里巴巴集团于纽约证券交易所正式挂牌上市
1.2 Web 服务介绍
1.2.1 Apache 经典的 Web 服务端
Apache起初由美国的伊利诺伊大学香槟分校的国家超级计算机应用中心开发
目前经历了两大版本分别是1.X和2.X
其可以通过编译安装实现特定的功能
1.2.1.1 Apache prefork 模型
-
预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024
-
每个子进程有一个独立的线程响应用户请求
-
相对比较占用内存,但是比较稳定,可以设置最大和最小进程数
-
是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景
优点:稳定
缺点:每个用户请求需要对应开启一个进程,占用资源较多,并发性差,不适用于高并发场景
1.2.1.2 Apache worker 模型
-
一种多进程和多线程混合的模型
-
有一个控制进程,启动多个子进程
-
每个子进程里面包含固定的线程
-
使用线程程来处理请求
-
当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,
-
由于其使用了线程处理请求,因此可以承受更高的并发
优点:相比prefork 占用的内存较少,可以同时处理更多的请求
缺点:使用keepalive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超
时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用(该问题在
prefork模式下,同样会发生)
1.2.1.3 Apache event模型
Apache中最新的模式,2012年发布的apache 2.4.X系列正式支持event 模型,属于事件驱动模型(epoll)
每个进程响应多个请求,在现在版本里的已经是稳定可用的模式
它和worker模式很像,最大的区别在于,它解决了keepalive场景下长期被占用的线程的资源浪费问题
(某些线程因为被keepalive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)event MPM中,会有一个专门的线程来管理这些keepalive类型的线程
当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力
优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keep
alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放
缺点:没有线程安全控制
1.2.2 Nginx-高性能的=Web 服务端
Nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学为俄罗斯rambler.ru公司开发的,开发
工作最早从2002年开始,第一次公开发布时间是2004年10月4日,版本号是0.1.0
2019年3月11日F5 与 NGINX达成协议,F5 将收购 NGINX 的所有已发行股票,总价值约为 6.7 亿美元。6.7亿美金约合44.97亿人民币,nginx核心模块代码长度198430(包括空格、注释),所以一行代码约为2.2万人民币
官网地址 www.nginx.org
Nginx历经十几年的迭代更新(https://nginx.org/en/CHANGES), 目前功能已经非常完善且运行稳定,另外Nginx的版本分为开发版、稳定版和过期版,nginx以功能丰富著称,它即可以作为http服务器,也可以作为反向代理服务器或者邮件服务器能够快速的响应静态网页的请求
支持FastCGI/SSL/Virtual Host/URL Rwrite /Gzip / HTTP Basic Auth/http或者TCP的负载均衡(1.9版本以上且开启stream模块)等功能,并且支持第三方的功能扩展。
天猫 淘宝 京东 小米 163 新浪等一线互联网公司都在用Nginx或者进行二次开发
1.2.3 用户访问体验和性能
1.2.3.1 用户访问体验统计
互联网存在用户速度体验的1-3-10原则,即1秒最优,1-3秒较优,3~10秒比较慢,10秒以上用户无法接
受。用户放弃一个产品的代价很低,只是换一个URL而已。
全球最大搜索引擎 Google:慢500 ms = 20% 将放弃访问。
全球最大的电商零售网站亚马逊:慢100 ms = 1% 将放弃交易
有很多研究都表明,性能对用户的行为有很大的影响:
79%的用户表示不太可能再次打开一个缓慢的网站
47%的用户期望网页能在2秒钟以内加载
40%的用户表示如果加载时间超过三秒钟,就会放弃这个网站
页面加载时间延迟一秒可能导致转换损失7%,页面浏览量减少11%
8秒定律:用户访问一个网站时,如果等待网页打开的时间超过8秒,会有超过30%的用户放弃等待
1.2.3.2 影响用户体验的因素
据说马云在刚开始创业在给客户演示时,打开一个网站花了不到四个小时。
-
影响用户体验的因素
1.客户端
-
客户端硬件配置
-
客户端网络速率
-
客户端与服务端距离
2.服务器
-
服务端网络速率
-
服务端硬件配置
-
服务端架构设计
-
服务端应用程序工作模式
-
服务端并发数量服务端响应文件大小及数量 buffer cache
-
服务端I/O压力1.2.4 服务端 I/O 流程
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 文件或者图片,然后内核通过相应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存,如果是比较大的数据也需要等待时间。
机械磁盘的寻道时间、旋转延迟和数据传输时间:
寻道时间:是指磁头移动到正确的磁道上所花费的时间,寻道时间越短则I/O处理就越快,目前磁盘的寻道时
间一般在3-15毫秒左右。
旋转延迟:是指将磁盘片旋转到数据所在的扇区到磁头下面所花费的时间,旋转延迟取决于磁盘的转速,通常使用磁盘旋转一周所需要时间的1/2之一表示,比如7200转的磁盘平均训传延迟大约为
60*1000/7200/2=4.17毫秒,公式的意思为 (每分钟60秒*1000毫秒每秒/7200转每分/2),如果是15000转的则为60*1000/15000/2=2毫秒
数据传输时间:指的是读取到数据后传输数据的时间,主要取决于传输速率,这个值等于数据大小除以传输速
率,目前的磁盘接口每秒的传输速度可以达到600MB,因此可以忽略不计。
常见的机械磁盘平均寻道时间值:
7200转/分的磁盘平均物理寻道时间:9毫秒
10000转/分的磁盘平均物理寻道时间:6毫秒
15000转/分的磁盘平均物理寻道时间:4毫秒
常见磁盘的平均延迟时间:
7200转的机械盘平均延迟:60*1000/7200/2 = 4.17ms
10000转的机械盘平均延迟:60*1000/10000/2 = 3ms
15000转的机械盘平均延迟:60*1000/15000/2 = 2ms
每秒最大IOPS的计算方法:
7200转的磁盘IOPS计算方式:1000毫秒/(9毫秒的寻道时间+4.17毫秒的平均旋转延迟时
间)=1000/13.13=75.9 IOPS
10000转的磁盘的IOPS计算方式:1000毫秒/(6毫秒的寻道时间+3毫秒的平均旋转延迟时
间)=1000/9=111IOPS
15000转的磁盘的IOPS计算方式:15000毫秒/(4毫秒的寻道时间+2毫秒的平均旋转延迟时
间)=1000/6=166.6 IOPS
1.2.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,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态
-
阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态
-
阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。
-
非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。
二.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官网:nginx news
- nginx的其它的二次发行版:
- Tengine:由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。从2011年12月开始,
- Tengine成为一个开源项目官网: The Tengine Web Server
- OpenResty:基于 Nginx 与 Lua 语言的高性能 Web 平台, 章亦春团队开发,官网:OpenResty® - 开源官方站
2.1.2 Nginx 功能介绍
-
静态的web资源服务器html,图片,js,css,txt等静态资源
-
http/https协议的反向代理
-
结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
-
tcp/udp协议的请求转发(反向代理)
-
imap4/pop3协议的反向代理
2.1.3 基础特性
-
模块化设计,较好的扩展性
-
高可靠性
-
支持热部署:不停机更新配置文件,升级版本,更换日志文件
-
低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
-
event-driven,aio,mmap,sendfile
2.2 Web 服务相关的功能
-
虚拟主机(server)
-
支持 keep-alive 和管道连接(利用一个连接做多次请求)
-
访问日志(支持基于日志缓冲提高其性能)url rewirte
-
路径别名
-
基于IP及用户的访问控制
-
支持速率限制及并发数限制
-
重新配置和在线升级而无须中断客户的工作进程
2.3 Nginx 架构和进程
架构图:
web请求处理机制
-
多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求
-
多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程和此客户端进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。
-
Nginx是多进程组织模型,而且是一个由Master主进程和Worker工作进程组成。
2.3.1 Nginx 进程结构
主进程(master process)的功能:
-
对外接口:接收外部的操作(信号)
-
对内转发:根据外部的操作的不同,通过信号管理 Worker
-
监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
-
读取Nginx 配置文件并验证其有效性和正确性
-
建立、绑定和关闭socket连接
-
按照配置生成、管理和结束工作进程
-
接受外界指令,比如重启、升级及退出服务器等指令
-
不中断服务,实现平滑升级,重启服务并应用新的配置
-
开启日志文件,获取文件描述符
-
不中断服务,实现平滑升级,升级失败进行回滚处理
-
编译和处理perl脚本
工作进程(worker process)的功能:
-
所有 Worker 进程都是平等的
-
实际处理:网络请求,由 Worker 进程处理
-
Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争CPU资源,
-
增加上下文切换的损耗
-
接受处理客户的请求
-
将请求依次送入各个功能模块进行处理
-
I/O调用,获取响应数据
-
与后端服务器通信,接收后端服务器的处理结果
-
缓存数据,访问缓存索引,查询和调用缓存数据
-
发送请求结果,响应客户的请求
-
接收主程序指令,比如重启、升级和退出等
2.3.2 Nginx 进程间通信
Nginx 是一个高性能的反向代理服务器和静态内容分发器,它采用事件驱动的模型来处理请求。在进程间通信方面,Nginx 使用了一个主进程 (master) 和多个工作进程 (worker) 的架构。以下是简化的 Nginx 进程间通信流程图:
-
主进程 (Master)
-
启动时创建指定数量的工作进程,并分配配置文件给它们。
-
监控工作进程状态,如有异常会重启故障进程。
-
-
工作进程 (Worker)
-
接收来自主进程的配置信息。
-
开始监听端口,等待客户端连接。
-
当接收到新连接时,创建一个新的子线程(称为 "epoll 单元"),负责处理该连接请求。
-
epoll 单元负责读取数据、处理请求、响应数据等操作。
-
请求完成后,关闭连接并回到空闲状态,等待新的连接。
-
worker进程之间的通信原理基本上和主进程与worker进程之间的通信是一样的,只要worker进程之间能够取得彼此的信息,建立管道即可通信,但是由于worker进程之间是完全隔离的,因此一个进程想要知道另外一个进程的状态信息,就只能通过主进程来实现。
为了实现worker进程之间的交互,master进程在生成worker进程之后,在worker进程表中进行遍历,将该新进程的PID以及针对该进程建立的管道句柄传递给worker进程中的其他进程,为worker进程之间的通信做准备,当worker进程1向worker进程2发送指令的时候,首先在master进程给它的其他worker进程工作信息中找到2的进程PID,然后将正确的指令写入指向进程2的管道,worker进程2捕获到管道中的事件后,解析指令并进行相关操作,这样就完成了worker进程之间的通信。
另worker进程可以通过共享内存来通讯的,比如upstream中的zone,或者limit_reqlimit_conn中的zone等。操作系统提供了共享内存机制
- 进程间的通信
-
主进程通过信号(如
SIGCHLD
)监控工作进程的状态变化。 -
子线程(epoll 单元)通常不会直接与其他工作进程交互,而是通过共享内存区域(如 mpm_event 或 ngx.shared_memory)来进行临时数据交换。
主进程与外界通过信号机制进行通信,当接收到需要处理的信号时,它通过管道向相关的工作进程发送
正确的指令,每个工作进程都有能力捕获管道中的可读事件,当管道中有可读事件的时候,工作进程就
会从管道中读取并解析指令,然后采取相应的执行动作,这样就完成了主进程与工作进程的交互
- 事件循环 (Event Loop)
-
Nginx 的事件循环机制允许非阻塞I/O,这意味着即使某个连接在等待数据,其他连接也可以继续处理,提高了并发性能。
-
关闭连接
-
子线程处理完请求后,通常关闭连接并释放资源。
-
工作进程继续监控子线程,如果所有连接都关闭,则优雅地退出。
-
-
负载均衡
-
若配置了负载均衡策略,Nginx 可能还会涉及集群内的进程通信,例如将流量分散到不同的工作节点。
-
2.3.3 Nginx 启动和 HTTP 连接建立
-
Nginx 启动时,Master 进程,加载配置文件
-
Master 进程,初始化监听的 socket
-
Master 进程,fork 出多个 Worker 进程
-
Worker 进程,竞争新的连接,获胜方通过三次握手,建立 Socket 连接,并处理请求
2.3 HTTP 处理过程
2.4Nginx 安装
- Mainline version 主要开发版本,一般为奇数版本号,比如1.19
- Stable version 当前最新稳定版,一般为偶数版本,如:1.20
- Legacy versions 旧的稳定版,一般为偶数版本,如:1.18
- yum的版本比较旧
- 编译安装可以更方便自定义相关路径
- 使用源码编译可以自定义相关功能,更方便业务的上的使用
1.Nginx 编译安装
搭建环境
克隆9.4 4g 2 cpu
设置IP 172.25.254.115 名字 nginx-node1.txy.org
官网下载nginx
复制链接 用wget 装
#导入安装包
[root@nginx1-node ~]# ls
anaconda-ks.cfg nginx-1.24.0.tar.gz srcache-nginx-module-0.33.tar.gz
echo-nginx-module-0.63.tar.gz nginx-1.26.1.tar.gz
memc-nginx-module-0.20.tar.gz php-8.3.9.tar.gz
[root@nginx1-node ~]# tar zxf nginx-1.24.0.tar.gz
[root@nginx1-node ~]# ls
anaconda-ks.cfg nginx-1.24.0 php-8.3.9.tar.gz
echo-nginx-module-0.63.tar.gz nginx-1.24.0.tar.gz srcache-nginx-module-0.33.tar.gz
memc-nginx-module-0.20.tar.gz nginx-1.26.1.tar.gz
[root@nginx1-node ~]# tar zxf nginx-1.26.1.tar.gz
[root@nginx1-node ~]# tar zxf echo-nginx-module-0.63.tar.gz
[root@nginx1-node ~]# tar zxf memc-nginx-module-0.20.tar.gz
[root@nginx1-node ~]# tar zxf srcache-nginx-module-0.33.tar.gz
[root@nginx1-node ~]# tar zxf php-8.3.9.tar.gz
[root@nginx1-node ~]# ls
anaconda-ks.cfg nginx-1.24.0 php-8.3.9.tar.gz
echo-nginx-module-0.63 nginx-1.24.0.tar.gz srcache-nginx-module-0.33
echo-nginx-module-0.63.tar.gz nginx-1.26.1 srcache-nginx-module-0.33.tar.gz
memc-nginx-module-0.20 nginx-1.26.1.tar.gz
memc-nginx-module-0.20.tar.gz php-8.3.9
[root@nginx1-node ~]# cd nginx-1.26.1/
[root@nginx1-node nginx-1.26.1]#
#装软件
[root@nginx1-node ~]# dnf install gcc pcre-devel zlib-devel openssl-devel -y
#关闭debug
[root@nginx1-node nginx-1.26.1]# vim ~/.bash_profile
[root@nginx1-node nginx-1.26.1]# source ~/.bash_profile
#编辑
[root@nginx1-node nginx-1.26.1]# vim auto/cc/gcc
export PATH=$PATH:/usr/local/nginx/sbin
[root@nginx1-node nginx-1.26.1]# source ~/.bash_profile
[root@nginx1-node nginx-1.26.1]# useradd -s /sbin/nologin -M nginx
#查看模块
[root@nginx1-node nginx-1.26.1]# ./configure --help| less
#装模块,进行编译
[root@nginx1-node nginx-1.26.1]# ./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 --without-http_gzip_module --with-stream --with-stream_ssl_module --with-stream_realip_module --with-pcre
#编译
[root@nginx1-node nginx-1.26.1]# make && make install
#查看
[root@nginx1-node nginx-1.26.1]# ls /usr/local/nginx/
conf html logs sbin
2.平滑升级和回滚
- 关闭debug
- 添加路径
- 回滚
3.全局参数优化配置
进程绑定
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node1 ~]# vim /etc/security/limits.conf
启动
测试压力
#装压力测试工具
[root@nginx-node1 ~]# yum install httpd-tools -y
[root@nginx-node1 logs]# ab -n 10000 -c 500 http://172.25.254.115/index.html
新建一个站点
装模型
写一个子文件来放站点配置文件
#建立目录
[root@nginx-node1 ~]# mkdir /usr/local/nginx/conf.d/
#写入内容
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.txy.org;
root /webdata/nginx/txy.org/txy/html;
index index.html;
}
#建立目录
[root@nginx-node1 ~]# mkdir -p /webdata/nginx/txy.org/txy/html
#导入域名
[root@nginx-node1 ~]# echo www.txy.org > /webdata/nginx/txy.org/txy/html/index.html
[root@nginx-node1 ~]#
#检测
[root@nginx-node1 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
#刷新
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]#
加解析、
采用root指定web的家目录
出错
排除
看日志
指定alias
location
不加符号
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]# mkdir -p /data/web/html
[root@nginx-node1 ~]# echo txy > /data/web/html
[root@nginx-node1 ~]# nginx -t
[root@nginx-node1 ~]# nginx -s reload
等号 后面只能+文件
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]# mkdir /data/web{1,2}/test
[root@nginx-node1 ~]# echo web1 txy > /data/web1/test/index.html
[root@nginx-node1 ~]# echo web2 klj > /data/web2/test/index.html
[root@nginx-node1 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]#
以啥就开头
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]# mkdir -p /data/web3/{test11,teng}
[root@nginx-node1 ~]# echo test11 > /data/web3/test11/index.html
[root@nginx-node1 ~]# echo teng > /data/web3/teng/index.html
[root@nginx-node1 ~]# mkdir -p /data/web3/klj
[root@nginx-node1 ~]# echo klj > /data/web3/klj/index.html
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]#
以为啥结尾 用于标准uri前,表示包含正则表达式,并且不区分大写
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]# mkdir -p /data/web4/klj
[root@nginx-node1 ~]# echo klj > /data/web4/klj/index.html
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]#
三、Nginx 核心配置详解
3.1Nginx 账户认证功能
创建默认认证文件
[root@nginx-node1 ~]# htpasswd -cm /usr/local/nginx/.htpasswd admin
New password:
Re-type new password:
Adding password for user admin
[root@nginx-node1 ~]# cat /usr/local/nginx/.htpasswd
admin:$apr1$1sAoYOcx$KWlnbl.m5UKe752FhvzxM/
[root@nginx-node1 ~]# htpasswd -m /usr/local/nginx/.htpasswd klj
New password:
Re-type new password:
Adding password for user klj
[root@nginx-node1 ~]# cat /usr/local/nginx/.htpasswd
admin:$apr1$1sAoYOcx$KWlnbl.m5UKe752FhvzxM/
klj:$apr1$kcW.10By$konpBKQ5EO6Zt6y/JspYD/
[root@nginx-node1 ~]# mkdir /data/web/klj
[root@nginx-node1 ~]# echo klj love txy > /data/web/klj/index.html
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]#
3.2 自定义错误页面
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]# mkdir -p /data/web/errorpage
[root@nginx-node1 ~]# echo 出现错误啦~ > /data/web/errorpage/40x.html
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]#
#改提示为英文
[root@nginx-node1 ~]# echo error page> /data/web/errorpage/40x.html
[root@nginx-node1 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]#
输入中文提示,由于网页类型没事别,会出现乱码
3.3 日志重定向
[root@nginx-node1 ~]# ll /usr/local/nginx/logs/
总用量 1064
-rw-r--r-- 1 root root 1073079 8月 16 13:12 access.log
-rw-r--r-- 1 root root 8443 8月 16 13:12 error.log
-rw-r--r-- 1 root root 5 8月 16 10:39 nginx.pid
[root@nginx-node1 ~]# vim /usr/l
lib/ lib64/ libexec/ local/
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]# mkdir -p /var/l
lib/ local/ lock/ log/
[root@nginx-node1 ~]# mkdir -p /var/log/txy.org
[root@nginx-node1 ~]# nginx -s reload
nginx: [emerg] directive "error_log" is not terminated by ";" in /usr/local/nginx/conf.d/vhosts.conf:31
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]#
测试
3.4 检测文件是否存在
[root@nginx-node1 ~]# vim /etc/hosts
[root@nginx-node1 ~]# curl www.txy.org
txy
[root@nginx-node1 ~]# rm -fr /data/web/html/index.html
[root@nginx-node1 ~]# rm -fr /data/web/html/error/
[root@nginx-node1 ~]# curl www.txy.org
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.26.2</center>
</body>
</html>
[root@nginx-node1 ~]# mkdir /data/web/html/error
[root@nginx-node1 ~]# echo error default > /data/web/html/error/default.html
[root@nginx-node1 ~]# curl www.txy.org
error default
[root@nginx-node1 ~]# curl www.txy.org/ff
error default
3.5 长连接配置:
文件配置
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
装工具
3.6 作为下载服务器配置
# 做了一个大的数据
[root@nginx-node1 ~]# dd if=/dev/zero of=/data/web/download/txyfile bs=M count=100
记录了100+0 的读入
记录了100+0 的写出
104857600字节(105 MB,100 MiB)已复制,0.0908634 s,1.2 GB/s
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 ~]# nginx -s reload
加参数
修改时间为本地时间
location /download{
root /data/web;
autoindex on;
autoindex_localtime on;
autoindex_exact_size off;
limit_rate 1024k; #设置下载速度
}
四、Nginx 高级配置
4.1 状态页面
-
写配置文件
[root@nginx-node1 ~]# cd /usr/local/nginx/conf.d/ [root@nginx-node1 conf.d]# [root@nginx-node1 conf.d]# vim status.conf [root@nginx-node1 conf.d]# nginx -s reload [root@nginx-node1 conf.d]#
- 做解析 window下
- 测试
- 请求页面不能随意访问,做配置 访问限制
4.2 Nginx 压缩功能
- 配置文件
[root@nginx-node1 conf.d]# vim /usr/local/nginx/conf/nginx.conf
写一个文件测试
、
[root@nginx-node1 ~]# cd /usr/local/nginx/conf.d/
、、
[root@nginx-node1 conf.d]# echo hello txy > /data/web/html/small.html
[root@nginx-node1 conf.d]# du -sh /usr/local/nginx/logs/
1.1M /usr/local/nginx/logs/
[root@nginx-node1 conf.d]# ls /usr/local/nginx/logs/
access.log error.log nginx.pid
[root@nginx-node1 conf.d]# du -sh /usr/local/nginx/logs/access.log
1.1M /usr/local/nginx/logs/access.log
[root@nginx-node1 conf.d]# cat /usr/local/nginx/logs/access.log > /data/web/html/big.html
- 测试
[root@nginx-node1 conf.d]# curl --head --compressed 172.25.254.115/small.html
[root@nginx-node1 conf.d]# curl --head --compressed 172.25.254.115/big.html
4.3 Nginx 变量使用
-
nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用
-
变量可以分为内置变量和自定义变量
-
内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。
4.3.1 内置变量
1.常用内置变量
官方文档
http://nginx.org/en/docs/varindex.html
$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 的对应的首部字段名需要为小写,如果有横线需要替换为下划线# 示例 :echo $http_user_agent;echo $http_host;$sent_http_<name>#name 为响应报文的首部字段, name 的对应的首部字段名需要为小写,如果有横线需要替换为下划线 , 此变量有 问题echo $sent_http_server;$arg_<name># 此变量存放了 URL 中的指定参数, name 为请求 url 中指定的参数echo $arg_id;
实列演示 做实验前确保自己有echo模块
2. 自定义变量
[root@nginx-node1 conf.d]# vim /usr/local/nginx.old/conf.d/zdy.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# vim /etc/hosts
写解析
测试
五、 Nginx Rewrite 相关功能
- Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求
- 此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库
- rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能
- 比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的 链接,就可以设置为访问
- 另外还可以在一定程度上提高网站的安全性。
5.1 ngx_http_rewrite_module 模块指令
1. if指令
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-node1 ~]# cd /usr/local/nginx.old/conf.d/
[root@nginx-node1 conf.d]#
[root@nginx-node1 conf.d]# ls
! A status.conf vars.conf vhosts.conf zdy.conf
[root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# ll -d /data/web/html/test
[root@nginx-node1 conf.d]# curl var.txy.org/test2/index.html
/data/web/html/test2/index.html is not exist
[root@nginx-node1 conf.d]#
#假设存在
[root@nginx-node1 conf.d]# mkdir -p /data/web/html/test2
[root@nginx-node1 conf.d]# echo test2 > /data/web/html/test2/index.html
[root@nginx-node1 conf.d]# curl var.txy.org/test2/index.html
test2
2.set指令
演示
3.break 指令
演示:
4.return 指令
- return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重
- 定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配
- 置都将不被执行,return可以在server、if 和 location块进行配置
return code; # 返回给客户端指定的 HTTP 状态码return code [text]; # 返回给客户端的状态码及响应报文的实体内容# 可以调用变量 , 其中 text 如果有空格 , 需要用单或双引号return code URL; # 返回给客户端的 URL 地址
演示:
rewrite 指令
- 通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配, rewrite主要是针对用户请求的URL或者是URI做具体处理
- 官方文档: https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite
- 语法格式 : 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 这几个字母以外的任意字符
1.rewrite flag 使用
- 跳转型指由客户端浏览器重新对新地址进行请求
- 代理型是在WEB服务器内部实现跳转
redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求,状态码:301
break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作
#而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,
#而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户
2.rewrite案例: 域名永久与临时重定向
域名的临时的调整,后期可能会变,之前的域名或者 URL 可能还用、或者跳转的目的域名和 URL 还会跳 转,这种情况浏览器不会缓存跳转, 临时重定向不会缓存域名解析记录 (A 记录 ) ,但是永久重定向会缓存。
3.永久重定向301
4.rewrite 案例: break 与 last
测试:
[root@nginx-node1 conf.d]# mkdir /data/web/html/{test1,test2,break,last} -p
[root@nginx-node1 conf.d]# echo test1 > /data/web/html/test1/index.html
[root@nginx-node1 conf.d]# echo test2 > /data/web/html/test2/index.html
[root@nginx-node1 conf.d]# echo break > /data/web/html/break/index.html
[root@nginx-node1 conf.d]# echo last > /data/web/html/last/index.html
[root@nginx-node1 conf.d]# vim pc.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# vim /etc/hosts
5.rewrite案例: 自动跳转 https
将在不影响用户请求情况下将http请求全部自动跳转至 https,另外也可以实现部分 location 跳转
6.防盗链
防盗链基于客户端携带的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
#新建一个主机172.25.254.111,盗取另一台主机www.txy.org/images/tt.png的图片
[root@test ~]# yum install httpd -y
[root@test ~]# cd /var/www/html
[root@test html]# ls
[root@test html]# vim index.html
[root@test html]# systemctl start httpd
[root@test html]# cat index.html
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>盗链</title>
</head>
<body>
<img src="http://www.txy.org/images/txy.png" >
<h1 style="color:red">欢迎大家</h1>
<p><a href=http://www.txy.org>lalala</a>hahaha</p>
</body>
</html>
#重启apache并访问http://172.25.254.111 测试
#验证两个域名的日志,是否会在被盗连的web站点的日志中出现以下盗链日志信息
实现防盗链
当对方想链接本站网站图片,可使用rewrite指令跳转到另外一张图片,使对方获取不到原本想要的图片,从而达到防盗链的效果。
[root@nginx ~]# cd /data/web/html/
[root@nginx html]# ls
break images index.html last test1 test2 daolian.jpg
server {
listen 80;
listen 443 ssl;
server_name www.zx.org;
root /data/web/html;
index index.html;
ssl_certificate /usr/local/nginx/certs/txy.org.crt;
ssl_certificate_key /usr/local/nginx/certs/txy.org.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
location /images {
valid_referers none blocked server_names *.txy.org ~/.baidu/.;
if ( $invalid_referer ){
rewrite ^/ http://www.txy.org/txy.png;
}
}
}
六 、Nginx 反向代理功能
- 反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的 一种方式,这是用的比较多的一种方式。
- Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预 定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主 要在不同的场景使用以下模块实现不同的功能
同构代理:用户不需要其他程序的参与,直接通过http协议或者tcp协议访问后端服务器
异构代理:用户访问的资源时需要经过处理后才能返回的,比如php,python,等等,这种访问资源需要经过处理才能被访问
1,实现 http 反向代理
http 协议反向代理
反向代理配置参数
proxy_pass; #用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP地址:端口的方式,也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
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_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
案例
实验环境:
node1 | 172.25.254.110 | ngnix反向代理 |
---|---|---|
web10 | 172.25.254.10 | real server1 |
web20 | 172.25.254.20 | real server2 |
#相关基础操作
#web10与web20
[root@web10 ~]# yum install httpd
[root@web10 ~]# systemctl enable --now httpd
[root@web10 ~]# echo 172.25.254.10 > /var/www/html/index.html
[root@web20 ~]# yum install httpd
[root@web20 ~]# systemctl enable --now httpd
[root@web20 ~]# echo 172.25.254.20 > /var/www/html/index.html
#测试一下
[root@nginx-node ~]# curl 172.25.254.10
172.25.254.10
[root@nginx-node ~]# curl 172.25.254.20
172.25.254.20
#在nginx构建反向代理
server {
listen 80;
server_name www.txy.org;
location / {
proxy_pass http://172.25.254.10:80;
}
}
~
案例一 指定 location 实现反向代理
[root@web10 ~]# echo 172.25.254.10 > /var/www/html/index.html
[root@web20 ~]# mkdir -p /var/www/html/static
[root@web20 ~]# echo static 172.25.254.20 >/var/www/html/static/index.html
[root@web20 ~]# vim /etc/httpd/conf/httpd.conf # 更改listen端口为8080
[root@web20 ~]# systemctl restart httpd
[root@nginx-node ~]# vim /root/usr/local/nginx/conf.d/vhost.conf
[root@nginx-node ~]# nginx -s reload
[root@nginx-node ~]# cat /root/usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.txy.org;
location / {
proxy_pass http://172.25.254.10:80;
}
location /static {
proxy_pass http://172.25.254.20:8080;
}
}
案例二 动静分离,针对特定的资源实现代理
[root@web10 ~]# cat /var/www/html/index.php
<?php
phpinfo();
?>
[root@web10 ~]# systemctl restart httpd.service
[root@nginx-node ~]# vim /usr/local/nginx/conf.d/vars.conf
server {
listen 80;
server_name www.txy.org;
location ~ \.php$ {
proxy_pass http://172.25.254.10:80;
}
location /static{
proxy_pass http://172.25.254.20:80;
}
案例三 反向代理示例: 缓存功能
缓存功能默认关闭状态,需要先动配置才能启用
proxy_cache zone_name | off; 默认off #指明调用的缓存,或关闭缓存机制;Context:http, server, location#zone_name 表示缓存的名称.需要由proxy_cache_path事先定义
proxy_cache_key string; #缓存中用于“键”的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time; #定义对特定响应码的响应内容的缓存时长,定义在http{...}中
proxy_cache_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];
[root@nginx-node ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node ~]# vim /root/usr/local/nginx/conf.d/vhost.conf
[root@nginx-node ~]# nginx -s reload
[root@nginx-node ~]# cat /root/usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.txy.org;
location ~ \.php$ {
proxy_pass http://172.25.254.10:80;
}
location /static {
proxy_pass http://172.25.254.20:8080;
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 10m;
proxy_cache_valid any 1m;
}
}
[root@nginx-node ~]# ll /usr/local/nginx/proxy_cache/ -d
drwx------ 2 nginx root 6 Aug 19 08:08 /usr/local/nginx/proxy_cache/
[root@nginx-node ~]# tree /usr/local/nginx/proxy_cache/
非缓存场景压测
[root@nginx-node ~]# ab -n1000 -c100 http://www.txy.org/static/index.html
准备缓存配置
访问并验证缓存文件
2.http 反向代理负载均衡
- 在上一个节中Nginx可以将客户端的请求转发至单台后端服务器但是无法转发至特定的一组的服务器,而 且不能对后端服务器提供相应的服务器状态监测,Nginx 可以基于ngx_http_upstream_module模块提 供服务器分组转发、权重分配、状态监测、调度算法等高级功能
- 官方文档: https://nginx.org/en/docs/http/ngx_http_upstream_module.html
http upstream配置参数
#自定义一组服务器,配置在http块内
upstream name {
server .....
......
}
server address [parameters]; #配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置
案例
[root@web10 ~]# echo 172.25.254.10 > /var/www/html/index.html
[root@web10 ~]# systemctl enable --now httpd
[root@web20 ~]# echo 172.25.254.20 > /var/www/html/index.html
[root@web20 ~]# systemctl enable --now httpd
[root@nginx-node ~]# vim /root/usr/local/nginx/conf.d/vhost.conf
[root@nginx-node ~]# nginx -s reload
[root@nginx-node ~]# cat /root/usr/local/nginx/conf.d/vhost.conf
upstream webcluster {
#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.110 backup;
}
server {
listen 80;
server_name www.txy.org;
location / {
proxy_pass http://webcluster;
}
}
3.实现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
1.TCP负载均衡
[root@web10 named]# vim /etc/named.conf
[root@web10 named]# vim /etc/named.rfc1912.zones
[root@wb10 ~]# yum install bind -y
[root@web20 ~]# yum install bind -y
[root@wb10 ~]# cd /var/named/
[root@wb10 named]# chgrp named txy.org.zone
[root@wb10 named]# cp named.localhost txy.org.zone
[root@wb10 named]# vim txy.org.zone
[root@wb10 named]# systemctl start named
[root@wb10 named]# cat txy.org.zone # wb20同操作,IP地址改成172.25.254.20
$TTL 1D
@ IN SOA ns.txy.org. root.txy.org. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS ns.zx.org.
ns A 172.25.254.10
www A 172.25.254.10
[root@wb10 named]# dig www.txy.org @172.25.254.10
[root@wb10 named]# dig www.txy.org @172.25.254.20
[root@wb10 named]# scp -p /etc/named.{conf,rfc1912.zones} root@172.25.254.20:/etc/
[root@wb10 named]# scp -p /var/named/txy.org.zone root@172.25.254.20:/var/named/txy.org.zone
[root@nginx-node ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx -node ~]# vim /root/usr/local/nginx/conf.d/vhost.conf
[root@nginx -node ~]# cat /root/usr/local/nginx/conf.d/vhost.conf
upstream webcluster {
#ip_hash;
#hash $request_uri consistent;
hash $cookie_hello;
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.110 backup;
}
server {
listen 80;
server_name www.txy.org;
location / {
proxy_pass http://webcluster;
}
}
[root@nginx -node ~]# mkdir -p /usr/local/nginx/tcpconf.d/
[root@nginx -node ~]# cd /usr/local/nginx/tcpconf.d/
[root@nginx -node ~]# vim dns.conf
[root@nginx tcpconf.d]# cat 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;
}
}
[root@nginx tcpconf.d]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx tcpconf.d]# nginx -s reload
[root@nginx -node ~]# netstat -antlupe | grep 53
tcp6 0 0 ::1:6011 :::* LISTEN 0 2753 1818/sshd: root@pts
udp 0 0 0.0.0.0:53 0.0.0.0:* 0 60428 1007/nginx: master
udp 0 0 0.0.0.0:53 0.0.0.0:* 0 60427 1007/nginx: master
udp 0 0 0.0.0.0:5353 0.0.0.0:* 70 23214 854/avahi-daemon: r
udp6 0 0 :::5353 :::* 70 23215 854/avahi-daemon: r
[root@nginx -node ~]# dig www.txy.org @172.25.254.110
; <<>> DiG 9.16.23-RH <<>> www.txy.org @172.25.254.110
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 46262
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: f379f4ad4e910f42c34cee6a66c2cdff2fb4580c3fd45eb5 (good)
;; QUESTION SECTION:
;www.txy.org. IN A
;; Query time: 3 msec
;; SERVER: 172.25.254.110#53(172.25.254.110)
;; WHEN: Mon Aug 19 12:45:51 CST 2024
;; MSG SIZE rcvd: 67
2.负载均衡实例:MySQL
#后端服务器安装 MySQL
[root@web10 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[root@web10 ~]# mysql -e "grant all on *.* to txy@'%' identified by 'txy';"
[root@web10 ~]# mysql -utxy -ptxy -h172.25.254.10 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 20 |
+-------------+
[root@web20 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[root@web20 ~]# systemctl start mariadb.service
[root@web20 ~]# mysql -e "grant all on *.* to txy@'%' identified by 'txy';"
[root@nweb20 ~]# mysql -utxy -ptxy -h172.25.254.20 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 10 |
+-------------+7
# 配置nginx服务器
[root@nginx-node ~]# vim /usr/local/nginx/conf.d/vars.conf
stream {
upstream mysql_server {
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 172.25.254.110:3306;
proxy_pass mysql_server;
proxy_connect_timeout 30s;
proxy_timeout 300s;
}
}
4.FastCGI的 实现
Nginx与php-fpm在同一服务器
1.nginx环境搭建
#导入安装包
[root@nginx1-node ~]# ls
anaconda-ks.cfg nginx-1.24.0.tar.gz srcache-nginx-module-0.33.tar.gz
echo-nginx-module-0.63.tar.gz nginx-1.26.1.tar.gz
memc-nginx-module-0.20.tar.gz php-8.3.9.tar.gz
[root@nginx1-node ~]# tar zxf nginx-1.24.0.tar.gz
[root@nginx1-node ~]# ls
anaconda-ks.cfg nginx-1.24.0 php-8.3.9.tar.gz
echo-nginx-module-0.63.tar.gz nginx-1.24.0.tar.gz srcache-nginx-module-0.33.tar.gz
memc-nginx-module-0.20.tar.gz nginx-1.26.1.tar.gz
[root@nginx1-node ~]# tar zxf nginx-1.26.1.tar.gz
[root@nginx1-node ~]# tar zxf echo-nginx-module-0.63.tar.gz
[root@nginx1-node ~]# tar zxf memc-nginx-module-0.20.tar.gz
[root@nginx1-node ~]# tar zxf srcache-nginx-module-0.33.tar.gz
[root@nginx1-node ~]# tar zxf php-8.3.9.tar.gz
[root@nginx1-node ~]# ls
anaconda-ks.cfg nginx-1.24.0 php-8.3.9.tar.gz
echo-nginx-module-0.63 nginx-1.24.0.tar.gz srcache-nginx-module-0.33
echo-nginx-module-0.63.tar.gz nginx-1.26.1 srcache-nginx-module-0.33.tar.gz
memc-nginx-module-0.20 nginx-1.26.1.tar.gz
memc-nginx-module-0.20.tar.gz php-8.3.9
[root@nginx1-node ~]# cd nginx-1.26.1/
[root@nginx1-node nginx-1.26.1]#
#装软件
[root@nginx1-node ~]# dnf install gcc pcre-devel zlib-devel openssl-devel -y
#关闭debug
[root@nginx1-node nginx-1.26.1]# vim ~/.bash_profile
[root@nginx1-node nginx-1.26.1]# source ~/.bash_profile
#编辑
[root@nginx1-node nginx-1.26.1]# vim auto/cc/gcc
export PATH=$PATH:/usr/local/nginx/sbin
[root@nginx1-node nginx-1.26.1]# source ~/.bash_profile
[root@nginx1-node nginx-1.26.1]# useradd -s /sbin/nologin -M nginx
#查看模块
[root@nginx1-node nginx-1.26.1]# ./configure --help| less
#装模块,进行编译
[root@nginx1-node nginx-1.26.1]# ./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 --without-http_gzip_module --with-stream --with-stream_ssl_module --with-stream_realip_module --with-pcre
#编译
[root@nginx1-node nginx-1.26.1]# make && make install
#查看
[root@nginx1-node nginx-1.26.1]# ls /usr/local/nginx/
conf html logs sbin
2. 装php
#下载包解压php包
#装软件
[root@nginx1-node ~]# dnf install libsystemd-devel -y
[root@nginx1-node ~]# dnf install sqlite-devel.x86_64 -y
[root@nginx1-node ~]# dnf install libcurl-devel-7.76.1-29.el9_4.x86_64 -y
[root@nginx1-node ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel
#官网下载依赖包oniguruma,然后上传,解压安装
[root@nginx1-node ~]# cd /root
[root@nginx1-node ~]# ls
anaconda-ks.cfg nginx-1.26.1
'oniguruma-devel-6.9.6-1.el9.5.x86_64 .rpm'
[root@nginx1-node ~]# dnf install 'oniguruma-devel-6.9.6-1.el9.5.x86_64 .rpm' -y
#编译
[root@nginx1-node php-8.3.9]# ./configure --prefix=/usr/local/php --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
#装
[root@nginx1-node php-8.3.9]# make && make install
3.php相关配置优化
[root@nginx1-node php-8.3.9]# cd /usr/local/php/etc/
[root@nginx1-node etc]# cp php-fpm.conf.default php-fpm.conf
[root@nginx1-node etc]# vim php-fpm.conf
[root@nginx1-node etc]#
[root@nginx1-node etc]# cd php-fpm.d/
[root@nginx1-node php-fpm.d]# cp www.conf.default www.conf
#生成主配置文件
[root@nginx1-node php-fpm.d]# cd /root/php-8.3.9/
[root@nginx1-node php-8.3.9]# cp php.ini-production /usr/local/php/etc/php.ini
[root@nginx1-node php-8.3.9]# vim /usr/local/php/etc/php.ini
##生成启动文件
[root@nginx1-node ~]# cd php-8.3.9/
[root@nginx1-node php-8.3.9]# cp sapi/fpm/php-fpm.service /lib/systemd/system/
[root@nginx1-node php-8.3.9]# vim /lib/systemd/system/php-fpm.service
[root@nginx1-node php-8.3.9]#
#启动
[root@nginx1-node php-8.3.9]# systemctl start php-fpm.service
4.准备php测试页面
#装c编辑器
[root@nginx1-node ~]# mkdir /data/php -p
[root@nginx1-node ~]# mkdir /data/web/
[root@nginx1-node ~]# mkdir /data/web/php
#pcre
[root@nginx1-node bin]# ./php -m
[root@nginx1-node bin]# pwd
/usr/local/php/bin
[root@nginx1-node bin]# vim ~/.bash_profile
[root@nginx1-node bin]# vim ~/.bash_profile
[root@nginx1-node bin]#
[root@nginx1-node bin]# source ~/.bash_profile
[root@nginx1-node bin]#
[root@nginx1-node bin]# cd /data/web/php/
[root@nginx1-node php]# ls
[root@nginx1-node php]# vim index.php
[root@nginx1-node nginx]# mkdir conf.d
[root@nginx1-node nginx]# vim conf/nginx.conf
[root@nginx1-node nginx]#
测试
5.nginx-php的缓存优化
[root@nginx1-node ]# tar zxf memcache-8.2.tgz
[root@nginx1-node ]# cd memcache-8.2/
[root@nginx memcache-8.2]# dnf install autoconf -y
[root@nginx memcache-8.2]# yum install php-devel
[root@nginx memcache-8.2]# phpize
Configuring for:
PHP Api Version: 20200930
Zend Module Api No: 20200930
Zend Extension Api No: 420200930
[root@nginx memcache-8.2]# ./configure && make && make install
[root@nginx1-node ]# cd /usr/local/php/lib/php/extensions/no-debug-non-zts-20230831/
[root@nginx1-node ]# cd /usr/local/php/etc/
[root@nginx etc]# vim php.ini
[root@nginx etc]# systemctl restart php-fpm.service
[root@nginx1-node ]# dnf install memcached.x86_64 -y # 部署memcache
[root@nginx1-node ]# systemctl enable --now memcached.service
[root@nginx1-node ]# vim /etc/sysconfig/memcached
[root@nginx1-node ]# systemctl start memcached.service
[root@nginx lib]# cp /usr/local/php/etc/php.ini /usr/local/php/lib
#复制测试文件到nginx发布目录
[root@nginx memcache-8.2]# cp example.php memcache.php /data/web/php/
[root@nginx memcache-8.2]# cd /data/web/php/
[root@nginx php]# ls
example.php index.php memcache.php
[root@nginx php]# vim memcache.php # 修改用户名和密码,访问地址
#性能对比
[root@nginx1-node ]# ab -n1000 -c10 http://www.txy.org/index.php
6.nginx-memcache高速缓存
安装的nginx中默认不支持memc和srcache功能,需要借助第三方模块来让nginx支持此功能,所 以nginx需要重新编译(基于以上基础)
[root@nginx memcache-8.2]# systemctl restart memcached
[root@nginx memcache-8.2]# systemctl status memcached
[root@nginx memcache-8.2]# netstat -antlupe | grep 11211
[root@nginx ~]# cd /usr/local/nginx/conf.d/
[root@nginx conf.d]# ls
vhost.conf
[root@nginx conf.d]# vim vhost.conf
[root@nginx conf.d]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# cat vhost.conf
upstream memcache {
server 127.0.0.1:11211;
keepalive 512;
}
server {
listen 80;
server_name www.txy.org;
root /data/web/html;
index index.html;
location /memc {
internal;
memc_connect_timeout 100ms;
memc_send_timeout 100ms;
memc_read_timeout 100ms;
set $mem_key $query_string;
set $memc_exptime 300;
memc_pass memcache;
}
location ~ \.php$ {
root /data/web/php;
set $key $uri$args;
srcache_fetch GET /memc $key;
srcache_store PUT /memc $key;
fastcgi_pass 172.25.254.110:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}