Apache 的三种模型
Prefork 模型
1、预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024
2、每个子进程有一个独立的线程响应用户请求
3、相对比较占用内存,但是比较稳定,可以设置最大和最小进程数
4、是最古老的一种模式也是最稳定的模式,适用于访问量不是很大的场景
优点:稳定
缺点:每个用户请求需要对应开启一个进程,占用资源较多,并发性差,不适用于高并发场景
worker 模型
1、一种多进程和多线程混合的模型
2、有一个控制进程,启动多个子进程
3、每个子进程里面包含固定的线程
4、使用线程来处理请求
5、当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,
6、由于其使用了线程处理请求,因此可以承受更高的并发
优点:相比prefork占用的内存较少,可以同时处理更多的请求
缺点:使用keepalive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用(该问题在prefork模式下,同样会发生)
event 模型
事件驱动模型(epoll)
每个进程响应多个请求,在现在版本里的已经是稳定可用的模式
它和worker模式很像,最大的区别在于,它解决了keepalive场景下长期被占用的线程的资源浪费问题(某些线程因为被keepalive,空挂在那里等待,中间几乎没有请求过来,甚至等到超时)
1、event MPM中,会有一个专门的线程来管理这些keepalive类型的线程
2、当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力
优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keepalive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放
缺点:没有线程安全控制
I/O 流
服务端 I/O 流程
I/O在计算机中指 Input/Output,IOPS(Input/Output Per Second) 即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一。IOPS是指单位时间内系统能处理的/O请求数量,一般以每秒处理的I/O请求数量为单位,I/O请求通常为读或写数据操作请求。
一次完整的I/O:用户空间的进程数据与内核空间的内核数据进行的一次完整的报文交换
但是由于内核空间与用户空间是严格隔离的,所以其数据交换过程中不能由用户空间的进程直接调用内核空间的内存数据,而是需要经历一次从内核空间中的内存数据copy到用户空间的进程内存当中,所以简单说I/O就是把数据从内核空间中的内存数据复制到用户空间中进程的内存当中。
服务器的I/O又分以下两种:
1、磁盘I/O
2、网络I/O:一切皆文件,本质是对socket文件的读写
不论磁盘还是网络 I/O,每次 I/O 都要经历两个阶段:
第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长
第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短
磁盘 I/O
磁盘 I/O 是进程向内核发起系统调用,请求磁盘上的某个资原(比如是html文件或者图片),然后内核通过相应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存,如果是比较大的数据则需要等待时间。
机械磁盘的寻道时间、旋转延迟和数据传输时间:
寻道时间:是指磁头移动到正确的磁道上所花费的时间,寻道时间越短则 I/O 处理就越快,目前磁盘的寻道时间一般在3-15毫秒左右
旋转延迟:是指将磁盘片旋转到数据所在的扇区到磁头下面所花费的时间,旋转延迟取决于磁盘的转速,通常使用磁盘旋转一周所需要时间的1/2之一表示
数据传输时间:指的是读取到数据后传输数据的时间,主要取决于传输速率,这个值等于数据大小除以传输速率,目前的磁盘接口每秒的传输速度可以达到600MB,因此可以忽略不计。
网络 I/O
网络I/O处理过程:
1、获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求
2、构建响应,当服务器接收完请求,并在用户空间处理客户瑞的请求,直到构建响应完成
3、返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端
I/O 模型
I/O 模型的相关概念
同步/异步:关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。
1、同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成
2、异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态
阻塞和非阻塞:关注调用者在等待结果返回之前所处的状态
1、阻塞:blocking,指 I/O 操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情
2、非阻塞:nonblocking,指 I/O 操作被调用后立即返回给用户一个状态值,而无需等到 I/O 操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情
网络 I/O 模型
阻塞型 I/O
阻塞 I/O 模型是最简单的 I/O 模型,用户线程在内核进行I/O操作时被阻塞
用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成read操作
用户需要等待read将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线程是被阻塞的,这导致用户在发起I/O请求时,不能做任何事情,对CPU的资原利用率不够
优点:程序简单,在阻塞等待数据期间进程线程挂起,基本不会占用CPU资源
缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销较大
同步阻塞:程序向内核发送I/O请求后一直等待内核响应,如果内核处理请求的I/O操作不能立刻返回,则进程将一直等待并不再接受新的请求,并由进程轮询查看I/O是否完成,完成后进程将I/O结果返回给Client,在I/O没有返回期间进程不能接受其他客户的请求,而且由进程自己去查看I/O是否完成,这种方式简单,但是比较慢,用的比较少。
非阻塞型 I/O
在设置连接为非阻塞时,当应用进程系统调用recvfrom没有数据返回时,内核会立即返回一个EWOULDBLOCK错误,而不会一直阻塞到数据准备好。如图在第四次调用时有一个数据报准
备好了,所以这时数据会被复制到应用进程缓冲区,于是recvfrom成功返回数据当一个应用进程这样循环调用recvfrom时,称之为轮询polling。这么做往往会耗费大量CPU时间,实际使用很少
用户线程发起I/O请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起I/O请求,直到数据到达后,才真正读取到数据。即"轮询机制存在两个问题:如果有大量文件描述符都要等,那么就要一个一个的read。这会带来大量的Context Switch(read是系统调用,每调用一次就得在用户和内核切换一次)。轮询的时间不好把握。这里是要猜多久之后数据才能到。等待时间设的大长,
程序响应延迟就过大;设的大短,就会造成过于频繁的重试,干耗CPU,是比较浪费CPU的方式,一
般很少直接使用这种模型,而是在其他I/O模型中使用非阻塞I/O这一特性。
非阻塞:程序向内核发送请I/O求后一直等待内核响应,如果内核处理请求的I/O操作不能立即返回I/O结果,进程将不再等待,而且继续处理其他请求,但是仍然需要进程隔一段时间就要查看内核I/O是否完成。
多路复用 I/O 型
多路复用I/O是指一个线程可以同时(实际是交替实现,即并发完成)监控和处理多个文件描述符对应各自的I/O,即复用同一个线程
一个线程之所以能实现同时处理多个I/O,是因为这个线程调用了内核中的SELECT,POLL或EPOLL等系统调用,从而实现多路复用I/O
l/O multiplexing 主要包括 select,poll,epoll 三种系统调用,select/poll/epoll 的好处就在于单个process就可以同时处理多个网络连接的I/O。
它的基本原理就是select/poll/epolli这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。
当用户进程调用了select,那么整个进程会被block,而同时,kernel会"监视"所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。
优点:
可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述
符一个线程),这样可以大大节省系统资源
缺点:
当连接数较少时效率相比多线程+阻塞I/O模型效率较低,可能延迟更大,因为单个连接处理
需要2次系统调用,占用时间会有增加
多路复用I/O 适用如下场合:
1、当客户端处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用
2、当一个客户端同时处理多个套接字时,此情况可能但很少出现
3、当一个服务器既要处理监听套接字,又要处理已连接套接字,一般也要用到I/O复用
4、当一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用
5、当一个服务器要处理多个服务或多个协议,一般要使用/O复用
信号驱动式 I/O 模型
进程不用等待,也不用去轮询。而是让内核在数据就绪时,发送信号通知进程。
在信号驱动式/O模型中,应用程序使用套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞;当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据。
通过系统调用sigaction,并注册一个信号处理的回调函数,该调用会立即返回,然后主程序可以继续向下执行,当有I/O操作准备就绪,即内核数据就绪时,内核会为该进程产生一个SIGIO信号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用recvfrom获取数据,将用户进程所需要的数据从内核空间拷贝到用户空间
此模型的优势在于等待数据报到达期间进程不被阻塞。用户主程序可以继续执行,只要等待来自信号处理函数的通知。
优点:
线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此可以提高资源的利用率
缺点:
信号I/O在大量I/O操作时可能会因为信号队列溢出导致没法通知
异步阻塞:程序进程向内核发送I/O调用后,不用等待内核响应,可以继续接受其他请求,内核收到进程请求后,如果内核调用的IO不能立即返回,内核会继续处理其他事物,直到IO完成后将结果通知给内核,内核再将IO完成的结果返回给进程。
异步 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 能够充分利用 DMA 特性,让 I/O 操作与计算重叠
缺点:
要实现真正的异步 I/O,操作系统需要做大量的工作。目前 Windows 下通过 IOCP 实现了真正的异步 I/O;在 Linux 系统下,Linux 2.6才引入,目前 AIO 并不完善,因此在 Linux 下实现高并发网络编程时以 IO 复用模型模式+多线程任务的架构基本可以满足需求
异步非阻塞:程序进程向内核发送IO调用后,不用等待内核响应,可以继续接受其他请求,内核调用的IO如果不能立即返回,内核会继续处理其他事物,直到IO完成后将结果通知给内核,内核在将IO完成的结果返回给进程,期间进程可以接受新的请求,内核也可以处理新的事物,因此相互不影响,可以实现较大的同时并实现较高的IO复用,因此异步非阻塞使用最多的一种通信方式。
五种 I/O 对比
I/O 的实现:select、poll、epoll
Select:
POSIX所规定,目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理
缺点:
单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义:FD_SETSIZE,再重新编译内核实现,但是这样也会造成效率的降低;
单个进程可监视的fd数量被限制,默认是1024,修改此值需要重新编译内核;对socket是线性扫描,即采用轮询的方法,效率较低;
select 采取了内存拷贝方法来实现内核将 FD 消息通知给用户空间,这样一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大
poll:
本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态;
其没有最大连接数的限制,原因是它是基于链表来存储的大量的fd的数组,被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义;
poll特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll会再次报告该fd select是边缘触发,即只通知一次
epoll:
在Linux 2.6内核中提出的select和poll的增强版本,支持水平触发LT和边缘触发ET,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次使用“事件”的就绪通知方式;
通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知
优点:
1、没有最大并发连接的限制:能打开的FD的上限远大于1024(1G的内存能监听约10万个端口),具体查看 /proc/sys/fs/file-max,此值和系统内存大小相关
2、效率提升:非轮询的方式,不会随着FD数目的增加而效率下降;只有活跃可用的FD才会调用callback函数,即epoll最大的优点就在于它只管理“活跃”的连接,而跟连接总数无关
3、内存拷贝,利用mmap(Memory Mapping)加速与内核空间的消息传递;即epoll使用mmap减少复制开销
总结:
1、epoll只是一组API,比起select这种扫描全部的文件描述符,epoll只读取就绪的文件描述符,再加入基于事件的就绪通知机制,所以性能比较好
2、基于epoll的事件多路复用减少了进程间切换的次数,使得操作系统少做了相对于用户任务来说的无用功。
3、epoll比select等多路复用方式来说,减少了遍历循环及内存拷贝的工作量,因为活跃连接只占总并发连接的很小一部分。
零拷贝
传统的 Linux 系统的标准 I/O 接口(read、write)是基于数据拷贝的,也就是数据都是 copy_to_user 或者 copy_from_user,这样做的好处是,通过中间缓存的机制,减少磁盘 I/O 的操作,但是坏处也很明显,大量数据的拷贝,用户态和内核态的频繁切换,会消耗大量的 CPU 资源,严重影响数据传输的性能
MMAP 技术
mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。
普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问。
mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。
实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。
内存映射减少数据在用户空间和内核空间之间的拷贝操作,适合大量数据传输
SENDFILE 技术
1、第一步,通过DMA将磁盘上的数据拷贝到内核缓冲区里;
2、第二步,缓冲区描述符和数据长度传到socket缓冲区,这样网卡的SG-DMA控制器就可以直接将内核缓存中的数据拷贝到网卡的缓冲区里,此过程不需要将数据从操作系统内核缓冲区拷贝到socket缓冲区中,这样就减少了一次数据拷贝
Nginx
Nginx 的源码安装
环境的配置
[root@nginx ~]# yum install gcc pcre-devel zlib-devel openssl-devel -y
使用源码安装 Nginx,自由设定自己需要的功能( “ \ ” 换行符 )
[root@Nginx nginx-1.24.0]#./configure --prefix=/usr/local/nginx\
--user=nginx\ #指定nginx运行用户
--group=nginx\ #指定nginxi运行组
--with-http_ss1_module\ #支持https://
--with-http_v2_module\ #支持http版本2
--with-http_realip_module\ #支持ip透传
--wi th-http_stub_status_module\ #支持状态页面
--with-http_gzip_static_module\ #支持压缩
--with-pcre\ #支持正则
--with-stream\ #支持tcp反向代理
--with-stream_ss1_module\ #支持tcp的ss1加密
--with-stream_realip_module #支持tcp的透传ip
进行源码的编译和 Nginx 的安装
安装好的软件大小
减少软件包大小:
关闭 debug 调试功能
按照之前的步骤重新安装之后的软件大小
快捷启动 Nginx 服务:
编辑本地文件,重新加载文件内容
[rootanginx ~]vim ~/.bash_profile
[root nginx ~]source ~/.bash_profile ----重新加载配置文件
编辑文件内容
启动/关闭 Nginx 服务
Nginx 平滑更新和回滚
平滑更新 nginx 版本
1、下载新的软件包源码并进行解压
2、自定义源码的功能,按回车键生成源码文件
3、进行源码的编译,但无需安装
[root@nginx ~]# cd nginx-1.26.1/
[root@nginx nginx-1.26.1]# make
查看两个版本的 Nginx 软件包
备份旧版 Nginx
将新版 Nginx 覆盖旧版
[root@nginx ~]# \cp -f /root/nginx-1.26.1/objs/nginx /usr/local/nginx/sbin/
检测新版是否存在问题
[root@nginx ~]# nginx -t
平滑升级:
旧版本及其进程
使用命令行进行版本的升级
[root@nginx sbin]# kill -USR2 旧进程号
在新进程启动后,80端口由新版本进行监听
将旧进程号回收
[root@nginx sbin]# kill -WINCH 旧进程号
旧版本回滚:
将现版本进行备份,将以前备份的旧版本覆盖现在的版本
[root@nginx sbin]# cp nginx nginx.26
[root@nginx sbin]# mv nginx.24 nginx -f
进行回滚
[root@nginx sbin]# kill -HUP 旧进程号
此时监听80端口的还不是回滚的版本
回收回滚之前版本的进程,由回滚后的版本进行80端口的监听
Nginx 常用参数
[root@nginx system]# nginx -help
nginx version: nginx/1.26.1
Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]
[-e filename] [-c filename] [-g directives]
Options:
-?,-h : this help
-v : show version and exit #仅显示版本
-V : show version and configure options then exit #显示版本和编译参数
-t : test configuration and exit #测试配置文件是否存在异常
-T : test configuration, dump it and exit #测试并打印
-q : suppress non-error messages during configuration testing #静默模式
-s signal : send signal to a master process: stop, quit, reopen, reload #发送信号,reload信号 会生成新的worker,但master不会重新生成
-p prefix : set prefix path (default: /usr/local/nginx/) #指定 Nginx 目录
-e filename : set error log file (default: logs/error.log)
-c filename : set configuration file (default: conf/nginx.conf) #指定配置文件路径
-g directives : set global directives out of configuration file #设置全局指令,注意不能和配置文件同时配置,否则会冲突
Nginx 启动文件制作
1、创建并编辑启动文件
[root@nginx sbin]# vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
2、重新加载文件内容
[root@nginx sbin]# systemctl daemon-reload
3、设置开机自启动
[root@nginx system]# systemctl enable --now nginx.service
Nginx 全局配置优化
修改用户名
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf ----主配置文件
核心绑定
修改配置文件,设置四核心
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf ----主配置文件
效果演示:
将核心与进程绑定:
修改配置文件
worker_cpu_affinity 01 10; #如果是四核心绑定,则是0001 0010 0100 1000;以此类推
效果演示:
最大并发链接修改
修改系统默认的最大访问文件数量
[root@nginx ~]# vim /etc/security/limits.conf
......
ginx - nofile 100000 ----在末尾添加
修改 nginx 全局配置文件,使用 epoll 模型
查看用户最大访问文件数量
[root@nginx ~]# sudo -u nginx ulimit -n
Nginx 站点的建立
防止主配置文件过于杂乱,创建子配置文件用于站点的建立
自动读取子配置文件
文件读取自上而下,不能把子配置文件路径放末尾,不然不生效
在子配置文件内进行内容的添加
[root@nginx ~]# vim /usr/local/nginx/conf.d/host.conf
创建相应的目录和文件内容
效果演示:
root 和 alias 的区别
root:指定web的家目录,在定义location的时候,文件的绝对路径等于root+location
创建页面
效果演示
alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于location上下文,此指令使用较少
创建页面
效果演示:
location 详细使用规则
1、在一个servert中location配置段可存在多个,用于实现从 URI 到文件系统的路径映射;
2、ngnix会根据用户请求的 URI 来检查定义的所有location,按一定的优先级找出一个最佳匹配;
3、在没有使用正则表达式的时候,nginx会先在servert中的多个locationi选取匹配度最高的一个uri;
3、uri 是用户请求的字符串,即域名后面的web文件路径;
4、然后使用该 location 模块中的正则 URI 和字符串,如果匹配成功就结束搜索,并使用此location处理此请求。
#语法规则:location [ = | ~ | ~* | 不带符号 | ^~ ] uri {...}
= #用于标准uri前,需要精确匹配文件,大小敏感,如果匹配成功就停止向下匹配并立即处理请求
^~ #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头
#对uri的最左边部分做匹配检查,不区分字符大小写
~ #用于标准uri前,表示包含正则表达式,并且区分大小写
~* #用于标准uri前,表示包含正则表达式,并且不区分大写
不带符号 #匹配起始于此uri的所有的uri
\ #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ? 等转义为普通符号(nginx-1.26版本之后不用转义符也可识别)
#匹配优先级从高到低("="后匹配文件):
=,~|~*,不带符号,^~
#匹配优先级从高到低(匹配目录):
~|~*,不带符号,^~,("="后要匹配文件才能生效)
URI 精确匹配
=:
效果演示:
~ 和 ~*:
“ ~ ” 和 “ ~* ” 的优先级最高,且两者优先级相同
效果演示:
不带符号:
不带符号 和 “ ^~ ” 两者之间,不带符号的优先级高
效果演示:
^~:
“ ^~ ” 的优先级最低
效果演示:
账户认证
创建页面登录密码
[root@nginx ~]# htpasswd -cm /usr/local/nginx/.htpasswd tym
编辑子配置文件
效果演示:
自定义错误页面
错误页显示内容:
编辑子配置文件:
演示效果:
自定义日志路径
修改子配置文件
演示效果:
检测文件是否存在
效果演示:
长链接配置
keepalive_timeout 65; #设定保持连接超时时长,0表示禁止长连接,默认为65s
#通常配置在http字段作为站点全局配置
keepa1ive_requests nuber; #在一次长连接上所允许请求资源的最大数量
#建议适当调大,比如:500
keepalive_timeout 65 60;
#开启长连接后,返回客户端的会话保持时间为60s,单次长连接累计请求达到指定次数或时间达到65秒后就会被断开链接,第二个数字60为服务端发送给客户端应答报文头部中显示的超时时间设置为60s:不设置该时间,客户端将不显示超时时间。
在连接时,客户端会收到服务端发来的报文:Keep-Alive:timeout=60
如果 " keepalive_timeout 0 " 表示关闭会话保持功能,将显示:#Connection:close
修改主配置文件
搭建服务器
autoindex on | off; #自动文件索引功能,默为off
autoindex_exact_size on | off; #计算文件确切大小(单位bytes),off 显示大概大小(单位K、M),默认on
autoindex_localtime on | off ; #显示本机时间而非GMT(格林威治)时间,默认off
limit_rate 1024k; #限速,默认不限速(0表示不限速)
修改子配置文件
效果演示:
Nginx 高级配置
Nginx 状态页
1、基于nginx模块 ngx_http_stub_status_module 实现;
2、在编译安装nginx的时候需要添加编译参数 " --with-http_stub_status_module "
3、如果没有添加参数,会在配置完成的监测页面提示错误
状态页各参数含义
页面参数示例:
Active connections:1
server accepts handled requests
94 94 165
Reading:0 writing:1 waiting:0
参数含义:
Active connections:number #当前处于活动状态的客户端连接数
#包括连接等待空闲连接数= reading + writing + waiting
accepts: #统计总值,Ngix自启动后已经接受的客户端请求连接的总数。
handled: #统计总值,Ngix自启动后已经处理完成的客户端请求连接总数
#通常等于accepts,除非有因worker_connections限制等被拒绝的连接
requests: #统计总值,Nginx自启动后客户端发来的总的请求数
Reading: #当前状态,正在读取客户端请求报文首部的连接的连接数
#数值越大,说明排队现象严重,性能不足
writing: #当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明访问量很大
waiting: #当前状态,正在等待客户端发出请求的空闲连接数
开启keep-alive的情况下,这个值等于active(reading+writing)
修改子配置文件
效果演示:
压缩传输资源
Nginx 支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,降低企业的 IT 支出,不过会占用相应的CPU资源。
Nginx 对文件的压缩功能是依赖于模块 ngx_http_gzip_module,默认是内置模块
gzip on|off; #启用或禁用gzip压缩,默认关闭
gzip_comp_level 4; #压缩比由低到高,从1到9,默认为1,值越高压缩后文件越小,但是消耗cpu比较高;基本设定为4或5
gzip_min_length 1k; #gzi压缩的最小文件,小于设置值的文件将不会压缩
gzip_http_version 1.0|1.1; #启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_vary on|off; #如果启用压缩,是否在响应报文首部插入“Vary:Accept-Encoding”,一般建议打开
gzip_types ...; #指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不直接指定路径,否则报错
gzip_static on|off; #预压缩,即直接从磁盘找到对应文件的gz后缀的压缩文件返回给用户,无需消耗服务器CPU;注意:该功能来自于 ngx_http_gzip_static_module 模块
gzip_buffers number size; #指定Nginx服务需要向服务器申请的缓存空间的个数和大小,不同平台之间不同,默认:324k或者168k;
gzip_disable "MSIE [1-6]\."; #禁用IE6 gzip功能,早期的IE6版本不支持压缩
修改主配置文件
资源类型:text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/gif image/png
效果演示:
Nginx 隐藏版本
在生成源码数据时可进行版本号和名称的修改
修改配置文件:
Nginx 变量
nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用
变量可以分为内置变量和自定义变量
内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值
常用内置变量:
$remote_addr; #存放了客户端的地址,注意是客户端的公网IP
$args; #变量中存放了URL中的所有参数
#例如:https://search.jd.com/Search?keyword=手机&enc=utf-8
#返回结果为: keyword=手机&enc=utf-8
$is_args #如果有参数返回值:? 否则为空
$document_root; #保存了针对当前资源的请求的系统根目录,例如:/webdata/nginx/timinglee.org/lee
$document_uri; #保存了当前请求中不包含参数的URI,注意是不包含请求的指令
#比如:http://lee.timinglee.org/var?\id=11111会被定义为/var
#返回结果为:/var
$host; #存放了请求的host名称
limit_rate 10240;
echo $limit_rate; #如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置,则显示0
$remote_port; #客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
$remote_user; #已经经过Auth Basic Module验证的用户名
$request_body_file; #做反向代理时发给后端服务器的本地资源的名称
$request_method; #请求资源的方式,GET/PUT/DELETE等
$request_filename; #当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径
#如:webdata/nginx/timinglee.org/lee/var/index.html
$request_uri; #包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args,
#例如:/main/index.do?id=20190221&partner=search
$scheme; #请求的协议,例如:http,https,ftp等
$server_protocol; #保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr; #保存了服务器的IP地址
$server_name; #虚拟主机的主机名
$server_port; #虚拟主机的端口号
$http_user_agent; #客户端浏览器的详细信息
$http_cookie; #客户端的所有cookie信息
$cookie_<name> #name为任意请求报文首部字部cookie的key名
$http_<name> #name为任意请求报文首部字段,表示记录请求报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线
#示例:
echo $http_user_agent;
echo $http_host;
$sent_http_<name> #name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有问题
echo $sent_http_server;
$arg_<name> #此变量存放了URL中的指定参数,name为请求url中指定的参数
echo $arg_id;
修改子配置文件
效果演示:
自定义变量
效果演示:
Nginx Rewrite 指令
1、Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求
2、此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库
3、rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能
4、比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问
5、另外还可以在一定程度上提高网站的安全性。
if 判断
用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断
使用正则表达式对变量进行匹配,匹配成功时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
编辑子配置文件
效果演示:
break 终止
1、用于中断当前相同作用域(location)中的其他Nginx配置
2、与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效
3、位于后面的 ngx_http_rewrite_module 模块中指令就不再执行
4、Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置
5、该指令可以在server块和locationif块中使用
注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module模块的指令,其它指令还会执行
编辑子配置文件
效果演示:
return 返回
return 用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置
修改子配置文件
演示效果:
文件路径存在,输出指定内容
文件路径不存在,则跳转至百度
rewrite 指令
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理
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 这几个字母以外的任意字符
rewrite flag
利用nginx的rewrite的指令,可以实现url的重新跳转,rewrite有四种不同的flag,分别是redirect(临时重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型
跳转型指由客户端浏览器重新对新地址进行请求
代理型是在WEB服务器内部实现跳转
redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求,状态码:301
break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作
#而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在
location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,
#而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户
临时重定向和永久重定向
临时重定向
修改子配置文件
效果演示:
永久重定向:
修改子配置文件
效果演示:
break 和 last 区别
break 不会跳出本地的 location
last 会跳出本地的 location,去匹配其它的 location(不限制于 ngx_http_rewrite_module 模块)
break:
修改子配置文件
演示效果:
没有加上 “ break ” 时
加上 “ break ”
last:
修改子配置文件
效果演示:
没有加上 ” last “
加上 ” last “
全站加密
修改子配置文件
效果演示:
Nginx 防盗链
防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站的图片或某个单独的资源,而不是打开了自己搭建网站的整个页面,这就是盗链,referer就是之前的那个网站域名
正常的referer信息有以下几种:
none #请求报文首部没有referer首部,
#比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked #请求报文有referer首部,但无有效值,比如为空。
server_names #referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string #自定义指定字符串,但可使用*作通配符。示例: *.baidu.com
regular expression #被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:
~.*\.baidu\.com
修改子配置文件
效果演示:
Nginx 反向代理
反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。
Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能:
ngx_http_proxy_module #将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module #用于定义为proxy_pass,fastcgi_pass,uwsgi_pass等指令引用的后端服务器分组
ngx_stream_proxy_module #将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module #将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module #将客户端对Python的请求以uwsgi协议转发至指定服务器处理
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_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。
实现反向代理
修改子配置文件
效果展示:
实现动静分离
修改子配置文件
效果展示:
动态页面
静态页面
缓存功能
缓存功能默认关闭状态,需要修改主配置文件才能启用
缓存功能参数:
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
修改主配置文件
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m
inactive=120s max_size=1g;
修改子配置文件:
效果展示:
进行压力测试:
ab -n1000 -c100 http://www.tym.com/static/index.html
http 反向代理负载均衡
配置参数:
#自定义一组服务器,配置在http模块内
upstream name {
server .....
......
}
#server支持的parameters如下:
weight=number; #设置权重,默认为1,实现类似于LVS中的WRR,WLC等
max_conns=number; #给当前后端server设置最大活动链接数,默认为0表示没有限制
max_fails=number; #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测
fail_timeout=time; #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒
backup; #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器
down; #标记为down状态,可以平滑下线后端服务器
resolve; #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx;
#支持算法如下:
hash KEY [consistent]; #基于指定请求报文中首部字段或者URI等key做hash计算,使用consistent参数,将使用ketama一致性hash算法,适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一致性hash基于取模运算
hash $request_uri consistent; #基于用户请求的uri做hash
hash $cookie_sessionid; #基于cookie中的sessionid这个key进行hash调度,实现会话绑定
ip_hash; #源地址hash调度方法,基于的客户端d1remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计算,以实现会话保持
least_conn; #最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC
实现负载均衡:
修改子配置文件
主配置文件:
效果演示:
调用算法:
效果演示:
Nginx 四层负载均衡
Nginx在1.9.0版本开始支持tcp模式的负载均衡,在1.9.13版本开始支持udp协议的负载,udp主要用于DNS的域名解析,其配置方式和指令和 http 代理类似,其基于 ngx_stream_proxy_module 模块实现tcp负载,另外基于模块 ngx_stream_upstream_module 实现后端服务器分组转发、权重分配、状态监测、调度算法等高级功能。
如果编译安装,需要指定 --with-stream 选项才能支持ngx_stream_proxy_module模块
TCP 和 UDP 负载均衡配置的参数
实现四层负载均衡:
修改主配置文件
四层负载均衡应写在HTTP之外
数据库负载均衡:
MySQL配置:
1、下载 mariadb-server
[root@rs2 named]# yum install mariadb-server -y
2、修改数据库服务 ID ;开启数据库并登录
#修改数据库服务ID
[root@rs2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
......
[mysqld]
server-id=2
......
#开启数据库
[root@rs2 named]# systemctl start mariadb
#登录数据库
[root@rs2 ~]# mysql
MariaDB [(none)]> CREATE USER tym@'%' identified by '123';
MariaDB [(none)]> GRANT ALL ON *.* TO tym@'%';
MariaDB [(none)]> exit
效果演示:
[root@rs2 ~]# mysql -utym -p123 -h172.25.254.10
DNS 负载均衡:
DNS 配置:
1、下载 bind
[root@rs2 ~]# yum install bind -y
2、修改配置文件
[root@rs2 ~]# vim /etc/named.conf
[root@rs2 ~]# vim /etc/named.rfc1912.zones
[root@rs2 ~]# cp /var/named/named.localhost /var/named/tym.org.zone
效果演示:
实现 FastCGL
CGI的由来:
最早的Web服务器只能简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态html文件,但是后期随着网站功能增多网站开发也越来越复杂,以至于出现动态技术,比如像php(1995年)、java(1995)、python(1991)语言开发的网站,但是nginx/apache服务器并不能直接运行 php、java这样的文件,apache实现的方式是打补丁,但是nginx缺通过与第三方基于协议实现,即通过某种特定协议将客户端请求转发给第三方服务处理,第三方服务器会新建新的进程处理用户的请求,处理完成后返回数据给Nginx并回收进程,最后nginx在返回给客户端,那这个约定就是通用网关接口(common gateway interface,简称CGI),CGI(协议) 是web服务器和外部应用程序之间的接口标准,是cgi程序和web服务器之间传递信息的标准化接口。
为什么会有FastCGI:
CGI协议虽然解决了语言解析器和 Web Server 之间通讯的问题,但是它的效率很低,因为 Web Server每收到一个请求都会创建一个CGI进程,PHP解析器都会解析php.ini文件,初始化环境,请求结束的时候再关闭进程,对于每一个创建的CGI进程都会执行这些操作,所以效率很低,而FastCGI是用来提高CGI性能的,FastCGI每次处理完请求之后不会关闭掉进程,而是保留这个进程,使这个进程可以处理多个请求。这样的话每个请求都不用再重新创建一个进程了,大大提升了处理效率。
什么是PHP-FPM:
PHP-FPM(FastCGI Process Manager):
1、FastCGI(进程管理器)是一个实现了Fastcgi的程序,并且提供进程管理的功能
2、进程包括master进程和worker进程。master进程只有一个,负责监听端口,接受来自web server的请求
3、worker进程一般会有多个,每个进程中会嵌入一个PHP解析器,进行PHP代码的处理
配置指令
Nginx 基于模块 ngx_http_fastcgi_module 实现通过fastcgi协议将指定的客户端请求转发至php-fpm处理,其配置指令如下:
fastcgi_pass address:port; #转发请求到后端服务器,address为后端的fastcgi server的地址,可用位置:location, if in location
fastcgi_index name; #fastcgi默认的主页资源,示例:fastcgi_index index.php;
fastcgi_param parameter value [if_not_empty]; #设置传递给FastCGI服务器的参数值,可以是文本,变量或组合,可用于将Nginx的内置变量赋值给自定义key
fastcgi_param REMOTE_ADDR $remote_addr; #客户端源IP
fastcgi_param REMOTE_PORT $remote_port; #客户端源端口
fastcgi_param SERVER_ADDR $server_addr; #请求的服务器IP地址
fastcgi_param SERVER_PORT $server_port; #请求的服务器端口
fastcgi_param SERVER_NAME $server_name; #请求的server name
源码安装 Nginx
1、下载源码安装包,安装环境依赖
环境依赖:
[root@nginx ~]# yum install gcc pcre-devel zlib-devel openssl-devel -y
使用源码安装 Nginx,自由设定自己需要的功能( “ \ ” 换行符 )
进入到源码目录内进行源码的生成
[root@Nginx nginx-1.26.1]#./configure --prefix=/usr/local/nginx\
--user=nginx\ #指定nginx运行用户
--group=nginx\ #指定nginxi运行组
--with-http_ss1_module\ #支持https://
--with-http_v2_module\ #支持http版本2
--with-http_realip_module\ #支持ip透传
--wi th-http_stub_status_module\ #支持状态页面
--with-http_gzip_static_module\ #支持压缩
--with-pcre\ #支持正则
--with-stream\ #支持tcp反向代理
--with-stream_ss1_module\ #支持tcp的ss1加密
--with-stream_realip_module\ #支持tcp的透传ip
--add-module=/root/echo-nginx-module-0.63\
--add-module=/root/memc-nginx-module-0.20\
--add-module=/root/srcache-nginx-module-0.33
进行源码的编译和安装
[root@Nginx ~]# make && make install
源码安装 PHP
1、下载源码安装包,安装环境依赖
环境依赖:
[root@Nginx ~]# yum install bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel oniguruma-devel gcc pcre-devel zlib-devel openssl-devel -y
2、选定参数,生成源码
进入到源码目录内选择参数生成源码
[root@nginx php-8.3.9]# ./configure \
--prefix=/usr/local/php \ #安装路径
--with-config-file-path=/usr/local/php/etc\ #指定配置路径
--enable-fpm \ #用cgi方式启动程序
--with-fpm-user=nginx \ #指定运行用户身份
--with-fpm-group=nginx \
--with-curl \ #打开curl浏览器支持
--with-iconv \ #启用iconv函数,转换字符编码
--with-mhash \ #mhash加密方式扩展库
--with-zlib \ #支持zlib库,用于压缩http压缩传输
--with-openssl \ #支持ssl加密
--enable-mysqlnd \ #mysql数据库
--with-mysqli \
--with-pdo-mysql \
--disable-debug \ #关闭debug功能
--enable-sockets \ #支持套接字访问
--enable-soap \ #支持soap扩展协议
--enable-xml \ #支持xml
--enable-ftp \ #支持ftp
--enable-gd \ #支持gd库
--enable-exif \ #支持图片元数据
--enable-mbstring \ #支持多字节字符串
--enable-bcmath \ #打开图片大小调整,用到zabbix监控的时候用到了这个模块
--with-fpm-systemd #支持systemctl 管理cgi
3、进行源码的编译
[root@nginx php-8.3.9]# make
4、编译完成后进行安装
[root@nginx php-8.3.9]# make install
PHP 配置优化
1、指定pid存放位置
[root@Nginx ~]# vim /usr/local/php/etc/php-fpm.conf
2、生成主配置文件
3、修改主配置文件
[root@Nginx ~]# vim /usr/local/php/etc/php.ini
4、生成自启动文件
编辑启动文件内容
5、开机自启动
6、本地快捷启动配置
[root@nginx ~]# vim /root/.bash_profile
Nginx 配置转发功能(PHP页面)
编辑 Nginx 子配置文件
添加 PHP 页面文件
效果演示:
Nginx-PHP 缓存优化
1、下载源码软件包 memcache-8.2
2、进行源码的编译和安装
#生成 ./configure 文件
[root@nginx memcache-8.2]# phpize
#生成源码
[root@nginx memcache-8.2]# ./configure
#编译和安装
[root@nginx memcache-8.2]# make && make install
3、在 PHP 主配置文件内添加 mencache 模块
[root@nginx memcache-8.2]# vim /usr/local/php/etc/php.ini
#修改完配置文件重新加载服务
[root@nginx memcache-8.2]# systemctl reload php-fpm.service
4、安装 memcached
[root@nginx etc]# yum install memcached -y
5、启动服务
[root@nginx etc]# systemctl start memcached.service
6、查看是否加载成功
[root@nginx ~]# php -m
7、复制 memcached 测试页面至 PHP 发布页
8、修改测试页内容
[root@nginx ~]# vim /php/memcache.php
效果演示:
Nginx-PHP 高速缓存
1、下载软件包(memc-nginx-module-0.20.tar.gz、srcache-nginx-module-0.33.tar.gz)
2、在生成 Nginx 的源码时,将以上两个模块添加上
进入到源码目录内进行源码的生成
[root@Nginx nginx-1.26.1]#./configure --prefix=/usr/local/nginx\
--user=nginx\ #指定nginx运行用户
--group=nginx\ #指定nginxi运行组
--with-http_ss1_module\ #支持https://
--with-http_v2_module\ #支持http版本2
--with-http_realip_module\ #支持ip透传
--wi th-http_stub_status_module\ #支持状态页面
--with-http_gzip_static_module\ #支持压缩
--with-pcre\ #支持正则
--with-stream\ #支持tcp反向代理
--with-stream_ss1_module\ #支持tcp的ss1加密
--with-stream_realip_module\ #支持tcp的透传ip
--add-module=/root/echo-nginx-module-0.63\
--add-module=/root/memc-nginx-module-0.20\
--add-module=/root/srcache-nginx-module-0.33
3、修改 Nginx 子配置文件
[root@nginx conf.d]# vim nginx.conf
#重新加载服务
[root@nginx conf.d]# nginx -s reload
效果演示:
#压力测试
[root@nginx conf.d]# ab -n500 -c10 http://www.tym.com/index.php