企业高性能web服务器学习轻松简单+愉快!!

目录

Web 服务介绍

Apache prefork 模型

Apache worker 模型

Apache event模型

网络 I/O

I/O 模型

I/O 模型相关概念

网络 I/O 模型

阻塞型I/O 模型(blocking IO)

非阻塞型I/O(nonblocking IO

多路复用I/O型(I/O multiplexing)

信号驱动式I/O模型 (signal-driven IO)

异步 I/O 模型(asynchronous IO)

五种IO对比

编译安装 Nginx

验证版本及编译参数

Nginx 启动文件

平滑升级和回滚

Nginx 核心配置详解

配置文件说明

全局配置

root 与 alias

Nginx 高级配置

Nginx 状态页

Nginx 压缩功能

Nginx 变量使用

自定义变量

if判定

set 指令

break 指令

return 指令

rewrite 指令

rewrite flag 使用介绍

rewrite案例: 域名永久与临时重定向

rewrite案例: 自动跳转 https

Nginx 防盗链

Nginx 反向代理功能

实战案例: 反向代理单台 web 服务器

实战案例: 指定 location 实现反向代理

实战案例: 动静分离

反向代理示例: 缓存功能

准备缓存配置

反向代理示例: 后端多台 web服务器

实现 Nginx 四层负载均衡

tcp负载均衡配置参数

tcp负载均衡配置参数

负载均衡实例: MySQL

实现 FastCGI

FastCGI配置指令

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

源码编译php

php相关配置优化

Nginx配置转发

添加php环境变量

php的动态扩展模块(php的缓存模块)

安装memcache模块

php高速缓存

nginx二次开发版本


Web 服务介绍

Apache prefork 模型

  • 预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024

  • 每个子进程有一个独立的线程响应用户请求

  • 相对比较占用内存,但是比较稳定,可以设置最大和最小进程数

  • 是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景

优点:稳定

缺点:每个用户请求需要对应开启一个进程,占用资源较多,并发性差,不适用于高并发场景

Apache worker 模型

  • 一种多进程和多线程混合的模型

  • 有一个控制进程,启动多个子进程

  • 每个子进程里面包含固定的线程

  • 使用线程程来处理请求

  • 当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,

  • 由于其使用了线程处理请求,因此可以承受更高的并发

优点:相比prefork 占用的内存较少,可以同时处理更多的请求

缺点:使用keepalive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超 时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用(该问题在 prefork模式下,同样会发生)

Apache event模型

Apache中最新的模式,2012年发布的apache 2.4.X系列正式支持event 模型,属于事件驱动模型(epoll)

每个进程响应多个请求,在现在版本里的已经是稳定可用的模式

它和worker模式很像,最大的区别在于,它解决了keepalive场景下长期被占用的线程的资源浪费问题(某些线程因为被keepalive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)

event MPM中,会有一个专门的线程来管理这些keepalive类型的线程

当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力

优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keepalive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放

缺点:没有线程安全控制

网络 I/O

网络通信就是网络协议栈到用户空间进程的IO就是网络IO

网络I/O 处理过程

  • 获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3)

  • 构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4)

  • 返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端(5-7)

不论磁盘和网络I/O

每次I/O,都要经由两个阶段:

  • 第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长

  • 第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短

I/O 模型

I/O 模型相关概念

同步/异步:关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。

  • 同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成

  • 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态

 

阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态

  • 阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。

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

 

网络 I/O 模型

阻塞依次减小:阻塞型、非阻塞型、复用型、信号驱动型、异步

阻塞型I/O 模型(blocking IO)

  • 阻塞IO模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞;

  • 用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成read操作;

  • 用户需要等待read将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够。

优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源

缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销

较apache 的preforck使用的是这种模式。

同步阻塞:程序向内核发送I/O请求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回,则进程将一直等待并不再接受新的请求,并由进程轮询查看I/O是否完成,完成后进程将I/O结果返回给Client,在IO没有返回期间进程不能接受其他客户的请求,而且是有进程自己去查看I/O是否完成,这种方式简单,但是比较慢,用的比较少。

非阻塞型I/O(nonblocking IO

用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据到达后,才真正读取到数据,继续执行。即 “轮询”机制存在两个问题:如果有大量文件描述符都要等,那么就得一个一个的read。这会带来大量的Context Switch(read是系统调用,每调用一次就得在用户态和核心态切换一次)。轮询的时间不好把握。这里是要猜多久之后数据才能到。等待时间设的太长,程序响应延迟就过大;设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。

非阻塞:程序向内核发送请I/O求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回IO结果,进程将不再等待,而且继续处理其他请求,但是仍然需要进程隔一段时间就要查看内核I/O是否完成。

查看上图可知,在设置连接为非阻塞时,当应用进程系统调用 recvfrom 没有数据返回时,内核会立即返回一个 EWOULDBLOCK 错误,而不会一直阻塞到数据准备好。如上图在第四次调用时有一个数据报准备好了,所以这时数据会被复制到 应用进程缓冲区 ,于是 recvfrom 成功返回数据

当一个应用进程这样循环调用 recvfrom 时,称之为轮询 polling 。这么做往往会耗费大量CPU时间,实际使用很少

多路复用I/O型(I/O multiplexing)

上面的模型中,每一个文件描述符对应的IO是由一个线程监控和处理

多路复用IO指一个线程可以同时(实际是交替实现,即并发完成)监控和处理多个文件描述符对应各自的IO,即复用同一个线程

一个线程之所以能实现同时处理多个IO,是因为这个线程调用了内核中的SELECT,POLL或EPOLL等系统调用,从而实现多路复用IO

I/O multiplexing 主要包括:select,poll,epoll三种系统调用,select/poll/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。

它的基本原理就是select/poll/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。

当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。

Apache prefork是此模式的select,worker是poll模式。

IO多路复用(IO Multiplexing) :是一种机制,程序注册一组socket文件描述符给操作系统,表示“我要

监视这些fd是否有IO事件发生,有了就告诉程序处理”IO多路复用一般和NIO一起使用的。NIO和IO多路复用是相对独立的。NIO仅仅是指IO API总是能立刻返回,不会被Blocking;而IO多路复用仅仅是操作系提供的一种便利的通知机制。操作系统并不会强制这俩必须得一起用,可以只用IO多路复用 + BIO,这时还是当前线程被卡住。IO多路复用和NIO是要配合一起使用才有实际意义

IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,就通知该进程多个连接共用一个等待机制,本模型会阻塞进程,但是进程是阻塞在select或者poll这两个系统调用上,而不是阻塞在真正的IO操作上用户首先将需要进行IO操作添加到select中,同时等待select系统调用返回。当数据到达时,IO被激活,select函数返回。用户线程正式发起read请求,读取数据并继续执行从流程上来看,使用select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还多了添加监视IO,以及调用select函数的额外操作,效率更差。并且阻塞了两次,但是第一次阻塞在select上时,select可以监控多个IO上是否已有IO操作准备就绪,即可达到在同一个线程内同时处理多个IO请求的目的。而不像阻塞IO那种,一次只能监控一个IO虽然上述方式允许单线程内处理多个IO请求,但是每个IO请求的过程还是阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要长。如果用户线程只是注册自己需要的IO请求,然后去做自己的事情,等到数据到来时再进行处理,则可以提高CPU的利用率IO多路复用是最常使用的IO模型,但是其异步程度还不够“彻底”,因它使用了会阻塞线程的select系统调用。因此IO多路复用只能称为异步阻塞IO模型,而非真正的异步IO

优缺点

  • 优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述符一个线程),这样可以大大节省系统资源

  • 缺点:当连接数较少时效率相比多线程+阻塞 I/O 模型效率较低,可能延迟更大,因为单个连接处理需要 2 次系统调用,占用时间会有增加

