企业高性能web服务器
一、Apache经典的Web服务端
1.1 Apache-prefork模型
单个子进程,单线程
- 预派生模式,有一个主控制进程,然后生成多个子进程,使用 select 模型,最大并发1024。
- 每个子进程有一个独立的线程响应用户请求。
- 相对比较占用内存,但是比较稳定,可以设置最大和最小进程数。
- 是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景。
优点 :稳定缺点 :每个用户请求需要对应开启一个进程 , 占用资源较多,并发性差 , 不适用于高并发场景
1.2 Apache-worker模型
多个子进程,多个线程(一个进程可处理多个请求)
- 一种多进程和多线程混合的模型
- 有一个控制进程,启动多个子进程
- 每个子进程里面包含固定的线程
- 使用线程程来处理请求
- 当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,
- 由于其使用了线程处理请求,因此可以承受更高的并发
优点 :相比 prefork 占用的内存较少,可以同时处理更多的请求缺点 :使用 keepalive 的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超 时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用(该问题在 prefork 模式下,同样会发生)
1.3 Apache-event模型
多个子进程开启多个线程,每个子进程多了一个监听线程。对系统资源节省较多。
- Apache 中最新的模式,2012年发布的 apache 2.4.X 系列正式支持 event 模型,属于事件驱动模型(epoll)
- 每个进程响应多个请求,在现在版本里的已经是稳定可用的模式
- 它和 worker 模式很像,最大的区别在于,它解决了 keepalive 场景下长期被占用的线程的资源浪费问题(某些线程因为被 keepalive ,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)
- event MPM 中,会有一个专门的线程来管理这些keepalive类型的线程
- 当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场 景下的请求处理能力
优点 :单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理 keep-alive 类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放缺点 :没有线程安全控制
二、、Nginx-高性能的web服务器
2.1 nginx的安装
环境准备:
rhel9克隆:nginx(172.25.254.100)
实验步骤:
[root@nginx-node1 ~]# tar zxf nginx-1.24.0.tar.gz
[root@nginx-node1 ~]# ls
anaconda-ks.cfg echo-nginx-module-0.63.tar.gz nginx-1.24.0 nginx-1.24.0.tar.gz nginx-1.26.1.tar.gz#安装依赖
[root@nginx-node1 ~]# dnf install gcc pcre-devel zlib-devel openssl-devel -y[root@nginx-node1 ~]# cd nginx-1.24.0/
[root@nginx-node1 nginx-1.24.0]# ./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[root@nginx-node1 nginx-1.24.0]# make && make install
[root@nginx-node1 nginx-1.24.0]# useradd -s /sbin/nologin -M nginx
[root@nginx-node1 nginx-1.24.0]# ls
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README
[root@nginx-node1 nginx-1.24.0]#
[root@nginx-node1 nginx-1.24.0]# ls /usr/local/nginx/
conf html logs sbin
[root@nginx-node1 nginx-1.24.0]# cd[root@nginx-node1 ~]# vim ~/.bash_profile
[root@nginx-node1 ~]# source ~/.bash_profile#查看大小
[root@nginx-node1 ~]# du -sh /usr/local/nginx/sbin/nginx
5.5M /usr/local/nginx/sbin/nginx#启动nginx
[root@nginx-node1 ~]# nginx 


2.2 平滑升级与回滚
[root@nginx-node1 ~]# ls
anaconda-ks.cfg echo-nginx-module-0.63.tar.gz nginx-1.24.0 nginx-1.24.0.tar.gz nginx-1.26.1.tar.gz
[root@nginx-node1 ~]# tar zxf echo-nginx-module-0.63.tar.gz
[root@nginx-node1 ~]# tar zxf nginx-1.26.1.tar.gz [root@nginx ~]# cd nginx-1.26.1/
[root@nginx nginx-1.26.1]# ./configure --prefix=/usr/local/nginx \
--user=nginx \ # 指定nginx运行用户
--group=nginx \ # 指定nginx运行组
--add-module=/root/echo-nginx-module-0.63
--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加密
--with-stream_realip_module # 支持tcp的透传ip[root@nginx nginx-1.26.1]# make#关闭nginx,进行make install
[root@nginx-node1 ~]# nginx -s stop
[root@nginx-node1 ~]# rm -rf /usr/local/nginx/
[root@nginx-node1 ~]# cd nginx-1.24.0/
[root@nginx-node1 nginx-1.24.0]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src
[root@nginx-node1 nginx-1.24.0]# make install
[root@nginx-node1 nginx-1.24.0]# cd /usr/local/nginx/
[root@nginx-node1 nginx]# ls
conf html logs sbin
[root@nginx-node1 nginx]# cd sbin/
[root@nginx-node1 sbin]# ls
nginx#启动nginx
[root@nginx-node1 sbin]# nginx
[root@nginx-node1 sbin]# curl -I 172.25.254.100
[root@nginx-node1 sbin]# cp nginx nginx.old
[root@nginx-node1 sbin]# ls
nginx nginx.old
[root@nginx-node1 sbin]# \cp -f /root/nginx-1.26.1/objs/nginx /usr/local/nginx/sbin/
[root@nginx-node1 sbin]# ll
total 11584
-rwxr-xr-x 1 root root 6178008 Aug 15 16:30 nginx
-rwxr-xr-x 1 root root 5679776 Aug 15 16:30 nginx.old[root@nginx-node1 sbin]# ps aux | grep nginx
root 10924 0.0 0.0 9916 936 ? Ss 16:29 0:00 nginx: master process nginx
nginx 10925 0.0 0.1 13756 5356 ? S 16:29 0:00 nginx: worker process
root 10940 0.0 0.0 6408 2280 pts/3 S+ 16:31 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]# pidof nginx
10925 10924
[root@nginx-node1 sbin]# kill -USR2 10924
[root@nginx-node1 sbin]# ps aux | grep nginx
root 10924 0.0 0.0 9916 2532 ? Ss 16:29 0:00 nginx: master process nginx
nginx 10925 0.0 0.1 13756 5356 ? S 16:29 0:00 nginx: worker process
root 10943 0.0 0.1 9952 6540 ? S 16:32 0:00 nginx: master process nginx
nginx 10944 0.0 0.1 13792 4776 ? S 16:32 0:00 nginx: worker process
root 10946 0.0 0.0 6408 2296 pts/3 S+ 16:32 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]# kill -WINCH 10924 #回收旧的work进程#该命令后变为1.16.1
[root@nginx-node1 ~]# curl -I 172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.26.1[root@nginx-node1 sbin]# ps aux | grep nginx
root 10924 0.0 0.0 9916 2532 ? Ss 16:29 0:00 nginx: master process nginx
root 10943 0.0 0.1 9952 6540 ? S 16:32 0:00 nginx: master process nginx
nginx 10944 0.0 0.1 13792 4776 ? S 16:32 0:00 nginx: worker process
root 10948 0.0 0.0 6408 2296 pts/3 S+ 16:33 0:00 grep --color=auto nginx[root@nginx-node1 sbin]# kill -HUP 10924 #激活旧版本
#该命令后恢复到:[root@nginx-node1 ~]# curl -I 172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.24.0[root@nginx-node1 sbin]# ps aux | grep nginx
root 10924 0.0 0.0 9916 2532 ? Ss 16:29 0:00 nginx: master process nginx
root 10943 0.0 0.1 9952 6540 ? S 16:32 0:00 nginx: master process nginx
nginx 10944 0.0 0.1 13792 5256 ? S 16:32 0:00 nginx: worker process
nginx 10950 0.0 0.1 13756 4752 ? S 16:33 0:00 nginx: worker process
root 10952 0.0 0.0 6408 2296 pts/3 S+ 16:33 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]# kill -WINCH 10943 #回收新版本
[root@nginx-node1 sbin]# ps aux | grep nginx
root 10924 0.0 0.0 9916 2532 ? Ss 16:29 0:00 nginx: master process nginx
root 10943 0.0 0.1 9952 6540 ? S 16:32 0:00 nginx: master process nginx
nginx 10950 0.0 0.1 13756 4752 ? S 16:33 0:00 nginx: worker process
root 10954 0.0 0.0 6408 2284 pts/3 S+ 16:34 0:00 grep --color=auto nginx#将新版本的nginx变为nginx.new,将旧的nginx.old变为nginx:
[root@nginx-node1 sbin]# ls
nginx nginx.old
[root@nginx-node1 sbin]# cp nginx nginx.new
[root@nginx-node1 sbin]# \cp -f nginx.old nginx
[root@nginx-node1 sbin]# ls
nginx nginx.new nginx.old#删除新的进程:
[root@nginx-node1 sbin]# ps aux | grep nginx
root 10712 0.0 0.0 9916 2560 ? Ss 19:18 0:00 nginx: master process nginx
root 10731 0.0 0.1 9952 6532 ? S 19:20 0:00 nginx: master process nginx
nginx 10739 0.0 0.1 13756 5432 ? S 19:21 0:00 nginx: worker process
root 10770 0.0 0.0 6408 2300 pts/0 S+ 19:26 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]# kill -9 10731
[root@nginx-node1 sbin]# ps aux | grep nginx
root 10712 0.0 0.0 9916 2560 ? Ss 19:18 0:00 nginx: master process nginx
nginx 10739 0.0 0.1 13756 5432 ? S 19:21 0:00 nginx: worker process
root 10772 0.0 0.0 6408 2244 pts/0 S+ 19:26 0:00 grep --color=auto nginx 三、I/O模型
IOPS (Input/Output Per Second) 即每秒的输入输出量(或读写次数)
3.1 影响IOPS的因素:
磁盘I/O
网络I/O: 一切皆文件,本质为对 socket 文件的读写
磁盘I/O
磁盘 I/O 是进程向内核发起系统调用,请求磁盘上的某个资源比如是 html 文件或者图片,然后内核通过相应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存,如果是比较大的数据也需要等待时间。
网络I/O
网络通信就是网络协议栈到用户空间进程的 I/O 就是网络 I/O
网络I/O处理过程
获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3)
构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4)
返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端(5-7)
不论磁盘和网络I/O
每次 I/O,都要经由两个阶段:
第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长
第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短
3.2 I/O模型相关概念
同步与异步:
同步/异步:关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。
同步:synchronous ,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成。异步: asynchronous ,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态

以上图为例:一个请求进入到2,进程接收到请求,3没有数据,就让内核去拷,内核就将数据从缓存拷贝到4,然后内核再拷贝到3
内核4去拷贝的过程中,拷没拷好是否通知进程3。不通知:同步;通知:异步
阻塞与非阻塞:
阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态
阻塞:blocking ,指 I/O 操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。非阻塞: nonblocking ,指 I/O 操作被调用后立即返回给用户一个状态值,而无需等到 I/O 操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。
比如:一个用户通知进程,要查看默认发布文件,这个进程就需要通知内核去取。内核取的过程中,进程是否等待
等待状态:阻塞
非等待状态:非阻塞
常见模型:
阻塞型 I/O 模型
同步阻塞:一个进程只能处理一个请求
- 阻塞 I/O 模型是最简单的 I/O 模型,用户线程在内核进行 I/O 操作时被阻塞
- 用户线程通过系统调用 read 发起 I/O 读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成 read 操作
- 用户需要等待 read 将数据读取到 buffer 后,才继续处理接收的数据。整个 I/O 请求的过程中,用户线程是被阻塞的,这导致用户在发起 I/O 请求时,不能做任何事情,对 CPU 的资源利用率不够
优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源
缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销较 apache 的 preforck 使用的是这种模式。
非阻塞型 I/O 模型
同步非阻塞:内核不会告知是否拷贝好了没有,需要自己去检测
用户线程发起 I/O 请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起 I/O 请求,直到数据到达后,才真正读取到数据,继续执行。即 “轮询”机制存在两个问题:如果有大量文件描述符都要等,那么就得一个一个的 read。这会带来大量的 Context Switch(read是系统调用,每调用一次就得在用户态和核心态切换一次)。轮询的时间不好把握。这里是要猜多久之后数据才能到。等待时间设的太长,程序响应延迟就过大;设的太短,就会造成过于频繁的重试,干耗 CPU 而已,是比较浪费 CPU 的方式,一般很少直接使用这种模型,而是在其他 I/O 模型中使用非阻塞 I/O 这一特性。
信号驱动式 I/O 模型
异步阻塞:内核会给出反馈,不需要等待,可以享用其他进程
信号驱动 I/O 的意思就是进程现在不用傻等着,也不用去轮询。而是让内核在数据就绪时,发送信号通知进程。
调用的步骤是,通过系统调用 sigaction,并注册一个信号处理的回调函数,该调用会立即返回,然后主程序可以继续向下执行,当有 I/O 操作准备就绪,即内核数据就绪时,内核会为该进程产生一个 SIGIO 信号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用 recvfrom 获取数据,将用户进程所需要的数据从内核空间拷贝到用户空间。
此模型的优势在于等待数据报到达期间进程不被阻塞。用户主程序可以继续执行,只要等待来自信号处理函数的通知。
在信号驱动式 I/O 模型中,应用程序使用套接口进行信号驱动 I/O,并安装一个信号处理函数,进程继续运行并不阻塞
当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 I/O 操作函数处理数据。
优点:线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此可以提高资源的利用率。
缺点:信号 I/O 在大量 I/O 操作时可能会因为信号队列溢出导致没法通知。
异步阻塞:程序进程向内核发送 I/O 调用后,不用等待内核响应,可以继续接受其他请求,内核收到进程请求后进行的 I/O 如果不能立即返回,就由内核等待结果,直到 I/O 完成后内核再通知进程。
异步 I/O 模型
异步非阻塞
异步 I/O 与 信号驱动 I/O 最大区别在于,信号驱动是内核通知用户进程何时开始一个 I/O 操作,而异步 I/O 是由内核通知用户进程 I/O 操作何时完成,两者有本质区别,相当于不用去饭店场吃饭,直接点个外卖,把等待上菜的时间也给省了。
相对于同步 I/O,异步 I/O 不是顺序执行。用户进程进行 aio_read 系统调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到 socket 数据准备好了,内核直接复制数据给进程,然后从内核向进程发送通知。I/O 两个阶段,进程都是非阻塞的。
信号驱动 I/O当内核通知触发信号处理程序时,信号处理程序还需要阻塞在从内核空间缓冲区拷贝数据到用户空间缓冲区这个阶段,而异步 I/O 直接是在第二个阶段完成后,内核直接通知用户线程可以进行后续操作了。
优点:异步 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 复用,因此异步非阻塞使用最多的一种通信方式。
多路复用 I/O 型
一个进程可接收多个请求:通过select记录一个列表,然后由select通知内核进行缓存。select会进行遍历,判断是否好了,通知进程。最多支持1024个链接。(poll没有链接受限,但链接越多越慢。epoll只记录好的,没好的不做记录,速度会更快,少了遍历的过程)
I/O 多路复用( I/O Multiplexing) :是一种机制,程序注册一组 socket 文件描述符给操作系统,表示“ 我要监视这些fd 是否有 IO 事件发生,有了就告诉程序处理” I/O 多路复用一般和 NIO 一起使用的。 NIO 和 I/O 多路 复用是相对独立的。NIO 仅仅是指 I/O API 总是能立刻返回,不会被 Blocking; 而 I/O 多路复用仅仅是操作系统提供的一种便利的通知机制。操作系统并不会强制这俩必须得一起用,可以只用 I/O 多路复用 + BIO ,这时还是当前线程被卡住。I/O 多路复用和 NIO 是要配合一起使用才有
优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述符一个线程),这样可以大大节省系统资源。
缺点:当连接数较少时效率相比多线程 + 阻塞 I/O 模型效率较低,可能延迟更大,因为单个连接处理需要 2 次系统调用,占用时间会有增加。
五种I/O的对比
这五种 I/O 模型中,越往后,阻塞越少,理论上效率也是最优前四种属于同步 I/O ,因为其中真正的 I/O 操作(recvfrom) 将阻塞进程 / 线程,只有异步 I/O 模型才与 POSIX 定义的异步 I/O 相匹配。
apache使用的是同步阻塞(优点:稳定。缺点:慢)
nginx使用的是异步非阻塞
常用I/O模型比较:
| select | poll | epoll | |
| 操作方法 | 遍历 | 遍历 | 回调 |
| 底层实现 | 数组 | 链表 | 哈希表 |
| I/O 效率 | 每次调用都进行线性遍历,时间复杂度为 O(n) | 同左 | 事件通知方式,每当 fd 就绪,系统注册的回调函数就会被调用,将就绪的 fd 放到 dllist 里,时间复杂度 O(1) |
| 最大连接数 | 1024(x86) 2048(x64) | 无上限 | 无上限 |
| fd 拷贝 | 每次调用 select 都需要把 fd 集合从用户拷贝到内核态 | 每次调用 poll,都需要把 fd 集合从用户态拷贝到内核态 | 调用 epoll_ct 时拷贝进内核并保存,之后每次 epoll_wait 不拷贝 |
3.3 零拷贝
内核的缓冲区共享给用户的缓冲区所使用,从而减少拷贝的过程
四、Nginx
4.1 nginx命令常用参数
[root@nginx-node1 sbin]# nginx -v #查看版本
[root@nginx-node1 sbin]# nginx -V #查看版本详细信息
[root@nginx-node1 sbin]# nginx -t #检查配置文件的语法是否正确
[root@nginx-node1 sbin]# nginx -T #测试并打印
[root@nginx-node1 sbin]# nginx -q #静默模式(开启nginx)
[root@nginx-node1 sbin]# nginx -s #指定信号
[root@nginx-node1 sbin]# nginx -p #指定nginx命令
[root@nginx-node1 sbin]# nginx -c #指定文件路径
[root@nginx-node1 sbin]# nginx -g #开启nginx时,指定配置。设置全局指令,注意和配置文件不要同时配置,否则冲突 4.2 设置nginx的开机启动文件
/lib/systemd/system/nginx.service
五、Nginx核心配置示例
5.1 全局配置及实现nginx的高并发配置
[ root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
[ root@nginx-node1 ~]# mkdir -p /usr/local/nginx/conf.d
[ root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[ root@nginx-node1 ~]# vim ~/.vimrc
[ root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[ root@nginx-node1 ~]# mkdir -p /data/web/html
[ root@nginx-node1 ~]# echo www.test.org > /data/web/html/index.html
[ root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
serve {listen 80;server_name www.test.org;root /data/web/html;index index.html;location /test1/ {root /data/web;}
}
[ root@nginx-node1 ~]# nginx -t
[ root@nginx-node1 ~]# nginx -s reload[ root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[ root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
serve {listen 80;server_name www.test.org;root /data/web/html;index index.html;location /test1/ {root /data/web;}location /test2 {alias /data/web/test1;}
}
[ root@nginx-node1 ~]# nginx -t
[ root@nginx-node1 ~]# nginx -s reload user nginx;
worker_processes auto; #有几个核就开几个
worker_cpu_affinity 01 10; #cpu的核心绑定,将这两个进程绑定到各自的核上去 
[root@nginx-node1 logs]# vim /etc/security/limits.conf
[root@nginx-node1 logs]# sudo -u nginx ulimit -a 
压力测试:
[root@nginx-node1 logs]# dnf install httpd-tools -y
[root@nginx-node1 logs]# ab -n 100 -c 50 http://172.25.254.100/index.html
[root@nginx-node1 logs]# ab -n 10000 -c 5000 http://172.25.254.100/index.html#将下面的配置文件都改为100000
[root@nginx-node1 logs]# vim /etc/security/limits.conf
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node1 ~]# nginx -s reload 
5.2 新建一个PC web站点
[ root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
[ root@nginx-node1 ~]# mkdir -p /usr/local/nginx/conf.d
[ root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[ root@nginx-node1 ~]# mkdir -p /data/web/html
[ root@nginx-node1 ~]# echo www.test.org > /data/web/html/index.html
[ root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
serve {listen 80;server_name www.test.org;root /data/web/html;index index.html;
} user nginx;
worker_processes auto;
worker_cpu_affinity 01 10;#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;#pid logs/nginx.pid;events {worker_connections 100000;use epoll;
}
...include "/usr/local/nginx/conf.d/*.conf";
... 测试:

5.3 root与alias
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;location /test1/ {root /data/web;}location /test2 {alias /data/web/test1;}
}
[root@nginx-node1 ~]# nginx -s reload 
5.4 location
优先级:
对目录匹配:
~*|~>无符号>^~>=对文件匹配: 但以同样结尾的uri文件,
=>~*|~>无符号>^~
[root@nginx-node1 ~]# nginx
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# mkdir -p /data/web/test
[root@nginx-node1 ~]# echo test page > /data/web/test/index.html
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;location /test {root /data/web;}location = /test {root /data/web;}
} 
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# mkdir /data/web{1,2}
[root@nginx-node1 ~]# mkdir /data/web{1,2}/test
[root@nginx-node1 ~]# echo web1 test > /data/web1/test/index.html
[root@nginx-node1 ~]# echo web2 test > /data/web2/test/index.html
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;location /test {root /data/web1;}location = /test {root /data/web2;}
} 
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;location = /test {root /data/web2;}location /test {root /data/web1;}location ^~ /t {root /data/web1;}
} 
[root@nginx-node1 ~]# mkdir -p /data/web1/{test1,tee}
[root@nginx-node1 ~]# echo test1 > /data/web1/test1/index.html
[root@nginx-node1 ~]# echo tee > /data/web1/tee/index.html
[root@nginx-node1 ~]# mkdir -p /data/web1/haha
[root@nginx-node1 ~]# echo haha > /data/web1/haha/index.html
[root@nginx-node1 ~]# nginx -s reload 

5.5 Nginx 账户认证功能
创建默认认证文件:
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[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$lmV1OI.y$Se4ONlcA1gbkgSiJXy4F[root@nginx-node1 ~]# htpasswd -m /usr/local/nginx/.htpasswd lee
New password:
Re-type new password:
Adding password for user lee
[root@nginx-node1 ~]# cat /usr/local/nginx/.htpasswd
admin:$apr1$lmV1OI.y$Se4ONlcA1gbkgSiJXy4F
lee:$apr1$qh/q8ic/$csWx57bXPCPLb5vxvlv/ 用户认证:
#无认证模式:
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# mkdir /data/web/lee
[root@nginx-node1 ~]# echo lee > /data/web/lee/index.html
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;location /lee {root /data/web;}
}
[root@nginx-node1 ~]# nginx -s reload 
#用户认证模式:
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;location /lee {root /data/web;auth_basic "login password !!";auth_basic_user_file "/usr/local/nginx/.htpasswd";}
}
[root@nginx-node1 ~]# nginx -s reload 
5.6 自定义错误页面
默认页面:
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# mkdir -p /data/web/errorpage
[root@nginx-node1 ~]# echo error page > /data/web/errorpage/40x.html
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;error_page 404 /40x.html;location /lee {root /data/web;auth_basic "login password !!";auth_basic_user_file "/usr/local/nginx/.htpasswd";}location = /40x.html {root /data/web/errorpage;}
}
[root@nginx-node1 ~]# nginx -s reload 
自定义日志:
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# mkdir /var/log/test.org
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# cat /var/log/test.org/access.log
172.25.254.1 - - [16/Aug/2024:14:31:59 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/8.4.0"
[root@nginx-node1 ~]# cat /var/log/test.org/error.log
2024/08/16 14:32:15 [error] 1885#0: *40 open() "/data/web/html/aaa" failed (2: No such file or directory), client: 172.25.254.1, server: www.test.org, request: "GET /aaa HTTP/1.1", host: "www.test.org"
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;error_page 404 /40x.html;error_log /var/log/test.org/error.log;access_log /var/log/test.org/access.log;location /lee {root /data/web;auth_basic "login password !!";auth_basic_user_file "/usr/local/nginx/.htpasswd";}location = /40x.html {root /data/web/errorpage;}
} 
5.7 检测文件是否存在:
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# rm -rf /data/web/html/index.html #删除原本会出来的内容www.test.org
[root@nginx-node1 ~]# mkdir /data/web/html/error
#没有内容前是500的错误
[root@nginx-node1 ~]# echo error default > /data/web/html/error/default.html
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/vhost.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;error_page 404 /40x.html;error_log /var/log/test.org/error.log;access_log /var/log/test.org/access.log;try_files $uri $uri.html $uri/index.html /error/default.html;location /lee {root /data/web;auth_basic "login password !!";auth_basic_user_file "/usr/local/nginx/.htpasswd";}location = /40x.html {root /data/web/errorpage;}
} 
5.8 长连接配置
[root@nginx-node1 ~]# dnf install telnet -y #测试工具
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node1 ~]# echo www.test.org > /data/web/html/index.html
[root@nginx-node1 ~]# nginx -s reloadkeepalive_timeout 65;keepalive_requests 2; #该实验测试请求次数不得超过两次#测试语句:
GET / HTTP/1.1
Host: www.test.org 