IO多路复用适用如下场合:

  • 当客户端处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用

  • 当一个客户端同时处理多个套接字时,此情况可能的但很少出现

  • 当一个服务器既要处理监听套接字,又要处理已连接套接字,一般也要用到I/O复用

  • 当一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用

  • 当一个服务器要处理多个服务或多个协议,一般要使用I/O复用

信号驱动式I/O模型 (signal-driven IO)

 

信号驱动I/O的意思就是进程现在不用傻等着,也不用去轮询。而是让内核在数据就绪时,发送信号通知进程。

调用的步骤是,通过系统调用 sigaction ,并注册一个信号处理的回调函数,该调用会立即返回,然后主程序可以继续向下执行,当有I/O操作准备就绪,即内核数据就绪时,内核会为该进程产生一个 SIGIO信号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用 recvfrom 获取数据,将用户进程所需要的数据从内核空间拷贝到用户空间

此模型的优势在于等待数据报到达期间进程不被阻塞。用户主程序可以继续执行,只要等待来自信号处理函数的通知。

在信号驱动式 I/O 模型中,应用程序使用套接口进行信号驱动 I/O,并安装一个信号处理函数,进程继续运行并不阻塞

在信号驱动式 I/O 模型中,应用程序使用套接口进行信号驱动 I/O,并安装一个信号处理函数,进程继续运行并不阻塞

当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 I/O 操作函数处理数据。

优点:线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此可以提高资源的利用率

缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知

异步阻塞:程序进程向内核发送IO调用后,不用等待内核响应,可以继续接受其他请求,内核收到进程请求后进行的IO如果不能立即返回,就由内核等待结果,直到IO完成后内核再通知进程

异步 I/O 模型(asynchronous IO)

异步I/O 与 信号驱动I/O最大区别在于,信号驱动是内核通知用户进程何时开始一个I/O操作,而异步I/O是由内核通知用户进程I/O操作何时完成,两者有本质区别,相当于不用去饭店场吃饭,直接点个外卖,把等待上菜的时间也给省了

相对于同步I/O,异步I/O不是顺序执行。用户进程进行aio_read系统调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到socket数据准备好了,内核直接复制数据给进程,然后从内核向进程发送通知。IO两个阶段,进程都是非阻塞的。

信号驱动IO当内核通知触发信号处理程序时,信号处理程序还需要阻塞在从内核空间缓冲区拷贝数据到用户空间缓冲区这个阶段,而异步IO直接是在第二个阶段完成后,内核直接通知用户线程可以进行后续操作了

优点:异步 I/O 能够充分利用 DMA 特性,让 I/O 操作与计算重叠

缺点:要实现真正的异步 I/O,操作系统需要做大量的工作。目前 Windows 下通过 IOCP 实现了真正的异步 I/O,在 Linux 系统下,Linux 2.6才引入,目前 AIO 并不完善,因此在 Linux 下实现高并发网络编程时以 IO 复用模型模式+多线程任务的架构基本可以满足需求

Linux提供了AIO库函数实现异步,但是用的很少。目前有很多开源的异步IO库,例如libevent、libev、libuv。

异步非阻塞:程序进程向内核发送IO调用后,不用等待内核响应,可以继续接受其他请求,内核调用的IO如果不能立即返回,内核会继续处理其他事物,直到IO完成后将结果通知给内核,内核在将IO完成的结果返回给进程,期间进程可以接受新的请求,内核也可以处理新的事物,因此相互不影响,可以实现较大的同时并实现较高的IO复用,因此异步非阻塞使用最多的一种通信方式。

五种IO对比

这五种 I/O 模型中,越往后,阻塞越少,理论上效率也是最优前四种属于同步 I/O,因为其中真正的 I/O操作(recvfrom)将阻塞进程/线程,只有异步 I/O 模型才与 POSIX 定义的异步 I/O 相匹配

 

Nginx 安装

编译安装 Nginx

安装nginx

官网下载链接:nginx: download

编译安装示例:

#可以用链接下载最新版
[root@Nginx ~]# wget https://nginx.org/download/nginx-1.26.2.tar.gz
#这里我用的1.24.0后面方便回滚实验
[root@Nginx ~]# dnf install gcc pcre-devel zlib-devel openssl-devel -y #安装所需要的环境
[root@Nginx nginx]# tar zxf nginx-1.24.0.tar.gz
[root@Nginx nginx-1.24.0]# useradd -s /sbin/nologin -M nginx
[root@Nginx nginx]# cd nginx-1.24.0/
[root@Nginx nginx-1.24.0]# ls
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README


[root@Nginx nginx-1.24.0]# ./configure --prefix=/usr/local/nginx \
--user=nginx \ 					   # 指定nginx运行用户
--group=nginx \ 				   # 指定nginx运行组
--with-http_ssl_module \ 		    # 支持https://
--with-http_v2_module \ 		    # 支持http版本2
--with-http_realip_module \		    # 支持ip透传
--with-http_stub_status_module \     # 支持状态页面
--with-http_gzip_static_module \     # 支持压缩
--with-pcre \ 					   # 支持正则
--with-stream \ 				   # 支持tcp反向代理
--with-stream_ssl_module \ 			# 支持tcp的ssl加密
--with-stream_realip_module 		# 支持tcp的透传ip
[root@Nginx nginx-1.24.0]# make && make install

[root@Nginx ~]# vim ~/.bash_profile   #把nginx软件的命令执行路径添加到环境变量中
 
 
 
 

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

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

conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能的,例如fastcgi功能使用的是fastcgi.conf和fastcgi_params两个文件,配置文件一般都有一个样板配置文件,是以.default为后缀,使用时可将其复制并将default后缀
去掉即可。

logs:用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比如/var/logs/nginx里面。

sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能。

验证版本及编译参数

[root@Nginx ~]# vim ~/.bash_profile #把nginx软件的命令执行路径添加到环境变量中
export PATH=$PATH:/usr/local/nginx/sbin
[root@Nginx ~]# source ~/.bash_profile
[root@Nginx ~]# nginx -V
nginx version: nginx/1.24.0
built by gcc 11.4.1 20231218 (Red Hat 11.4.1-3) (GCC)
built with OpenSSL 3.0.7 1 Nov 2022
TLS SNI support enabled
configure arguments: --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

Nginx 启动文件

#nginx -s quit 命令用于优雅地关闭 Nginx 服务器。
#当执行此命令时,Nginx 会完成当前正在处理的请求,然后关闭服务器。
#与直接使用 kill 命令强制终止 Nginx 进程不同,nginx -s quit 可以确保不会导致正在处理的连接突然中断,从而提供更平稳和可靠的服务器关闭方式。
[root@Nginx ~]# nginx -s quit

[root@Nginx ~]# 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

[root@Nginx ~]# systemctl daemon-reload
[root@Nginx ~]# systemctl start nginx

平滑升级和回滚

#解压模块echo-nginx-module-0.63
[root@nginx ~]# tar zxf echo-nginx-module-0.63
#解压nginx-1.26.1.tar.gz
[root@nginx ~]# tar zxf nginx-1.26.1.tar.gz
#增加一个参数--add-module=/root/echo-nginx-module-0.63,在编译nginx这个版本的时候会把echo-nginx-module-0.63这个模块在nginx中加进去,让Nginx在内部可以具备echo命令的功能。
[root@nginx nginx-1.26.2]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --add-module=/root/echo-nginx-module-0.63 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_gzip_static_module --with-http_stub_status_module --with-pcre --with-stream --with-stream_ssl_module 
[root@Nginx nginx-1.26.1]# make

#把之前的旧版的nginx命令备份
[root@Nginx ~]# cd /usr/local/nginx/sbin/
[root@Nginx sbin]# cp nginx nginx.24

#把新版本的nginx命令复制过去
[root@Nginx sbin]# \cp -f /root/nginx/nginx-1.26.1/objs/nginx
/usr/local/nginx/sbin

#检测一下有没有问题
[root@Nginx sbin]# 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 sbin]# kill -USR2 38007 #nginx worker ID
#USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的
nginx
#此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80
#此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。