[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node1 ~]# nginx -s reloadkeepalive_timeout 5; #该实验测试长连接的最长等待时间keepalive_requests 2; 
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node1 ~]# nginx -s reloadkeepalive_timeout 65 60; #该实验测试给用户显示的时间keepalive_requests 2; 
5.9 作为下载服务器配置
[root@nginx-node1 ~]# mkdir /data/web/download
[root@nginx-node1 ~]# dd if=/dev/zero of=/data/web/download/testfile bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.0301573 s, 3.5 GB/s
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# nginx -s reload location /download {root /data/web;autoindex on; #自动索引内容,实现访问}

location /download {root /data/web;autoindex on; #自动索引内容,实现访问autoindex_localtime on; #on表示显示本机时间而非GMT(格林威治)时间,默为为off显示GMT时间autoindex_exact_size off;limit_rate 1024k;} 前后对比:

六、Nginx高级配置
6.1 状态页
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/status.conf
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/status.conf
server {listen 80;server_name status.test.org;root /data/web/html;index index.html;location /status {stub_status;#allow 172.25.254.1;#deny all;}
}
[root@nginx-node1 ~]# nginx -s reload 
[root@nginx-node1 ~]# vim /etc/hosts
[root@nginx-node1 ~]# curl status.test.org/status/
Active connections: 1
server accepts handled requests73 73 101
Reading: 0 Writing: 1 Waiting: 0 [root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/status.conf
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# curl status.test.org/status/
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.26.1</center>
</body>
</html>
[root@nginx-node1 ~]# cat /usr/local/nginx/conf.d/status.conf
server {listen 80;server_name status.test.org;root /data/web/html;index index.html;location /status {stub_status;allow 172.25.254.1;deny all;}
} 前后对比:

6.2 压缩功能
#dnf install -y
#curl --head --compressed #查看响应报头的头部[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# echo hello test > /data/web/html/small.html
[root@nginx-node1 ~]# du -sh /usr/local/nginx/logs/access.log
32K /usr/local/nginx/logs/access.log
[root@nginx-node1 ~]# cat /usr/local/nginx/logs/access.log > /data/web/html/big.html
[root@nginx-node1 ~]#
[root@nginx-node1 ~]# curl --head --compressed 172.25.254.100/small.html
[root@nginx-node1 ~]# curl --head --compressed 172.25.254.100/big.html
#在传输过程中对文件进行压缩,原文件大小没有变gzip on;gzip_comp_level 5;gzip_min_length 1k;gzip_http_version 1.1;gzip_vary on;gzip_types text/plain application/javascript application/x-javascript text/css
application/xml text/javascript application/x-httpd-php image/gif image/png; 6.3 Nginx变量使用
server {listen 80;server_name var.test.org;root /data/web/html;index index.html;location /var {default_type text/html;echo $remote_addr; #存放了客户端的地址,注意是客户端的公网IPecho $args; #变量中存放了URL中的所有参数echo $is_args; #如果有参数为? 否则为空echo $document_root; #保存了针对当前资源的请求的系统根目录echo $document_uri; #保存了当前请求中不包含参数的URI,注意是不包含请求的指令echo $host; #存放了请求的host名称echo $remote_port; #客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口echo $remote_user; #已经经过Auth Basic Module验证的用户名echo $request_method; #请求资源的方式,GET/PUT/DELETE等echo $request_filename; #当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径echo $request_uri; #包含请求参数的原始URI,不包含主机名echo $scheme; #请求的协议echo $server_protocol; #保存了客户端请求资源使用的协议的版本echo $server_addr; #保存了服务器的IP地址echo $server_name; #虚拟主机的主机名echo $server_port; #虚拟主机的端口号echo $http_user_agent; #客户端浏览器的详细信息echo $http_cookie; #客户端的所有cookie信息echo $cookie_<name>; #name为任意请求报文首部字部cookie的key名echo $http_<name>; #name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有横线需要替换为下划线echo $sent_http_<name>; #name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有问题}
} [root@nginx-node1 ~]# cd /usr/local/nginx/conf.d
[root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# vim /etc/hosts
#172.25.254.100 var.test.org
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl -b "key1=lee,key2=lee1" -u lee:lee var.test.org/var?name=lee&&id=6666
172.25.254.100
name=lee
?
/data/web/html
/var
var.test.org
53464
lee
GET
/data/web/html/var
/var?name=lee
http
HTTP/1.1
172.25.254.100
var.test.org
80
curl/7.76.1
key1=lee,key2=lee1
lee1
lee server {listen 80;server_name var.test.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;}
} 自定义变量
#nginx自定义变量:
server {listen 80;server_name var.test.org;root /data/web/html;index index.html;location /var {default_type text/html;set $test lee;echo $test;}
} [root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# curl -b "key1=lee,key2=timinglee" -u lee:lee var.timinglee.org/var?name=lee&&id=6666 七、Nginx Rewrite 相关功能
7.1 if 指令
[root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl var.test.org/test2/index.html
/data/web/html/test2/index.html is not exist
[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.test.org/test2/index.html
test2 server {listen 80;server_name var.test.org;root /data/web/html;index index.html;location /var {default_type text/html;set $test lee;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;echo $test;}location /test2 {if ( !-e $request_filename ){echo "$request_filename is not exist";#return 409; #会刷新掉echo的内容}}
} 7.2 break 指令
[root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl var.test.org/break
lee
6666
[root@nginx-node1 conf.d]# cat vars.conf
server {listen 80;server_name var.test.org;root /data/web/html;index index.html;location /var {default_type text/html;set $test lee;...location /break {default_type text/html;set $name lee;echo $name;#if ( $http_user_agent = "curl/7.76.1" ){# break;#}set $id 6666;echo $id;}
}[root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl var.test.org/break
lee
[root@nginx-node1 conf.d]# cat vars.conf
server {listen 80;server_name var.test.org;root /data/web/html;index index.html;location /var {default_type text/html;set $test lee;...location /break {default_type text/html;set $name lee;echo $name;if ( $http_user_agent = "curl/7.76.1" ){break;}set $id 6666;echo $id;}
}[root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl -A "firefox" var.test.org/break
lee
6666 7.3 return 指令
[root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl -I var.test.org/return
HTTP/1.1 301 Moved Permanently
...[root@nginx-node1 conf.d]# mkdir -p /data/web/html/return
[root@nginx-node1 conf.d]# curl -I var.test.org/return
HTTP/1.1 200 OK
... server {listen 80;server_name var.test.org;root /data/web/html;index index.html;location /var {default_type text/html;set $test lee;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;echo $test;}location /test2 {if ( !-e $request_filename ){echo "$request_filename is not exist";#return 409; #会刷新掉echo的内容}}location /break {default_type text/html;set $name lee;echo $name;if ( $http_user_agent = "curl/7.76.1" ){break;}set $id 6666;echo $id;}location /return {default_type text/html;if ( !-e $request_filename){return 301 http://www.baidu.com;}echo "$request_filename is exist";}
} 7.4 rewrite 指令
[root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl var.test.org
server {listen 80;server_name var.test.org;root /data/web/html;index index.html;location / {root /data/web/var;index index.html;rewrite / http://www.timinglee.com permanent;#rewrite / http://www.timinglee.com redirect;}
}[root@nginx-node1 conf.d]# vim vars.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl -I var.test.org
HTTP/1.1 302 Moved Temporarily
...
server {listen 80;server_name var.test.org;root /data/web/html;index index.html;location / {root /data/web/var;index index.html;#rewrite / http://www.timinglee.com permanent;rewrite / http://www.timinglee.com redirect;}
} 7.5 break 和 last 区别案例
原始
[root@nginx-node1 conf.d]# mkdir -p /data/web/html/{test1,test2,break,last}
[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 vars.conf
[root@nginx-node1 conf.d]# nginx -s reload server {listen 80;server_name var.test.org;root /data/web/html;index index.html;location /break {rewrite ^/break/(.*) /test1/$1; #$1对/(.*)进行引用rewrite ^/test1/(.*) /test2/$1; #break转到test1,test1转到test2}location /last {rewrite ^/last/(.*) /test1/$1;rewrite ^/test1/(.*) /test2/$1;}location /test1 {default_type text/html;echo "test hahahahaha";}location /test2 {root /data/web/html;}
} 
break 和 last 后:
server {listen 80;server_name var.test.org;root /data/web/html;index index.html;location /break {root /data/web/html;rewrite ^/break/(.*) /test1/$1 break;#忽略底下的所以,访问/data/web/html下的rewrite ^/test1/(.*) /test2/$1;}location /last {root /data/web/html;rewrite ^/last/(.*) /test1/$1 last;rewrite ^/test1/(.*) /test2/$1;}location /test1 {default_type text/html;echo "test hahahahaha";}location /test2 {root /data/web/html;}
} 
7.6 rewrite案例: 自动跳转 https
[root@nginx-node1 ~]# cd /usr/local/nginx/
[root@nginx-node1 nginx]# mkdir certs
[root@nginx-node1 nginx]# cd
[root@nginx-node1 ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/nginx/certs/test.org.key -x509 -days 365 -out /usr/local/nginx/certs/test.org.crt[root@nginx-node1 ~]# cd /usr/local/nginx/certs/
[root@nginx-node1 certs]# ls[root@nginx-node1 certs]# cd /usr/local/nginx/conf.d/
[root@nginx-node1 certs]# vim vhosts.conf #里面的内容部分在主配置文件里面有:/usr/local/nginx/conf/nginx.conf
[root@nginx-node1 certs]# nginx -s reload[root@nginx-node1 certs]# vim vhosts.conf
[root@nginx-node1 certs]# nginx -s reload 7.7 rewrite 案例: 判断文件是否存在
server {listen 80;listen 443 ssl;server_name www.test.org;root /data/web/html;index index.html;ssl_certificate /usr/local/nginx/certs/test.org.crt;ssl_certificate_key /usr/local/nginx/certs/test.org.crt;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;}}
} 八、Nginx 防盗链
[root@nginx-node1 ~]# vim vhosts.conf
[root@nginx-node1 ~]# mkdir -p /data/web/html/images #图片一放入/data/web/html/images/里,图片二放入/data/web/html/里
[root@nginx-node1 ~]# nginx -s reload#[root@web10 ~]# dnf install httpd -y
[root@web10 ~]# cd /var/www/html/
[root@web10 ~]# vim index.html
[root@web10 ~]# systemctl start httpd server {listen 80;listen 443 ssl;server_name www.test.org;root /data/web/html;index index.html;ssl_certificate /usr/local/nginx/certs/test.org.crt;ssl_certificate_key /usr/local/nginx/certs/test.org.crt;ssl_session_cache shared:SSL:1m;ssl_session_timeout 5m;location /images {valid_referers none blocked server_names *.test.org ~/.baidu/.;if ( $invalid_referer ){rewrite ^/ http://www.test.org/test2.png;}}
} #盗链网页
<html><head><meta http-equiv=Content-Type content="text/html;charset=utf-8"><title>盗链</title></head><body><img src="http://www.test.org/images/test1.png"><h1 style="color:red">欢迎大家</h1><p><a href=http://www.test.org>点击进入</a>恭喜发财</p></body></html> 九、实现 http 反向代理
正向代理:
例如:三台主机想访问国外的网站,但访问不了,就找一台能访问的主机,将外网可访问的信息缓存到中间的主机里,其他的主机通过网络连接中间主机,通过访问缓存实现访问外网的效果。
反向代理:
例如:三台主机想访问企业的网站,本应访问真实的服务器,但不让访问到真实的服务器,中间隔了一个代理服务器,所有的DNS指向代理服务器,代理根据访问请求进行分析,最终定位到某一个真实的realserver上。
9.1 Nginx 反向代理功能
中间有一个代理服务器,通过代理服务器访问到正确的服务器
[root@web10 ~]# dnf install httpd -y
[root@web10 ~]# systemctl enable --now httpd
[root@web10 ~]# echo 172.25.254.10 > /var/www/html/index.html #定义默认发布页[root@web20 ~]# dnf install httpd -y
[root@web20 ~]# systemctl enable --now httpd
[root@web20 ~]# echo 172.25.254.20 > /var/www/html/index.html
测试:
[root@nginx-node1 ~]# curl 172.25.254.10
172.25.254.10
[root@nginx-node1 ~]# curl 172.25.254.20
172.25.254.20[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# cat vhosts.conf
server {listen 80;server_name www.test.org;location / {proxy_pass http://172.25.254.10:80;}
}
# 此时访问curl www.test.org ===> 172.25.254.10[root@web20 ~]# vim /etc/httpd/conf/httpd.conf
[root@web20 ~]# systemctl restart httpd
Listen 8080
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# cat vhosts.conf
server {listen 80;server_name www.test.org;location / {#proxy_pass http://172.25.254.10:80;proxy_pass http://172.25.254.20:8080;}
}
# 此时访问curl www.test.org ===> 172.25.254.10[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# cat vhosts.conf
server {listen 80;server_name www.test.org;location / {proxy_pass http://172.25.254.10:80;}location /static {proxy_pass http://172.25.254.20:8080;}
}
# 此时访问curl www.test.org/static/ ===> 404错误
[root@web20 ~]# mkdir -p /var/www/html/static
[root@web20 ~]# echo static 172.25.254.20 > /var/www/html/static/index.html
# 此时访问curl www.test.org/static/ ===> static 172.25.254.20 server {listen 80;server_name www.test.org;location / {proxy_pass http://172.25.254.10:80;}
} 动静分离:
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# cat vhosts.conf
server {listen 80;server_name www.test.org;location ~ \.php$ {proxy_pass http://172.25.254.10:80;}location /static {proxy_pass http://172.25.254.20:8080;}
}[root@web10 ~]# dnf install php -y
[root@web10 ~]# systemctl restart httpd
[root@web10 ~]# vim /var/www/html/index.php
[root@web10 ~]# cat /var/www/html/index.php
<?phpphpinfo();
?>#浏览器访问www.test.org/index.php ===> php界面(10的)
#浏览器访问www.test.org/static/ ===> static 172.25.254.20 9.2 http 反向代理负载均衡
[root@web10 html]# vim /etc/hosts
172.25.254.10 www.test.org
[root@web10 html]# ab -n1000 -c100 http://www.test.org/static/index.html
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking www.test.org (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requestsServer Software: Apache/2.4.53
Server Hostname: www.test.org
Server Port: 80Document Path: /static/index.html
Document Length: 196 bytesConcurrency Level: 100
Time taken for tests: 0.070 seconds
Complete requests: 1000
Failed requests: 0
Non-2xx responses: 1000
Total transferred: 394000 bytes
HTML transferred: 196000 bytes
Requests per second: 14348.64 [#/sec] (mean)
Time per request: 6.969 [ms] (mean)
Time per request: 0.070 [ms] (mean, across all concurrent requests)
Transfer rate: 5520.86 [Kbytes/sec] receivedConnection Times (ms)min mean[+/-sd] median max
Connect: 0 1 1.0 0 3
Processing: 1 6 2.5 6 19
Waiting: 0 5 2.1 5 14
Total: 2 7 2.2 6 19
WARNING: The median and mean for the initial connection time are not within a normal deviationThese results are probably not that reliable.Percentage of the requests served within a certain time (ms)50% 666% 775% 780% 890% 995% 1098% 1499% 14100% 19 (longest request)[root@nginx-node1 conf.d]# vim /usr/local/nginx/conf/nginx.conf #把之前的都注释掉#gzip on;#gzip_comp_level 5;#gzip_min_length 1k;#gzip_http_version 1.1;#gzip_vary on;#gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/gif image/png;#在下方写入以下内容:
proxy_cache_path /apps/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m inactive=120s max_size=1g;
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# cat vhosts.conf
server {listen 80;server_name www.test.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@web10 html]# ab -n1000 -c100 http://www.test.org/static/index.html [root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# cat vhosts.conf
upstream webserver {ip_hash; #curl www.test.org ===> 10#hash $request_uri consistent; #curl www.test.org ===> 20;curl www.test.org/static/ ===> 172.25.254.10 static#hash $cookie_lee #curl -b "lee=1" www.test.org ===> 10;curl -b "lee=2" www.test.org ===> 20;curl -b "lee=3" www.test.org ===> 10;curl -b "lee=4" www.test.org ===> 10;#least_conn;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.test.org;location / {proxy_pass http://webserver;}
}[root@web10 html]# vim /etc/hosts
172.25.254.100 www.test.org
[root@web20 html]# vim /etc/hosts
172.25.254.100 www.test.org[root@web10 html]# mkdir -p /var/www/html/static
[root@web10 html]# echo 172.25.254.10 static > /var/www/html/static/index.html
十、实现 Nginx 四层负载均衡
[root@web10 ~]# dnf install bind -y
[root@web20 ~]# dnf install bind -y[root@web10 html]# vim /etc/named.conf
// listen-on port 53 { 127.0.0.1; };
// listen-on-v6 port 53 { ::1; };
// allow-query { localhost; };
dnssec-validation no[root@web10 html]# vim /etc/named.rfc1912.zones
#新增内容
zone "test.org" IN { type master;file "test.org.zone";allow-update { none; };
}; [root@web10 html]# cd /var/named/
[root@web10 named]# cp named.localhost test.org.zone -p
[root@web10 named]# vim test.org.zone
[root@web10 named]# cat test.org.zone
$TTL 1D
@ IN SOA ns.test.org. root.test.org. (0 ; serial1D ; refresh1H ; retry1W ; expire3H ) ; minimumNS ns.test.org.
ns A 172.25.254.10
www A 172.25.254.10
[root@web10 named]# systemctl start named
[root@web10 named]# dig www.test.org @172.25.254.10[root@web10 named]# scp -p /etc/named.{conf,rfc1912.zones} root@172.25.254.20:/etc/
[root@web20 ~]# ll /etc/named.conf
-rw-r----- 1 root named 1727 Aug 18 23:36 /etc/named.conf
[root@web20 ~]# ll /etc/named.rfc1912.zones
-rw-r----- 1 root named 1116 Aug 18 23:37 /etc/named.rfc1912.zones[root@web10 named]# scp -p /var/named/test.org.zone root@172.25.254.20:/var/named/test.org.zone
[root@web20 ~]# vim /var/named/test.org.zone
[root@web20 ~]# cat /var/named/test.org.zone
$TTL 1D
@ IN SOA ns.test.org. root.test.org. (0 ; serial1D ; refresh1H ; retry1W ; expire3H ) ; minimumNS ns.test.org.
ns A 172.25.254.20
www A 172.25.254.20[root@web20 ~]# systemctl start named
[root@web20 ~]# cd /var/named/
[root@web20 named]# ll
total 20
drwxrwx--- 2 named named 23 Aug 18 23:46 data
drwxrwx--- 2 named named 60 Aug 18 23:47 dynamic
-rw-r----- 1 root named 2253 Feb 27 2023 named.ca
-rw-r----- 1 root named 152 Feb 27 2023 named.empty
-rw-r----- 1 root named 152 Feb 27 2023 named.localhost
-rw-r----- 1 root named 168 Feb 27 2023 named.loopback
drwxrwx--- 2 named named 6 Feb 27 2023 slaves
-rw-r----- 1 root root 190 Aug 18 23:46 test.org.zone
[root@web20 named]# chgrp named test.org.zone
[root@web20 named]# ll
total 20
drwxrwx--- 2 named named 23 Aug 18 23:46 data
drwxrwx--- 2 named named 60 Aug 18 23:47 dynamic
-rw-r----- 1 root named 2253 Feb 27 2023 named.ca
-rw-r----- 1 root named 152 Feb 27 2023 named.empty
-rw-r----- 1 root named 152 Feb 27 2023 named.localhost
-rw-r----- 1 root named 168 Feb 27 2023 named.loopback
drwxrwx--- 2 named named 6 Feb 27 2023 slaves
-rw-r----- 1 root named 190 Aug 18 23:46 test.org.zone
[root@web20 named]# systemctl restart named
[root@web20 named]# dig www.test.org @172.25.254.20 [root@web10 named]# dnf install mariadb-server -y
[root@web20 named]# dnf install mariadb-server -y[root@nginx-node1 conf.d]# cat vhosts.conf
upstream webserver {#ip_hash;#hash $request_uri consistent;hash $cookie_lee#least_conn;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.test.org;location / {proxy_pass http://webserver;}
}[root@nginx-node1 conf.d]# cat .conf
stream {upstream dns { #定义stream相关的服务;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 { #定义serverlisten 53 udp reuseport; #监听IP:PORTproxy_timeout 20s; #转发超时时间proxy_pass dns; #转发到具体服务器组}
}[root@nginx-node1 conf.d]# vim /usr/local/nginx/conf/nginx.conf
include "/usr/local/nginx/tcpconf.d/*.conf";
[root@nginx-node1 conf.d]# mkdir -p /usr/local/nginx/tcpconf.d
[root@nginx-node1 conf.d]# mv dns.conf /usr/local/nginx/tcpconf.d/
[root@nginx-node1 conf.d]# nginx -s reload#此后轮询调度[root@nginx-node1 conf.d]# dig www.test.org @172.25.254.100 数据库:
[root@web10 named]# dnf install mariadb-server -y
[root@web10 named]# vim /etc/my.cnf.d/mariadb-server.cnf
#在[mysqld]下面增加一行server-id=10
[root@web10 named]# systemctl start mariadb[root@web20 named]# dnf install mariadb-server -y
[root@web20 named]# vim /etc/my.cnf.d/mariadb-server.cnf
#在[mysqld]下面增加一行server-id=20
[root@web20 named]# systemctl start mariadb[root@nginx-node1 conf.d]# cat .conf
stream {upstream dns { #定义stream相关的服务;server 172.25.254.10:53 fail_timeout=15s max_fails=3;server 172.25.254.20:53 fail_timeout=15s max_fails=3;}upstream mysqlserver { #定义serverlisten 53 udp reuseport; #监听IP:PORTproxy_timeout 20s; #转发超时时间proxy_pass dns; #转发到具体服务器组}
} 十一、实现 FastCGI
11.1 环境编译与准备
[root@nginx-node1 nginx-1.26.1]# rm -rf /usr/local/nginx
[root@nginx-node1 nginx-1.26.1]# cd
[root@nginx-node1 ~]# tar zxf memc-nginx-module-0.20.tar.gz
[root@nginx-node1 ~]# tar zxf srcache-nginx-module-0.33.tar.gz[root@nginx-node1 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_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-node1 nginx-1.26.1]# make[root@nginx-node1 nginx-1.26.1]# nginx
-bash: nginx: command not found
[root@nginx-node1 nginx-1.26.1]#
[root@nginx-node1 nginx-1.26.1]# cd /usr/local/
[root@nginx-node1 local]# ls
bin etc games include lib lib64 libexec sbin share src
[root@nginx-node1 local]# cd -
/root/nginx-1.26.1
[root@nginx-node1 nginx-1.26.1]# ls
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README
[root@nginx-node1 nginx-1.26.1]# cd objs/
[root@nginx-node1 objs]# ls
addon Makefile nginx.8 ngx_auto_headers.h ngx_modules.
autoconf.err nginx ngx_auto_config.h ngx_modules.c src
[root@nginx-node1 objs]# cd
[root@nginx-node1 ~]# cd nginx-1.24.0/
[root@nginx-node1 nginx-1.24.0]# ls
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README
[root@nginx-node1 nginx-1.24.0]# make install[root@nginx-node1 nginx-1.24.0]# cd /usr/local/nginx/
[root@nginx-node1 nginx]# ls
conf html logs sbin
[root@nginx-node1 nginx]# cd sbin/
[root@nginx-node1 sbin]# ls
nginx
[root@nginx-node1 sbin]# nginx
[root@nginx-node1 sbin]#
[root@nginx-node1 sbin]# cd[root@nginx-node1 ~]# tar zxf php-8.3.9.tar.gz
[root@nginx-node1 ~]# ls[root@nginx-node1 ~]# cd php-8.3.9/
[root@nginx-node1 php-8.3.9]# ls
appveyor EXTENSIONS scripts
benchmark LICENSE SECURITY.md
build main tests
buildconf NEWS travis
buildconf.bat pear TSRM
CODING_STANDARDS.md php.ini-development UPGRADING
configure php.ini-production UPGRADING.INTERNALS
configure.ac README.md win32
CONTRIBUTING.md README.REDIST.BINS Zend
docs run-tests.php
ext sapi
[root@nginx-node1 php-8.3.9]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel
[root@nginx-node1 php-8.3.9]# wget https://mirrors.aliyun.com/rockylinux/9.4/devel/x86_64/kickstart/Packages/o/oniguruma-devel-6.9.6-1.el9.5.x86_64.rpm
[root@nginx-node1 php-8.3.9]# dnf install -y oniguruma-devel-6.9.6-1.el9.5.x86_64.rpm[root@nginx-node1 php-8.3.9]# ./configure --prefix=/usr/local/php --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@nginx-node1 php-8.3.9]# make && make install [root@nginx-node1 php-8.3.9]# cd /usr/local/php/etc/
[root@nginx-node1 etc]# ls
php-fpm.conf.default php-fpm.d[root@nginx-node1 etc]# cp -p php-fpm.conf.default php-fpm.conf
[root@nginx-node1 etc]# ls
php-fpm.conf php-fpm.conf.default php-fpm.d
[root@nginx-node1 etc]# vim php-fpm.conf
#去掉注释
pid = run/php-fpm.pid #指定pid文件存放位置[root@nginx-node1 etc]# cd php-fpm.d/
[root@nginx-node1 php-fpm.d]# ls
www.conf.default
[root@nginx-node1 php-fpm.d]# cp -p www.conf.default www.conf[root@nginx-node1 etc]# cd /root/php-8.3.9/
[root@nginx-node1 php-8.3.9]# ls
[root@nginx-node1 php-8.3.9]# cp php.ini-production /usr/local/php/etc/php.ini
[root@nginx-node1 php-8.3.9]# vim /usr/local/php/etc/php.ini
date.timezone = Asia/Shanghai #修改时区[root@nginx-node1 php-8.3.9]# cd sapi/
[root@nginx-node1 sapi]# cd fpm/
[root@nginx-node1 fpm]# cp php-fpm.service /lib/systemd/system/
[root@nginx-node1 fpm]# vim /lib/systemd/system/php-fpm.service
#ProtectSystem=full #注释该内容[root@nginx-node1 fpm]# systemctl start php-fpm.service
[root@nginx-node1 fpm]# systemctl daemon-reload
[root@nginx-node1 fpm]# systemctl start php-fpm
[root@nginx-node1 fpm]# netstat -antlupe | grep php
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 0 126634 156497/php-fpm: mas [root@nginx-node1 fpm]# mkdir -p /data/web/php
[root@nginx-node1 fpm]# cd /usr/local/php/bin/
[root@nginx-node1 bin]# ls
phar phar.phar php php-cgi php-config phpdbg phpize
[root@nginx-node1 bin]# vim ~/.bash_profile
[root@nginx-node1 bin]# cat ~/.bash_profile
# .bash_profile# Get the aliases and functions
if [ -f ~/.bashrc ]; then. ~/.bashrc
fi# User specific environment and startup programs
export PATH=$PATH:/usr/local/nginx/sbin:/usr/local/php/bin:/usr/local/php/sbin
[root@nginx-node1 bin]# source ~/.bash_profile
[root@nginx-node1 bin]# php
php php-cgi php-config phpdbg php-fpm phpize
[root@nginx-node1 bin]# vim /data/web/php/index.php
[root@nginx-node1 bin]# cat /data/web/php/index.php
<?phpphpinfo();
?>[root@nginx-node1 bin]# cd /usr/local/
[root@nginx-node1 local]# cd nginx/
[root@nginx-node1 nginx]# cd conf/
[root@nginx-node1 conf]# ls
fastcgi.conf koi-win scgi_params
fastcgi.conf.default mime.types scgi_params.default
fastcgi_params mime.types.default uwsgi_params
fastcgi_params.default nginx.conf uwsgi_params.default
koi-utf nginx.conf.default win-utf
[root@nginx-node1 conf]# vim fastcgi.conf
[root@nginx-node1 conf]# cd ..
[root@nginx-node1 nginx]# mkdir conf.d
[root@nginx-node1 nginx]# vim conf/nginx.confinclude "/usr/local/nginx/conf.d/*.conf";[root@nginx-node1 nginx]# cd conf.d/
[root@nginx-node1 conf.d]# pwd
/usr/local/nginx/conf.d
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# cat vhosts.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;location ~ \.php$ {root /data/web/php;fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;include fastcgi.conf;}
}
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]#
[root@nginx-node1 conf.d]# vim /usr/local/php/etc/php-fpm.d/www.conf
[root@nginx-node1 conf.d]# systemctl restart php-fpm.service
[root@nginx-node1 conf.d]# netstat -antlupe | grep php
tcp 0 0 0.0.0.0:9000 0.0.0.0:* LISTEN 0 128283 156715/php-fpm: mas
[root@nginx-node1 conf.d]#
[root@nginx-node1 conf.d]# cd /usr/local/nginx/conf.d/
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# cat vhosts.conf
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;location ~ \.php$ {root /data/web/php;fastcgi_pass 172.25.254.100:9000;fastcgi_index index.php;include fastcgi.conf;}
}
[root@nginx-node1 conf.d]# nginx -s reload 

十二、php的动态扩展模块
12.1 安装 memcache 模块
配置 php 加载 memcache 模块
<---
[root@nginx-node1 ~]# cd /usr/local/php/
[root@nginx-node1 php]# ls
bin etc include lib php sbin var
[root@nginx-node1 php]# cd etc/
[root@nginx-node1 etc]# ls
php-fpm.conf php-fpm.conf.default php-fpm.d php.ini
[root@nginx-node1 etc]# cp php.ini ../lib/
[root@nginx-node1 etc]# cd ../lib/
[root@nginx-node1 lib]# ls
php php.ini
--->#以上操作是因为以下没有指定配置路径,所以需要移动位置:
#解压源码并安装
[root@Nginx ~]# ./configure \
...
--with-config-file-path=/usr/local/php/etc \ #指定配置路径
...
[root@nginx-node1 ~]# ls
anaconda-ks.cfg nginx-1.26.1
echo-nginx-module-0.63 nginx-1.26.1.tar.gz
echo-nginx-module-0.63.tar.gz php-8.3.9
memcache-8.2.tgz php-8.3.9.tar.gz
memc-nginx-module-0.20 srcache-nginx-module-0.33
memc-nginx-module-0.20.tar.gz srcache-nginx-module-0.33.tar.gz
nginx-1.24.0 testfile
nginx-1.24.0.tar.gz testfile.1
[root@nginx-node1 ~]# tar zxf memcache-8.2.tgz
[root@nginx-node1 ~]# ls
anaconda-ks.cfg nginx-1.26.1
echo-nginx-module-0.63 nginx-1.26.1.tar.gz
echo-nginx-module-0.63.tar.gz package.xml
memcache-8.2 php-8.3.9
memcache-8.2.tgz php-8.3.9.tar.gz
memc-nginx-module-0.20 srcache-nginx-module-0.33
memc-nginx-module-0.20.tar.gz srcache-nginx-module-0.33.tar.gz
nginx-1.24.0 testfile
nginx-1.24.0.tar.gz testfile.1
[root@nginx-node1 ~]# cd memcache-8.2/
[root@nginx-node1 memcache-8.2]# ls
config9.m4 config.w32 docker example.php memcache.php src
config.m4 CREDITS Dockerfile LICENSE README tests
[root@nginx-node1 memcache-8.2]# phpize
Configuring for:
PHP Api Version: 20230831
Zend Module Api No: 20230831
Zend Extension Api No: 420230831
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.[root@nginx-node1 memcache-8.2]# dnf install autoconf -y[root@nginx-node1 memcache-8.2]# phpize
Configuring for:
PHP Api Version: 20230831
Zend Module Api No: 20230831
Zend Extension Api No: 420230831
[root@nginx-node1 memcache-8.2]# ./configure && make && make install[root@nginx-node1 memcache-8.2]# ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20230831/
memcache.so opcache.so
[root@nginx-node1 memcache-8.2]#
[root@nginx-node1 memcache-8.2]# vim /usr/local/php/etc/php.ini
[root@nginx-node1 memcache-8.2]# systemctl restart php-fpm.service
[root@nginx-node1 memcache-8.2]# dnf install memcached -y[root@nginx-node1 memcache-8.2]# vim /etc/sysconfig/memcached
[root@nginx-node1 memcache-8.2]# systemctl start memcached.service
[root@nginx-node1 memcache-8.2]# netstat -antlupe | grep memcache
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 991 140132 163074/memcached
tcp6 0 0 ::1:11211 :::* LISTEN 991 140133 163074/memcached
[root@nginx-node1 memcache-8.2]# php -m
[root@nginx-node1 memcache-8.2]# systemctl restart php-fpm.service
[root@nginx-node1 memcache-8.2]# systemctl restart memcached.service
[root@nginx-node1 memcache-8.2]# php -m[root@nginx-node1 memcache-8.2]# cp example.php memcache.php /data/web/php/
[root@nginx-node1 memcache-8.2]# cd /data/web/php/
[root@nginx-node1 php]# ls
example.php index.php memcache.php
[root@nginx-node1 php]# vim memcache.php
[root@nginx-node1 php]# systemctl restart php-fpm.service
[root@nginx-node1 php]# systemctl restart memcached.service #测试对比:
[root@nginx-node1 php]# ab -n1000 -c10 http://www.test.org/index.php
[root@nginx-node1 php]# ab -n1000 -c10 http://www.test.org/index.php
#Failed requests:变少是正常的






刷新上一个页面

上图重启后恢复:[root@nginx-node1 php]# systemctl restart memcached.service
前后对比


12.2 php高速缓存
[root@nginx-node1 conf.d]# cd /usr/local/nginx/conf.d/
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# cat vhosts.conf
upstream memcache {server 127.0.0.1:11211;keepalived 512;
}
server {listen 80;server_name www.test.org;root /data/web/html;index index.html;location /memc {internal;memc_connect_timeout 100ms;memc_send_timeout 100ms;memc_read_timeout 100ms;set $memc_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 127.0.0.1:9000;fastcgi_index index.php;include fastcgi.conf;}
}
[root@nginx-node1 ~]# cd nginx-1.26.1/
[root@nginx-node1 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
[root@nginx-node1 nginx-1.26.1]# make && make install
[root@nginx-node1 conf.d]# nginx -V
nginx version: nginx/1.26.1
built by gcc 11.3.1 20221121 (Red Hat 11.3.1-4) (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 --add-module=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module-0.33[root@nginx-node1 php]# cd /usr/local/nginx/conf.d/
[root@nginx-node1 conf.d]# ls
vhosts.conf
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -t
[root@nginx-node1 conf.d]# nginx -s reload#前后对比测试:
[root@nginx-node1 ~]# ab -n500 -c10 http://www.test.org/index.php
[root@nginx-node1 ~]# ab -n500 -c10 http://www.test.org/index.php


十三、编译安装 openresty
#查看是否有,没有则做:[root@Nginx ~]# dnf -y install gcc pcre-devel openssl-devel perl[root@Nginx ~]# useradd -r -s /sbin/nologin nginx
[root@Nginx openresty-1.17.8.2]#./configure \
--prefix=/usr/local/openresty \
--user=nginx --group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with_http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module
--with-pcre --with-stream \
--with-stream_ssl_module \
--with-stream_realip_module[root@Nginx openresty-1.17.8.2]# gmake -2 && gmake install
[ root@nginx-node1 bin]# vim ~/.bash_profile
[ root@nginx-node1 bin]# pwd
/usr/local/openresty/bin
[ root@nginx-node1 bin]# vim ~/.bash_profile
[ root@nginx-node1 bin]# source ~/.bash_profile
# .bash_ profile
# Get the aliases and functions
if [-f ~/.bashrc ]; then. ~/.bashrc
fi
# User specific environment and startup programs
export PATH=$PATH:/usr/local/nginx/sbin:/usr/local/php/bin:/usr/local/php/sbin:/usr/local/openresty/bin
[ root@nginx-nodel bin]# openresty
[ root@nginx-nodel bin]# netstat -antlulpe| grep 80