[root@Nginx sbin]# ps aux | grep nginx
root 38007 0.0 0.1 9868 2436 ? Ss 14:17 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
nobody 38008 0.0 0.2 14200 4868 ? S 14:17 0:00 nginx: worker
process
root 42075 0.0 0.3 9876 6528 ? S 15:41 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
nobody 42076 0.0 0.2 14208 4868 ? S 15:41 0:00 nginx: worker
process

[root@Nginx sbin]# curl -I 172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.24.0 ##依旧是旧版本生生效
Date: Tue, 20 Aug 2024 15:28:39 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 19 Aug 2024 02:23:20 GMT
Connection: keep-alive
ETag: "66988ed9-267"
Accept-Ranges: bytes

#回收旧版本
[root@Nginx sbin]# kill -WINCH 38007
[root@Nginx sbin]# ps aux | grep nginx
root 38007 0.0 0.1 9868 2436 ? Ss 14:17 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
root 42075 0.0 0.3 9876 6528 ? S 15:41 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
nobody 42076 0.0 0.2 14208 4868 ? S 15:41 0:00 nginx: worker
process

#检测版本信息
[root@nginx ~]# curl -I 172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.26.1				#新版本生效
Date: Tue, 20 Aug 2024 15:40:28 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 19 Aug 2024 02:30:20 GMT
Connection: keep-alive
ETag: "66c2ac98-267"
Accept-Ranges: bytes

#回滚
#如果升级的版本发现问题需要回滚,可以重新拉起旧版本的worker
[root@Nginx sbin]# cp nginx nginx.26
[root@Nginx sbin]# ls
nginx nginx.24 nginx.26
[root@Nginx sbin]# mv nginx.24 nginx
mv: overwrite 'nginx'? y

[root@Nginx sbin]# kill -HUP 38007
[root@Nginx sbin]# ps aux | grep nginx
root 38007 0.0 0.1 9868 2436 ? Ss 14:17 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
root 42075 0.0 0.3 9876 6528 ? S 15:41 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
nobody 42076 0.0 0.2 14208 5124 ? S 15:41 0:00 nginx: worker
process
nobody 42130 0.0 0.2 14200 4868 ? S 16:30 0:00 nginx: worker
process

[root@Nginx sbin]# kill -WINCH 42075
[root@Nginx sbin]# ps aux | grep nginx
root 38007 0.0 0.1 9868 2436 ? Ss 14:17 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
root 42075 0.0 0.3 9876 6528 ? S 15:41 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
nobody 42130 0.0 0.2 14200 4868 ? S 16:30 0:00 nginx: worker
process
root =42137 0.0 0.1 221664 2176 pts/0 S+ 16:31 0:00 grep --
color=auto nginx

[root@Nginx sbin]# curl -I 172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.24.0 		#版本回滚完成
Date: Tue, 20 Aug 2024 15:28:39 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 19 Aug 2024 02:23:20 GMT
Connection: keep-alive
ETag: "66988ed9-267"
Accept-Ranges: bytes

#自定义Nginx版本信息
#目录:/root/nginx-1.24.0/src/core
#文件:nginx.h

Nginx 核心配置详解

配置文件说明

Nginx的配置文件的组成部分:

  • 主配置文件:nginx.conf

  • 子配置文件: include conf.d/*.conf

  • fastcgi, uwsgi,scgi 等协议相关的配置文件

  • mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮

  • 件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某

  • 种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动

  • 使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

nginx 配置文件格式说明

配置文件由指令与指令块构成
每条指令以;分号结尾,指令与值之间以空格符号分隔
可以将多条指令放在同一行,用分号分隔即可,但可读性差,不推荐
指令块以{ }大括号将多条指令组织在一起,且可以嵌套指令块
include语句允许组合多个配置文件以提升可维护性
使用#符号添加注释,提高可读性
使用$符号使用变量
部分指令的参数支持正则表达式

Nginx 主配置文件的配置指令方式:  

main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
...
}
#http/https 协议相关配置段
http {
...
}
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}
#stream 服务器相关配置段
stream {
...

默认的nginx.conf 配置文件格式说明

#全局配置端,对全局生效,主要设置nginx的启动用户/组,启动的工作进程数量,工作模式,Nginx的PID路径,日志路径等。
user nginx nginx;
worker_processes 1; #启动工作进程数数量
events { #events 	#设置快,主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多
个网络连接,使用哪种事件驱动模型 #处理请求,每个工作进程可以同时支持的
最大连接数,是否开启对多工作进程下的网络连接进行序列化等。
worker_connections 1024; #设置单个nginx工作进程可以接受的最大并发,作为web服务器的时候最大并发数为 #worker_connections *
worker_processes,作为反向代理的时为  #(worker_connections * worker_processes)/2
}
http { 			#http块是Nginx服务器配置中的重要部分,缓存、代理和日志格式定义等绝大多数功能和第三方模块都 	#可以在这设置,http块可以包含多个server块,而一个server块中又可以包含多个location块
#server块可以配置文件引入、MIME-Type定义、日志自定义、是否启用sendfile、连接超时时间和 #单个链接的请求上限等。
include mime.types;
default_type application/octet-stream;
sendfile on; #作为web服务器的时候打开sendfile加快静态文件传输,指定是否使用
				#sendfile系统调用来传输文件
					#sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作)
						#从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝,
							#硬盘 >> kernel buffer (快速拷贝到kernelsocketbuffer) >>协议栈。
keepalive_timeout 65; #长连接超时时间,单位是秒
server { #设置一个虚拟机主机,可以包含自己的全局快,同时也可以包含多个location模块
			#比如本虚拟机监听的端口、本虚拟机的名称和IP配置,多个server 可以使用一个端口比如都使用 		#80端口提供web服务
listen 80; #配置server监听的端口
server_name localhost; #本server的名称,当访问此名称的时候nginx会调用当前serevr内部的配置进程匹配。
location / { #location其实是server的一个指令,为nginx服务器提供比较多而且灵活的指令
				#都是在location中体现的,主要是基于nginx接受到的请求字符串
					#对用户请求的UIL进行匹配,并对特定的指令进行处理
						#包括地址重定向、数据缓存和应答控制等功能都是在这部分实现
							#另外很多第三方模块的配置也是在location模块中配置。
root html; #相当于默认页面的目录名称,默认是安装目录的相对路径,可以使用绝对路径配置。
index index.html index.htm; #默认的页面文件名称
}
error_page 500 502 503 504 /50x.html; #错误页面的文件名称
location = /50x.html { #location处理对应的不同错误码的页面定义到/50x.html
						#这个跟对应其server中定义的目录下。
root html; 			#定义默认页面所在的目录
}
}
#和邮件相关的配置
#mail {
# ...
# } mail 协议相关配置段
#tcp代理配置,1.9版本以上支持
#stream {
# ...
# } stream 服务器相关配置段
#导入其他路径的配置文件
#include /apps/nginx/conf.d/*.conf
}

全局配置

Main 全局配置段常见的配置指令分类:

  • 正常运行必备的配置

  • 优化性能相关的配置

  • 用于调试及定位问题相关的配置

  • 事件驱动相关的配置

全局配置说明:

user nginx nginx; #启动Nginx工作进程的用户和组
worker_processes [number | auto]; #启动Nginx工作进程的数量,一般设为和CPU核心数相同
worker_cpu_affinity 00000001 00000010 00000100 00001000 | auto ;
#将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进
程独占以一核心CPU,但是可以保证此进程不运行在其他核心上,这就极大减少了nginx的工作进程在不同的
cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务
器的性能。
CPU MASK: 00000001:0号CPU
00000010:1号CPU
10000000:7号CPU

[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
user  nginx;
worker_processes  auto;
worker_cpu_affinity 0001 0010;

[root@nginx ~]# nginx -s reload
[root@nginx-node1 ~]# ps aux | grep nginx
root 42075 0.0 0.3 9876 6528 ? S 15:41 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
nobody 42076 0.0 0.2 14208 5124 ? S 15:41 0:00 nginx: worker
process
nobody 42077 0.0 0.2 14200 4868 ? S 16:30 0:00 nginx: worker
process
root 42079 0.0 0.1 221664 2176 pts/0 S+ 16:31 0:00 grep --
color=auto nginx

[root@nginx ~]# vim /etc/security/limits.conf
# 在文件末尾添加
nginx            -      nofile          100000

[root@nginx~]# sudo -u nginx ulimit -a
real-time non-blocking time  (microseconds, -R) unlimited
core file size              (blocks, -c) 0
data seg size               (kbytes, -d) unlimited
scheduling priority                 (-e) 0
file size                   (blocks, -f) unlimited
pending signals                     (-i) 14261
max locked memory           (kbytes, -l) 8192
max memory size             (kbytes, -m) unlimited
open files                          (-n) 100000
pipe size                (512 bytes, -p) 8
POSIX message queues         (bytes, -q) 819200
real-time priority                  (-r) 0
stack size                  (kbytes, -s) 8192
cpu time                   (seconds, -t) unlimited
max user processes                  (-u) 14261
virtual memory              (kbytes, -v) unlimited
file locks                          (-x) unlimited

[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
events {
    worker_connections  100000;  #修改会话连接数
}
[root@nginx ~]# nginx -s reload

[root@nginx-node1 ~]# dnf install httpd-tools -y
[root@nginx-node1 ~]# ab -n 10000 -c 500 http://172.25.254.100/index.html
This is ApacheBench, Version 2.3 <$Revision: 1903618 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 172.25.254.100 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        nginx/1.26.2
Server Hostname:        172.25.254.100
Server Port:            80

Document Path:          /index.html
Document Length:        615 bytes

Concurrency Level:      500
Time taken for tests:   0.496 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      8480000 bytes
HTML transferred:       6150000 bytes
Requests per second:    20146.79 [#/sec] (mean)
Time per request:       24.818 [ms] (mean)
Time per request:       0.050 [ms] (mean, across all concurrent requests)
Transfer rate:          16684.06 [Kbytes/sec] received

root 与 alias

[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
#gzip  on;
    include "/usr/local/nginx/conf.d/*.conf";  #包含子配置文件
    
[root@nginx ~]# mkdir -p /usr/local/nginx/conf.d
[root@nginx ~]# vim /usr/local/nginx/conf.d/kaolo.conf
server {
    listen 80;
    server_name www.kaolo.com;
    root /www/html;
    index index.html;
}
[root@nginx ~]# mkdir -p /www/html
[root@nginx ~]# echo Nginx - www.kaolo.com > /www/html/index.html
[root@nginx ~]# 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
#在Windows上添加解析
172.25.254.100 www.kaolo.com
#浏览器测试

Nginx 高级配置

Nginx 状态页

Active connections: 291
server accepts handled requests
16630948 16630948 31070465
上面三个数字分别对应accepts,handled,requests三个值
Reading: 6 Writing: 179 Waiting: 106
Active connections: #当前处于活动状态的客户端连接数
#包括连接等待空闲连接数=reading+writing+waiting

accepts: #统计总值,Nginx自启动后已经接受的客户端请求连接的总数。

handled: #统计总值,Nginx自启动后已经处理完成的客户端请求连接总数,通常等于accepts,除非有因worker_connections限制等被拒绝的连接

requests: #统计总值,Nginx自启动后客户端发来的总的请求数

Reading: #当前状态,正在读取客户端请求报文首部的连接的连接数,数值越大,说明排队现象严重,性能不足

Writing: #当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明访问量很大

Waiting: #当前状态,正在等待客户端发出请求的空闲连接数
开启 keep-alive的情况下,这个值等于active –(reading+writing)

#注意要做本地解析 www.kaolo.com
[root@nginx html]# cat /usr/local/nginx/conf.d/kaolo.conf 
server {
	listen 80;
	server_name www.kaolo.com;
	root /www/html;
	index index.html;

	location /kaolo {
		stub_status;
		allow 172.25.254.1;
		deny all;
	}
}

 

Nginx 压缩功能

Nginx支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文 件大小将比源文件显著变小,样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相 应的CPU资源。

Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module,默认是内置模块

[root@nginx ~]# cat /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;
#########################


[root@nginx conf.d]# echo hello kaolo > /www/html/small.html
[root@nginx conf.d]# du -sh /usr/local/nginx/logs/access.log 
72K	/usr/local/nginx/logs/access.log
[root@nginx conf.d]# cat /usr/local/nginx/logs/access.log > /www/html/big.html
[root@nginx conf.d]# nginx -s reload 重新加载nginx服务

[root@nginx html]# curl --head --compressed 172.25.254.100/small.html
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Fri, 16 Aug 2024 08:32:11 GMT
Content-Type: text/html
Content-Length: 3
Last-Modified: Fri, 16 Aug 2024 08:31:19 GMT
Connection: keep-alive
ETag: "66bf0e57-3"
Accept-Ranges: bytes

[root@nginx html]# curl --head --compressed 172.25.254.100/big.html
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Fri, 16 Aug 2024 08:32:19 GMT
Content-Type: text/html
Last-Modified: Fri, 16 Aug 2024 08:20:27 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: W/"66bf0bcb-11518"
Content-Encoding: gzip

Nginx 变量使用

  • nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用 ;

  • 变量可以分为内置变量和自定义变量 ;

  • 内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。

[root@nginx conf.d]# cat var.conf 
server {
	listen 80;
	server_name var.kaolo.com;
	root /www/html;
	index index.html;

	location /var {
		default_type test/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;
	}
}




[root@nginx conf.d]#  curl -b "key1=lee,key2=lee1" -u lee:lee var.kaolo.com/var?name=lee&&id=6666
172.25.254.100
name=lee
?
/www/html
/var
var.kaolo.com
34618
lee
GET
/www/html/var
/var?name=lee
http
HTTP/1.1
172.25.254.100
var.kaolo.com
80
curl/7.76.1
key1=lee,key2=lee1
lee1

自定义变量

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

语法格式:

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

示例:

[root@nginx conf.d]# cat var1.conf 
server {
	server_name xixi.kaolo.com;
	root /www/html;
	index index.html;

	location /var {
		default_type text/html;
		set $kaolo Sons1;
		echo $kaolo;
	}
}

[root@nginx conf.d]# curl xixi.kaolo.com/var
Sons1

if判定

用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行 配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:

if (条件匹配) {
action
}

使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间 使用以下符号链接:  

= 	#比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= 	#比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ 	#区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ 	#区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* 	#不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* 	#不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false
[root@nginx conf.d]# cat var.conf 
server {
	listen 80;
	server_name var.kaolo.com;
	root /www/html;
	index index.html;
	
  	location /test2 {
    	if (!-e $request_filename) {
        	echo "$request_filename is not exist.";
    }
    }
}


[root@nginx conf.d]# curl var.kaolo.com/test2/index.html
/www/html/test2/index.html is not exist.

set 指令

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

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

break 指令

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

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

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

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

使用语法如下:

[root@nginx conf.d]# cat var.conf 
server {
	listen 80;
	server_name var.kaolo.com;
	root /www/html;
	index index.html;
    location /break {
    default_type text/html;
        set $name Sons1;
        echo $name;
   if ( $http_user_agent = "curl/7.76.1" ){
            break;
        }
        set $id 1111111111111;
        echo $id;
    }



[root@nginx conf.d]# curl var.kaolo.com/break
Sons1

[root@nginx conf.d]# curl -A "firefox" var.kaolo.com/break
Sons1
1111111111111

return 指令

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

语法格式:

return code;         #返回给客户端指定的HTTP状态码
return code [text];     #返回给客户端的状态码及响应报文的实体内容
                        #可以调用变量,其中text如果有空格,需要用单或双引号
return code URL;             #返回给客户端的URL地址

[root@nginx conf.d]# cat var.conf 
server {
	listen 80;
	server_name var.kaolo.com;
	root /www/html;
	index index.html;
	
     location /return {
        default_type text/html;
        if ( !-e $request_filename){
            return 301 http://www.baidu.com;
        }
        echo "$request_filename is exist";
    }



[root@nginx conf.d]# curl -I var.kaolo.com/return
HTTP/1.1 301 Moved Permanently
Server: nginx/1.26.1
Date: Sun, 18 Aug 2024 06:05:25 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://www.baidu.com


[root@nginx conf.d]# mkdir -p /www/html/return
[root@nginx conf.d]# curl -I var.kaolo.com/return
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Sun, 18 Aug 2024 06:08:48 GMT
Content-Type: text/html
Connection: keep-alive
Vary: Accept-Encoding

rewrite 指令

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

法格式 :

rewrite regex replacement [flag];

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

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

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

正则表达式格式

. #匹配除换行符以外的任意字符
\w #匹配字母或数字或下划线或汉字
\s #匹配任意的空白符
\d #匹配数字
\b #匹配单词的开始或结束
^ #匹配字付串的开始
$ #匹配字符串的结束
* #匹配重复零次或更多次
+ #匹配重复一次或更多次
? #匹配重复零次或一次
(n) #匹配重复n次
{n,} #匹配重复n次或更多次
{n,m} #匹配重复n到m次
*? #匹配重复任意次,但尽可能少重复
+? #匹配重复1次或更多次,但尽可能少重复
?? #匹配重复0次或1次,但尽可能少重复
{n,m}? #匹配重复n到m次,但尽可能少重复
{n,}? #匹配重复n次以上,但尽可能少重复
\W #匹配任意不是字母,数字,下划线,汉字的字符
\S #匹配任意不是空白符的字符
\D #匹配任意非数字的字符
\B #匹配不是单词开头或结束的位置
[^x] #匹配除了x以外的任意字符
[^lee] #匹配除了magedu 这几个字母以外的任意字符

rewrite flag 使用介绍

利用nginx的rewrite的指令,可以实现url的重新跳转,rewrite有四种不同的flag,分别是redirect(临时 重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型

  • 跳转型指由客户端浏览器重新对新地址进行请求;

  • 代理型是在WEB服务器内部实现跳转。

rewrite 格式

Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据
包。
Default: —
Context: server, location, if

flag 说明

redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302

permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求,状态码:301

break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作
#而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在location中使用
#适用于一个URL一次重写

last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,
#而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户

rewrite案例: 域名永久与临时重定向

域名的临时的调整,后期可能会变,之前的域名或者URL可能还用、或者跳转的目的域名和URL还会跳 转,这种情况浏览器不会缓存跳转,临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存。

示例: 因业务需要,将访问源域名 www.kaolo.org 的请求永久重定向到 www.kaolo.com

location / {
root /www/html/pc;
index index.html;
rewrite / http://www.kaolo.com permanent;
#rewrite / http://www.kaolo.com redirect;
}
#重启Nginx并访问域名 http://www.kaolo.org 进行测试

rewrite案例: 自动跳转 https

案例:基于通信安全考虑公司网站要求全站 https,因此要求将在不影响用户请求的情况下将http请求全 部自动跳转至 https,另外也可以实现部分 location 跳转

[root@nginx nginx]# mkdir -p /usr/local/nginx/certs
[root@nginx nginx]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/nginx/certs/kaolo.key -x509 -days 365 -out /usr/local/nginx/certs/kaolo.crt


[root@nginx conf.d]# cat exam.conf
server {
    listen 80;
    listen 443 ssl;
    server_name www.kaolo.com;
    root /www/html;
    index index.html;
    ssl_certificate /usr/local/nginx/certs/kaolo.crt;
    ssl_certificate_key /usr/local/nginx/certs/kaolo.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    location / {
        if ( $scheme = http ){
            rewrite / https://$host redirect; #当$scheme = http时 让https去访问
        }
    }

}

[root@nginx conf.d]# cat exam.conf
server {
    listen 80;
    listen 443 ssl;
    server_name www.kaolo.com;
    root /www/html;
    index index.html;
    ssl_certificate /usr/local/nginx/certs/kaolo.crt;
    ssl_certificate_key /usr/local/nginx/certs/kaolo.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    location / {
        if ( $scheme = http ){
            rewrite / https://$host redirect; #当$scheme = http时 让https去访问
        }
    }
     location / {
        if ( $scheme = http ){
            rewrite /(.*) https://$host/$1 redirect; #(.*)一个元素 $1第一行的第一个元素(.*)
        }
    }

server {
    listen 80;
    listen 443 ssl;
    server_name www.kaolo.com;
    root /www/html;
    index index.html;
    ssl_certificate /usr/local/nginx/certs/kaolo.crt;
    ssl_certificate_key /usr/local/nginx/certs/kaolo.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    
    location / {
        if ( $scheme = http ){
            rewrite /(.*) https://$host/$1 redirect;
        }
    }
        if ( !-e $request_filename ){
           rewrite /(.*) https://$host/index.html redirect; #为了不让乱访问路径让他转到https://$host/index.html
       }
        
}  

Nginx 防盗链

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标 记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗 链,referer就是之前的那个网站域名,正常的referer信息有以下几种:

 none: #请求报文首部没有referer首部,
#比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked: #请求报文有referer首部,但无有效值,比如为空。
server_names: #referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string: #自定义指定字符串,但可使用*作通配符。示例: *.kaolo.org
www.kaolo.*
regular expression: #被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:
~.*\.kaolo\.com

#注意我用了两台虚机实现的盗链过程 nginx apache
#没做盗链之前
[root@nginx conf.d]# mkdir -p /www/html/images


[root@nginx conf.d]# cat exam.conf 
server {
	listen 80;
	listen 443 ssl;
	server_name www.kaolo.com;
	root /www/html;
	index index.html;
	ssl_certificate /usr/local/nginx/certs/kaolo.crt;
    ssl_certificate_key /usr/local/nginx/certs/kaolo.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

	location /images {
		
	}   	
}

#拉两张图片到不同路径下
[root@nginx html]# ls
big.html  images      index.html.1  return      sons1
error     index.html  `Mlv.png`      small.html

[root@nginx images]# ls
`Cx.png`

[root@apache1 ~]# cat /var/www/html/index.html 
<html>

  <head>
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <title>盗链</title>
</head>

  <body>
    <img src="http://www.kaolo.com/images/Cx.png" >
    <h1 style="color:red">欢迎大家</h1>
    <p><a href=http://www.kaolo.com>Sons1</a>出门见喜</p>
  </body>

</html>

 

#做防盗链之后
[root@nginx conf.d]# cat exam.conf 
server {
	listen 80;
	listen 443 ssl;
	server_name www.kaolo.com;
	root /www/html;
	index index.html;
	ssl_certificate /usr/local/nginx/certs/kaolo.crt;
    ssl_certificate_key /usr/local/nginx/certs/kaolo.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

	location /images {
		valid_referers none blocked server_names *.kaolo.com ~/.baidu/.;
    if ( $invalid_referer ){
        rewrite ^/   http://www.kaolo.com/Mlv.png;
	}	
}
}

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

实战案例: 反向代理单台 web 服务器

要求:将用户对域 www.kaolo.com 的请求转发给后端服务器处理

[root@apache1 + apache2 ~]# dnf install httpd -y
[root@apache1 + apache2 ~]# systemctl enable --now httpd
[root@apache1 ~]# echo apache - 172.25.254.10 > /var/www/html/index.html
[root@apache2 ~]# echo apache - 172.25.254.20 > /var/www/html/index.html

[root@nginx conf.d]# cat kaolo.conf 
server {
	listen 80;
	server_name www.kaolo.com;

	location / {
		proxy_pass http://172.25.254.10:80; #proxy_pass只能写一个
	}
}
#测试
[C:\~]$ curl www.kaolo.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0   2973      0 --:--:-- --:--:-- --:--:--  3833
apache - 172.25.254.10

实战案例: 指定 location 实现反向代理

[root@nginx conf.d]# cat kaolo.conf 
server {
	listen 80;
	server_name www.kaolo.com;

	location / {
		proxy_pass http://172.25.254.10:80;
	}

	location /static {
		proxy_pass http://172.25.254.20:8080;
	}
}
[root@nginx conf.d]# nginx -s reload

[root@apache2 conf]# mkdir /var/www/html/static -p
[root@apache2 conf]# echo static - 172.25.254.20 > /var/www/html/static/index.html

#改完apache2的监听端口记得重启httpd

[C:\~]$ curl www.kaolo.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0    803      0 --:--:-- --:--:-- --:--:--   851
apache - 172.25.254.10

[C:\~]$ curl www.kaolo.com/static/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0   3088      0 --:--:-- --:--:-- --:--:--  3833
static - 172.25.254.20

实战案例: 动静分离

[root@nginx conf.d]# cat kaolo.conf 
server {
	listen 80;
	server_name www.kaolo.com;

	location ~ \.php$ {
		proxy_pass http://172.25.254.10:80;
	}

	location /static {
		proxy_pass http://172.25.254.20:8080;
	}
}
[root@nginx conf.d]# nginx -s reload


[root@apache1 ~]# dnf install php -y
[root@apache1 ~]# systemctl restart httpd 
[root@apache1 ~]# vim /var/www/html/index.php
[root@apache1 ~]# cat /var/www/html/index.php 
<?php
	phpinfo();
?>

反向代理示例: 缓存功能

准备缓存配置
#之前没缓存
[root@apache1 ~]# ab -n1000 -c100 http://www.kaolo.com/static/index.html #-n1000请求数量1000 -c同时间请求数量100
Concurrency Level:      100
Time taken for tests:   4.307 seconds
Complete requests:      1000
Failed requests:        708
   (Connect: 0, Receive: 0, Length: 708, Exceptions: 0)
Total transferred:      74168 bytes
HTML transferred:       33288 bytes
Requests per second:    103.17 [#/sec] (mean)
Time per request:       430.724 [ms] (mean)
Time per request:       4.307 [ms] (mean, across all concurrent requests)
Transfer rate:          16.82 [Kbytes/sec] received



[root@Nginx ~]# vim /usr/nginx/conf/nginx.conf

#gzip on;
proxy_cache_path /apps/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m
inactive=120s max_size=1g; #配置在nginx.conf http配置段

[root@nginx conf.d]# cat kaolo.conf 
server {
	listen 80;
	server_name www.kaolo.com;

	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 conf.d]# nginx -s reload

反向代理示例: 后端多台 web服务器

环境说明:

172.25.254.100 #Nginx 代理服务器
172.25.254.10 #后端web A,Apache部署
172.25.254.20 #后端web B,Apache部署

 部署后端 Apache服务器

[root@apache1 ~]# yum install httpd -y
[root@apache1 ~]# echo apache - 172.25.254.10 > /var/www/html/index.html
[root@apache1 ~]# systemctl enable --now httpd
[root@apache2 ~]# yum install httpd -y
[root@apache2 ~]# echo apache - 172.25.254.20 >> /var/www/html/index.html
[root@apache2 ~]# systemctl enable --now httpd
#访问测试
[root@nginx ~]# curl http://172.25.254.10
apache - 172.25.254.10
[root@nginx ~]# curl http://172.25.254.20
apache - 172.25.254.20

配置 nginx 反向代理

[root@nginx conf.d]# cat sons1.conf 
upstream webcluster {
	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.kaolo.com;
	
	location / {
		proxy_pass http://webcluster;
	}
}


[C:\~]$ curl www.kaolo.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0   3474      0 --:--:-- --:--:-- --:--:--  4600
apache - 172.25.254.10

[C:\~]$ curl www.kaolo.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0    702      0 --:--:-- --:--:-- --:--:--   741
apache - 172.25.254.20
[root@nginx conf.d]# cat sons1.conf 
upstream webcluster {
	ip_hash;	#调度到同个IP
	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.kaolo.com;
	
	location / {
		proxy_pass http://webcluster;
		
[C:\~]$ curl www.kaolo.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0   3490      0 --:--:-- --:--:-- --:--:--  4600
apache - 172.25.254.10

[C:\~]$ curl www.kaolo.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    23  100    23    0     0   3483      0 --:--:-- --:--:-- --:--:--  4600
apache - 172.25.254.10


#hash $request_uri consistent; #uri进行hash
[root@nginx conf.d]# cat sons1.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.100:80 backup;
}

server {
	listen 80;
	server_name www.kaolo.com;
	
	location / {
		proxy_pass http://webcluster;
	}
}

[root@apache1 + apache2 ~]# mkdir -p /var/www/html/static
[root@apache1 ~]# echo static - 172.25.254.10 > /var/www/html/static/index.html
[root@apache2 ~]# echo static - 172.25.254.20 > /var/www/html/static/index.html


[C:\~]$ curl www.kaolo.com/static/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--  100    23  100    23    0     0   3483      0 --:--:-- --:--:-- --:--:--  4600
static - 172.25.254.10

[C:\~]$ curl www.kaolo.com/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--  100    23  100    23    0     0   1941      0 --:--:-- --:--:-- --:--:--  2300
apache - 172.25.254.20


#hash $cookie_kaolo;	对cookie值进行hash
[root@nginx conf.d]# cat sons1.conf 
upstream webcluster {
	#ip_hash;
	#hash $request_uri consistent;
	hash $cookie_kaolo;
	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.kaolo.com;
	
	location / {
		proxy_pass http://webcluster;
	}
}



#对cookie值进行hash
[C:\~]$ curl -b "kaolo=1" www.kaolo.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--  100    23  100    23    0     0    863      0 --:--:-- --:--:-- --:--:--   920
apache - 172.25.254.10

[C:\~]$ curl -b "kaolo=2" www.kaolo.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--  100    23  100    23    0     0   3676      0 --:--:-- --:--:-- --:--:--  4600
apache - 172.25.254.20

	

实现 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负载均衡配置参数

[root@apache1 + apache2 ~]# dnf install  bind -y
[root@apache1 + apache2 ~]# vim /etc/named.conf

[root@apache1 ~]# vim /etc/named.rfc1912.zones 
zone "kaolo.com" IN {
        type master;
        file "kaolo.com.zone";
        allow-update { none; };
};

[root@apache1 named]# cp named.localhost kaolo.com.zone -p
[root@apache1 named]# cat kaolo.com.zone 
$TTL 1D
@	IN SOA	 ns.kaolo.com root.kaolo.com. (
					0	; serial
					1D	; refresh
					1H	; retry
					1W	; expire
					3H )	; minimum
	NS	ns.kaolo.com.
ns	A	172.25.254.10
www	A	172.25.254.10

[root@apache1 named]# systemctl start named
[root@apache1 named]# dig www.kaolo.com @172.25.254.10

; <<>> DiG 9.16.23-RH <<>> www.kaolo.com @172.25.254.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11926
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 7d3db08ddde64df00100000066c219a02e7695811439da32 (good)
;; QUESTION SECTION:
;www.kaolo.com.			IN	A

;; ANSWER SECTION:
www.kaolo.com.		86400	IN	A	172.25.254.10

;; Query time: 2 msec
;; SERVER: 172.25.254.10#53(172.25.254.10)
;; WHEN: Sun Aug 18 23:56:16 CST 2024
;; MSG SIZE  rcvd: 86

[root@apache1 named]# scp -p /etc/named.{conf,rfc1912.zones} root@172.25.254.20
[root@apache1 named]# scp -p /var/named/kaolo.com.zone  root@172.25.254.20:/var/named/kaolo.com.zone
[root@apache2 named]# ll
total 20
drwxrwx--- 2 named named   23 Aug 19 00:04 data
drwxrwx--- 2 named named   60 Aug 19 00:05 dynamic
-rw-r----- 1 root  root   193 Aug 19 00:03 kaolo.com.zone
-rw-r----- 1 root  named 2253 Nov 26  2021 named.ca
-rw-r----- 1 root  named  152 Nov 26  2021 named.empty
-rw-r----- 1 root  named  152 Nov 26  2021 named.localhost
-rw-r----- 1 root  named  168 Nov 26  2021 named.loopback
drwxrwx--- 2 named named    6 Nov 26  2021 slaves
#更改named所属组
[root@apache2 named]# chgrp named kaolo.com.zone 
[root@apache2 named]# systemctl restart named

[root@apache2 named]# dig www.kaolo.com @172.25.254.20

; <<>> DiG 9.16.23-RH <<>> www.kaolo.com @172.25.254.20
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32830
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 38494e5b0c79b68d0100000066c21c934e2c1f64dfa67517 (good)
;; QUESTION SECTION:
;www.kaolo.com.			IN	A

;; ANSWER SECTION:
www.kaolo.com.		86400	IN	A	172.25.254.20

;; Query time: 0 msec
;; SERVER: 172.25.254.20#53(172.25.254.20)
;; WHEN: Mon Aug 19 00:08:51 CST 2024
;; MSG SIZE  rcvd: 86

tcp负载均衡配置参数

tcp的负载均衡要写在http语句块之外

[root@nginx conf]# mkdir -p /usr/local/nginx/tcpconf.d
[root@nginx tcpconf.d]# cat dns.conf 
stream {				#定义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 {					#定义server
		listen 53 udp reuseport;
		proxy_timeout 20s;			#转发超时时间
		proxy_pass dns;

	}

}
[root@nginx ~]# 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 ~]# nginx -s reload

[root@nginx ~]# netstat -antlupe | grep 53
tcp        0      0 172.25.254.100:22       172.25.254.1:51058      ESTABLISHED 0          153921     45899/sshd: root [p 
udp        0      0 0.0.0.0:53              0.0.0.0:*                           0          178983     46800/nginx: master 
udp        0      0 0.0.0.0:5353            0.0.0.0:*                           70         22154      874/avahi-daemon: r 
udp6       0      0 :::5353                 :::*                                70         22155      874/avahi-daemon: r 
[root@nginx ~]# dig www.kaolo.com @172.25.254.100

; <<>> DiG 9.16.23-RH <<>> www.kaolo.com @172.25.254.100
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7441
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 89ba80d4585bf3610100000066c221fc2bf6888e34c817b7 (good)
;; QUESTION SECTION:
;www.kaolo.com.			IN	A

;; ANSWER SECTION:
www.kaolo.com.		86400	IN	A	172.25.254.10

;; Query time: 0 msec
;; SERVER: 172.25.254.100#53(172.25.254.100)
;; WHEN: Mon Aug 19 00:31:56 CST 2024
;; MSG SIZE  rcvd: 86

[root@nginx ~]# dig www.kaolo.com @172.25.254.100

; <<>> DiG 9.16.23-RH <<>> www.kaolo.com @172.25.254.100
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31938
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: db6e8b16d2fcc3d60100000066c22204a70670ca254f860b (good)
;; QUESTION SECTION:
;www.kaolo.com.			IN	A

;; ANSWER SECTION:
www.kaolo.com.		86400	IN	A	172.25.254.20

;; Query time: 0 msec
;; SERVER: 172.25.254.100#53(172.25.254.100)
;; WHEN: Mon Aug 19 00:32:04 CST 2024
;; MSG SIZE  rcvd: 86

负载均衡实例: MySQL

[root@apache1 + apache2 ~]# dnf install mariadb-server -y
[root@apache1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=10 #另外一个20
[root@apache1 ~]# systemctl start mariadb
[root@apache1 + apache2 ~]# mysql
MariaDB [(none)]> CREATE USER sons1@'%' identified by '123';
Query OK, 0 rows affected (0.001 sec)

MariaDB [(none)]> GRANT ALL ON *.* to kaolo@'%';
Query OK, 0 rows affected (0.001 sec)

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

	upstream mysql{
		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 3306;
		proxy_timeout 60s;
		proxy_pass mysql;
	}
	server {
		listen 53 udp reuseport;
		proxy_timeout 20s;
		proxy_pass dns;

	}

}
[root@nginx tcpconf.d]# nginx -s reload
[root@nginx tcpconf.d]# netstat -antlupe | grep 3306
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      0          179872     46800/nginx: master
#这里的不是mysql服务 要下载才能用mysql命令
[root@nginx tcpconf.d]# dnf install mariadb -y

[root@nginx tcpconf.d]# mysql -u sons1 -p -h 172.25.254.100
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          10 |
+-------------+
1 row in set (0.001 sec)

[root@nginx tcpconf.d]# mysql -u sons1 -p -h 172.25.254.100
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          20 |
+-------------+
1 row in set (0.001 sec)

实现 FastCGI

CGI的由来:

最早的Web服务器只能简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏 览器,也就是静态html文件,但是后期随着网站功能增多网站开发也越来越复杂,以至于出现动态技 术,比如像php(1995年)、java(1995)、python(1991)语言开发的网站,但是nginx/apache服务器并不 能直接运行 php、java这样的文件,apache实现的方式是打补丁,但是nginx缺通过与第三方基于协议实 现,即通过某种特定协议将客户端请求转发给第三方服务处理,第三方服务器会新建新的进程处理用户 的请求,处理完成后返回数据给Nginx并回收进程,最后nginx在返回给客户端,那这个约定就是通用网 关接口(common gateway interface,简称CGI),CGI(协议) 是web服务器和外部应用程序之间的接口 标准,是cgi程序和web服务器之间传递信息的标准化接口。

 

为什么会有FastCGI?

CGI协议虽然解决了语言解析器和 Web Server 之间通讯的问题,但是它的效率很低,因为 Web Server 每收到一个请求都会创建一个CGI进程,PHP解析器都会解析php.ini文件,初始化环境,请求结束的时候 再关闭进程,对于每一个创建的CGI进程都会执行这些操作,所以效率很低,而FastCGI是用来提高CGI性 能的,FastCGI每次处理完请求之后不会关闭掉进程,而是保留这个进程,使这个进程可以处理多个请 求。这样的话每个请求都不用再重新创建一个进程了,大大提升了处理效率。

什么是PHP-FPM?

  • PHP-FPM(FastCGI Process Manager:

  • FastCGI进程管理器)是一个实现了Fastcgi的程序,并且提供进程管理的功能。

  • 进程包括master进程和worker进程。master进程只有一个,负责监听端口,接受来自web server 的请求

  • worker进程一般会有多个,每个进程中会嵌入一个PHP解析器,进行PHP代码的处理。

FastCGI配置指令

Nginx基于模块ngx_http_fastcgi_module实现通过fastcgi协议将指定的客户端请求转发至php-fpm处理,其配置指令如下:

#转发请求到后端服务器,address为后端的fastcgi server的地址,可用位置:location, if in location
fastcgi_pass address:port;

#fastcgi默认的主页资源,示例:fastcgi_index index.php;
fastcgi_index name;

#设置传递给FastCGI服务器的参数值,可以是文本,变量或组合,可用于将Nginx的内置变量赋值给自定义key
fastcgi_param parameter value [if_not_empty];

fastcgi_param REMOTE_ADDR $remote_addr; #客户端源IP
fastcgi_param REMOTE_PORT $remote_port; #客户端源端口
fastcgi_param SERVER_ADDR $server_addr; #请求的服务器IP地址
fastcgi_param SERVER_PORT $server_port; #请求的服务器端口
fastcgi_param SERVER_NAME $server_name; #请求的server name

Nginx默认配置示例:
	location ~ \.php$ {
		root /scripts;
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #默认脚本路径
		#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params; #此文件默认系统已提供,存放的相对路径为prefix/conf
}

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

重新编译nginx

[root@nginx nginx-1.26.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --add-module=/root/echo-nginx-module-0.63 --add-module=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module-0.33 --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 

源码编译php

#利用yum解决php依赖
dnf install 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 ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel oniguruma-devel

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

php相关配置优化

[root@Nginx ~]# cd /usr/local/php/etc
[root@Nginx etc]# cp php-fpm.conf.default php-fpm.conf
[root@Nginx etc]# vim php-fpm.conf
去掉注释
pid = run/php-fpm.pid 	#指定pid文件存放位置

[root@Nginx etc]# cd php-fpm.d/
[root@Nginx php-fpm.d]# cp www.conf.default www.conf

#生成主配置文件
[root@Nginx php-fpm.d]# cd /root/php-8.3.9/
[root@Nginx php-8.3.9]# cp php.ini-production /usr/local/php/etc/php.ini
[root@Nginx ~]# vim /usr/local/php/etc/php.ini
[Date]
; Defines the default timezone used by the date functions
; https://php.net/date.timezone
date.timezone = Asia/Shanghai #修改时区


#生成启动文件
[root@Nginx ~]# cd /root/php-8.3.9/
[root@Nginx php-8.3.9]# cp sapi/fpm/php-fpm.service /lib/systemd/system/
[root@Nginx php-8.3.9]# vim /lib/systemd/system/php-fpm.service
# Mounts the /usr, /boot, and /etc directories read-only for processes invoked by
this unit.
#ProtectSystem=full #注释该内容

[root@Nginx php-8.3.9]# systemctl start php-fpm.service
[root@nginx ~]# netstat -antlupe | grep php
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      0          285350     199450/php-fpm: mas 

#准备php测试页面
[root@nginx ~]# mkdir -p /www/php
[root@nginx ~]# cat /www/php/index.php 
<?php
	phpinfo();
?>

Nginx配置转发

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

[root@nginx conf.d]# cat php.conf 
server {
	listen 80;
	server_name www.kaolo.com;
	root /www/html;
	index index.html;

	location ~ \.php$ {
		root /www/php;
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_index index.php;
		include fastcgi.conf;
	}
}
#重启Nginx并访问web测试
[root@Nginx ~]# nginx -s reload

 访问验证php测试页面

添加php环境变量

[root@nginx nginx]# vim ~/.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 bin]# pwd
/usr/local/php/bin
[root@nginx bin]# source ~/.bash_profile

php的动态扩展模块(php的缓存模块)

安装memcache模块

[root@nginx ~]# tar zxf memcache-8.2.tgz
[root@nginx ~]# cd memcache-8.2/
[root@nginx memcache-8.2]# yum install autoconf -y
[root@nginx memcache-8.2]# phpize
[root@nginx memcache-8.2]# ./configure && make && make install
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20230831/
[root@nginx memcache-8.2]# ls /usr/local/php/lib/php/extensions/no-debug-non-zts-
20230831/
memcache.so opcache.so

#复制测试文件到nginx发布目录中
[root@nginx memcache-8.2]# cp example.php memcache.php /www/php/
[root@nginx memcache-8.2]# vim /www/php/memcache.php
$VERSION='$Id$';

define('ADMIN_USERNAME','kaolo');       // Admin Username
define('ADMIN_PASSWORD','123');         // Admin Password
define('DATE_FORMAT','Y/m/d H:i:s');
define('GRAPH_SIZE',200);
define('MAX_ITEM_DUMP',50);

$MEMCACHE_SERVERS[] = '127.0.0.1:11211'; // add more as an array
#$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array

#配置php加载memcache模块
[root@nginx ~]# vim /usr/local/php/etc/php.ini
;extension=zip
extension=memcache
;zend_extension=opcache
[root@nginx ~]# systemctl reload php-fpm
[root@nginx no-debug-non-zts-20230831]# php -m | grep mem
memcache

#部署memcached
[root@nginx ~]# yum install memcached -y
[root@nginx ~]# systemctl enable --now memcached.service
[root@nginx ~]# netstat -antlupe | grep memcache
tcp        0      0 127.0.0.1:11211         0.0.0.0:*               LISTEN      980        180281     191583/memcached    
tcp6       0      0 ::1:11211               :::*                    LISTEN      980        180282     191583/memcached    

[root@nginx ~]# cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1,::1"

#性能对比
[root@nginx-node1 ~]#  ab -n500 -c10 http://www.kaolo.com/index.php
Concurrency Level: 10
Time taken for tests: 0.514 seconds
Complete requests: 500
Failed requests: 44
(Connect: 0, Receive: 0, Length: 44, Exceptions: 0)

[root@nginx-node1 ~]#  ab -n500 -c10 http://www.kaolo.com/index.php
Concurrency Level: 10
Time taken for tests: 0.452 seconds
Complete requests: 500
Failed requests: 0

php高速缓存

部署方法

在我们安装的nginx中默认不支持memc和srcache功能,需要借助第三方模块来让nginx支持此功能,所 以nginx需要重新编译

[root@nginx ~]# tar zxf srcache-nginx-module-0.33.tar.gz
[root@nginx ~]# vim /usr/local/nginx/conf.d/kaolo.conf
upstream memcache {
    server 127.0.0.1:11211;
    keepalive 512;
}

server {
    listen 80;
    server_name www.kaolo.com;
    root /www/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 172.25.254.100:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}
[root@nginx ~]# nginx -s reload

#测试结果
[root@nginx ~]# ab -n500 -c10 http://www.kaolo.com/index.php
Concurrency Level: 10
Time taken for tests: 0.255 seconds
Complete requests: 500
Failed requests: 0

nginx二次开发版本


[root@nginx ~]# dnf -yq install gcc pcre-devel openssl-devel perl
[root@nginx ~]# useradd -r -s /sbin/nologin nginx
[root@nginx ~]# cd /usr/local/src
[root@nginx src]# wget https://openresty.org/download/openresty-1.25.3.1.tar.gz
[root@nginx src]# tar zxf openresty-1.25.3.1.tar.gz
[root@nginx src]# cd openresty-1.25.3.1/
[root@nginx openresty-1.25.3.1]# ./configure \
--prefix=/usr/local/openresty \
--with-stream_realip_module \
--with-http_realip_module \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-http_sub_module \
--without-http_memcached_module \
--with-stream \
--with-stream_ssl_module 

[root@nginx openresty-1.25.3.1]# gmake -j2 && gmake install
[root@nginx openresty-1.25.3.1]# cd /usr/local/openresty/
[root@nginx openresty]# ls
bin  COPYRIGHT  luajit  lualib  nginx  pod  resty.index  site
[root@nginx openresty]# cd bin/
[root@nginx bin]# ls
md2pod.pl  nginx-xml2pod  openresty  opm  resty  restydoc  restydoc-index
[root@nginx bin]# ll
total 168
-rwxr-xr-x 1 root root 19435 Aug 19 19:23 md2pod.pl
-rwxr-xr-x 1 root root 15423 Aug 19 19:23 nginx-xml2pod
lrwxrwxrwx 1 root root    37 Aug 19 19:23 openresty -> /usr/local/openresty/nginx/sbin/nginx
-rwxr-xr-x 1 root root 63423 Aug 19 19:23 opm
-rwxr-xr-x 1 root root 33123 Aug 19 19:23 resty
-rwxr-xr-x 1 root root 1324 Aug 19 19:23 restydoc
-rwxr-xr-x 1 root root  8362 Aug 19 19:23 restydoc-index
[root@nginx-node1 bin]# vim ~/.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 bin]# source ~/.bash_profile
[root@nginx bin]# openresty 
[root@nginx bin]# netstat -antlulpe | grep 80
tcp        0      0 127.0.0.1:11211         0.0.0.0:*               LISTEN      980        180281     191583/memcached    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      0          227829     215315/nginx: maste 
tcp6       0      0 ::1:11211               :::*                    LISTEN      980        180282     191583/memcached    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值