目录
一.Web 服务基础介绍
Web 服务介绍
服务端 I/O 流程
- 磁盘I/O
磁盘 I/O 是进程向内核发起系统调用,请求磁盘上的某个资源比如是 html 文件或者图片,然后内核通过相应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存,如果是比较大的数据也需要等待时间。
机械磁盘的寻道时间、旋转延迟和数据传输时间: 寻道时间:是指磁头移动到正确的磁道上所花费的时间,寻道时间越短则I/O处理就越快,目前磁盘的寻道时间一般在3-15毫秒左右。 旋转延迟:是指将磁盘片旋转到数据所在的扇区到磁头下面所花费的时间,旋转延迟取决于磁盘的转速,通常使用磁盘旋转一周所需要时间的1/2之一表示,比如7200转的磁盘平均训传延迟大约为60*1000/7200/2=4.17毫秒,公式的意思为 (每分钟60秒*1000毫秒每秒/7200转每分/2),如果是15000转的则为60*1000/15000/2=2毫秒。 数据传输时间:指的是读取到数据后传输数据的时间,主要取决于传输速率,这个值等于数据大小除以传输速率,目前的磁盘接口每秒的传输速度可以达到600MB,因此可以忽略不计。 常见的机械磁盘平均寻道时间值: 7200转/分的磁盘平均物理寻道时间:9毫秒 10000转/分的磁盘平均物理寻道时间:6毫秒 15000转/分的磁盘平均物理寻道时间:4毫秒 常见磁盘的平均延迟时间: 7200转的机械盘平均延迟:60*1000/7200/2 = 4.17ms 10000转的机械盘平均延迟:60*1000/10000/2 = 3ms 15000转的机械盘平均延迟:60*1000/15000/2 = 2ms 每秒最大IOPS的计算方法: 7200转的磁盘IOPS计算方式:1000毫秒/(9毫秒的寻道时间+4.17毫秒的平均旋转延迟时 间)=1000/13.13=75.9 IOPS 10000转的磁盘的IOPS计算方式:1000毫秒/(6毫秒的寻道时间+3毫秒的平均旋转延迟时 间)=1000/9=111IOPS 15000转的磁盘的IOPS计算方式:15000毫秒/(4毫秒的寻道时间+2毫秒的平均旋转延迟时 间)=1000/6=166.6 IOPS
- 网络I/O : 一切皆文件,本质为对socket文件的读写。网络通信就是网络协议栈到用户空间进程的IO就是网络IO。
网络 I/O 处理过程获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求( 1-3 )构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成( 4 )返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端( 5-7 )不论磁盘和网络 I/O每次 I/O ,都要经由两个阶段:第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短
I/O 模型
网络 I/O 模型
- 阻塞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 模型 (asynchronous IO)
零拷贝
零拷贝字面上的意思包括两个,“零”和“拷贝”:
• “拷贝”:就是指数据从一个存储区域转移到另一个存储区域。
• “零” :表示次数为0,它表示拷贝数据的次数为0。
零拷贝指在进行数据 IO 时,数据在用户态下经历了零次 CPU 拷贝,并非不拷贝数据。通过减少数据传输过程中 内核缓冲区和用户进程缓冲区 间不必要的CPU数据拷贝 与 用户态和内核态的上下文切换次数,降低 CPU 在这两方面的开销,释放 CPU 执行其他任务,更有效的利用系统资源,提高传输效率,同时还减少了内存的占用,也提升应用程序的性能。
由于零拷贝在内核空间中完成所有的内存拷贝,可以最大化使用 socket 缓冲区的可用空间,从而提高了一次系统调用中处理的数据量,进一步降低了上下文切换次数。零拷贝技术基于 PageCache,而 PageCache 缓存了最近访问过的数据,提升了访问缓存数据的性能,同时,为了解决机械磁盘寻址慢的问题,它还协助 IO 调度算法实现了 IO 合并与预读(这也是顺序读比随机读性能好的原因),这进一步提升了零拷贝的性能。
传统的IO执行流程
传统的IO流程,包括read和write的过程。
- read:把数据从磁盘读取到内核缓冲区,再拷贝到用户缓冲区
- write:先把数据写入到socket缓冲区,最后写入网卡设备。
-
用户应用进程调用read函数,向操作系统发起IO调用,上下文从用户态转为内核态
DMA控制器把数据从磁盘中,读取到内核缓冲区。 -
CPU把内核缓冲区数据,拷贝到用户应用缓冲区,上下文从内核态转为用户态,read函数返回
-
用户应用进程通过write函数,发起IO调用,上下文从用户态转为内核态,CPU将用户缓冲区中的数据,拷贝到socket缓冲区
-
DMA控制器把数据从socket缓冲区,拷贝到网卡设备,上下文从内核态切换回用户态,write函数返回
DMA技术
DMA,英文全称是Direct Memory Access,即直接内存访问。DMA本质上是一块主板上独立的芯片,允许外设设备和内存存储器之间直接进行IO数据传输,其过程不需要CPU的参与。
DMA实现零拷贝流程如下:
1、用户应用进程调用read函数,向操作系统发起IO调用,进入阻塞状态,等待数据返回。
2、CPU收到指令后,对DMA控制器发起指令调度。
3、DMA收到IO请求后,将请求发送给磁盘;
4、磁盘将数据放入磁盘控制缓冲区,并通知DMA;
5、DMA将数据从磁盘控制器缓冲区拷贝到内核缓冲区。
6、DMA向CPU发出数据读完的信号,把工作交换给CPU,由CPU负责将数据从内核缓冲区拷贝到用户缓冲区。
7、用户应用进程由内核态切换回用户态,解除阻塞状态
可以发现,DMA做的事情很清晰啦,它主要就是帮忙CPU转发一下IO请求,以及拷贝数据。
sendfile实现的零拷贝
sendfile是Linux2.1内核版本后引入的一个系统调用函数。
sendfile表示在两个文件描述符之间传输数据,它是在操作系统内核中操作的,避免了数据从内核缓冲区和用户缓冲区之间的拷贝操作,因此可以使用它来实现零拷贝。
sendfile实现的零拷贝流程如下:
1、用户进程发起sendfile系统调用,上下文(切换1)从用户态转向内核态
2、DMA控制器,把数据从硬盘中拷贝到内核缓冲区。
3、CPU将读缓冲区中数据拷贝到socket缓冲区
4、DMA控制器,异步把数据从socket缓冲区拷贝到网卡,
5、上下文(切换2)从内核态切换回用户态,sendfile调用返回。
可以发现,sendfile实现的零拷贝,I/O发生了2次用户空间与内核空间的上下文切换,以及3次数据拷贝。其中3次数据拷贝中,包括了2次DMA拷贝和1次CPU拷贝。
sendfile+DMA scatter/gather实现的零拷贝
linux 2.4版本之后,对sendfile做了优化升级,引入SG-DMA技术,其实就是对DMA拷贝加入了scatter/gather操作,它可以直接从内核空间缓冲区中将数据读取到网卡。使用这个特点搞零拷贝,即还可以多省去一次CPU拷贝。
1、用户进程发起sendfile系统调用,上下文(切换1)从用户态转向内核态
2.、DMA控制器,把数据从硬盘中拷贝到内核缓冲区。
3.、CPU把内核缓冲区中的文件描述符信息(包括内核缓冲区的内存地址和偏移量)发送到socket缓冲区;
4.、DMA控制器根据文件描述符信息,直接把数据从内核缓冲区拷贝到网卡
5.、上下文(切换2)从内核态切换回用户态,sendfile调用返回。
可以发现,sendfile+DMA scatter/gather实现的零拷贝,I/O发生了2次用户空间与内核空间的上下文切换,以及2次数据拷贝。其中2次数据拷贝都是包DMA拷贝。这就是真正的 零拷贝(Zero-copy) 技术,全程都没有通过CPU来搬运数据,所有的数据都是通过DMA来进行传输的。
二.Nginx 架构和安装
1、Nginx概述
- 静态的web资源服务器html,图片,js,css,txt等静态资源
- http/https协议的反向代理
- 结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
- tcp/udp协议的请求转发(反向代理)
- imap4/pop3协议的反向代理
- 模块化设计,较好的扩展性
- 高可靠性
- 支持热部署:不停机更新配置文件,升级版本,更换日志文件
- 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
- event-driven,aio,mmap,sendfile
Nginx 的代码是由一个 核心 和一系列的 模块 组成。
1.1 核心
核心的功能如下:
主要用于提供 WebServer 的基本功能;
实现 Web 和 Mail 反向代理的功能;
还用于启用网络协议;
创建必要的运行时环境以及确保不同的模块之间平滑地进行交互。
模块
大多跟协议相关的功能和应用特有的功能都由 Nginx 模块实现。
这些功能模块大致可以分为:事件模块、阶段性处理器、输出过滤器、变量处理器、协议、upstream 和负载均衡几个类别,这些功能模块共同组成了 Nginx 的 http 功能。
其中:
事件模块主要用于提供 OS 独立的(不同操作系统的事件机制有所不同)事件通知机制,如 kqueue 或 epoll 等。
协议模块则负责实现 Nginx 通过 HTTP、TLS/SSL、SMTP、POP3 以及 IMAP 与对应的客户端建立会话。
在 Nginx 内部,进程间的通信是通过模块的 pipeline 或 chain 实现的。
nginx 进程介绍
(1)首先,每个 worker 进程都是从 master 进程 fork 过来,在 master 进程里面,先建立好需要 listen 的 socket(listenfd)之后,然后再 fork 出多个 worker 进程。
(2)所有 worker 进程的 listenfd 会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有 worker 进程会在注册 listenfd 读事件前抢 accept_mutex,抢到互斥锁的那个进程注册 listenfd 读事件,然后在读事件里调用 accept 接受该连接。
(3)当一个 worker 进程在 accept 这个连接之后,就开始读取请求、解析请求、处理请求。产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了
2、编译安装 Nginx
[root@apache hh]# vmset.sh ens160 172.25.254.100 nginx-node1.zf.org
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/2)
使用Xftp传输nginx的压缩包到虚拟机上
[root@nginx-node1 ~]# ls
anaconda-ks.cfg nginx-1.24.0.tar.gz
[root@nginx-node1 ~]# tar zxf nginx-1.24.0.tar.gz
[root@nginx-node1 ~]# ls
anaconda-ks.cfg nginx-1.24.0 nginx-1.24.0.tar.gz
[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 man README src
[root@nginx-node1 nginx-1.24.0]# dnf install gcc pcre-devel zlib-devel openssl-devel -y
[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]# ls
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README
[root@nginx-node1 nginx-1.24.0]# make -j2
[root@nginx-node1 nginx-1.24.0]# cd objs/
[root@nginx-node1 objs]# ls
autoconf.err nginx ngx_auto_config.h ngx_modules.c src
Makefile nginx.8 ngx_auto_headers.h ngx_modules.o
[root@nginx-node1 nginx-1.24.0]# make install
[root@nginx-node1 nginx-1.24.0]# useradd -s /sbin/nologin -M nginx
[root@nginx-node1 sbin]# id nginx
用户id=1001(nginx) 组id=1001(nginx) 组=1001(nginx)
[root@nginx-node1 sbin]# ll
总用量 5548
-rwxr-xr-x 1 root root 5679504 8月 15 14:06 nginx
[root@nginx-node1 sbin]# ./nginx #启动nginx
[root@nginx-node1 sbin]# ps aux | grep nginx
root 38374 0.0 0.0 9836 932 ? Ss 14:09 0:00 nginx: master process ./nginx
nginx 38375 0.0 0.1 13724 4704 ? S 14:09 0:00 nginx: worker process
root 38377 0.0 0.0 221680 2360 pts/1 S+ 14:10 0:00 grep
--color=auto nginx
[root@nginx-node1 sbin]# netstat -antlupe | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 76848 38374/nginx: master
访问测试:
关闭服务的方法:
[root@nginx-node1 nginx-1.24.0]# rm -fr /usr/local/nginx/
[root@nginx-node1 nginx-1.24.0]# make clean
rm -rf Makefile objs
[root@nginx-node1 nginx-1.24.0]# ls
auto CHANGES.ru configure html man src
CHANGES conf contrib LICENSE README
[root@nginx-node1 nginx-1.24.0]# vim auto/cc/gcc
#关闭debug功能
[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 ~]# du -sh /usr/local/nginx/sbin/nginx
1.2M /usr/local/nginx/sbin/nginx
[root@nginx-node1 nginx-1.24.0]# vim ~/.bash_profile #把nginx软件的命令执行路径添加到环境变量中
[root@nginx-node1 nginx-1.24.0]# 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
[root@nginx-node1 nginx-1.24.0]# source ~/.bash_profile
[root@nginx-node1 ~]# nginx
网页测试:
3、平滑升级和回滚
安装1.26.2版本的nginx的软件包
[root@nginx-node1 ~]# wget https://nginx.org/download/nginx-1.26.2.tar.gz
--2024-08-15 10:40:02-- https://nginx.org/download/nginx-1.26.2.tar.gz
正在解析主机 nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05:d014:5c0:2600::6, ...
正在连接 nginx.org (nginx.org)|3.125.197.172|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:1244789 (1.2M) [application/octet-stream]
正在保存至: “nginx-1.26.2.tar.gz”
nginx-1.26.2.tar.gz 100%[====================>] 1.19M 47.3KB/s 用时 28s
2024-08-15 11:40:31 (43.7 KB/s) - 已保存 “nginx-1.26.2.tar.gz” [1244789/1244789])
[root@nginx-node1 ~]# ls
anaconda-ks.cfg nginx-1.24.0 nginx-1.24.0.tar.gz nginx-1.26.2.tar.gz
p传输echo的压缩包到虚拟机上
[root@nginx-node1 ~]# ls
anaconda-ks.cfg nginx-1.24.0 nginx-1.26.2.tar.gz
echo-nginx-module-0.63.tar.gz nginx-1.24.0.tar.gz
[root@nginx-node1 ~]# tar zxf echo-nginx-module-0.63.tar.gz
[root@nginx-node1 ~]# tar zxf nginx-1.26.2.tar.gz
[root@nginx-node1 ~]# ls
anaconda-ks.cfg nginx-1.24.0 nginx-1.26.2.tar.gz
echo-nginx-module-0.63 nginx-1.24.0.tar.gz
echo-nginx-module-0.63.tar.gz nginx-1.26.2
[root@nginx-node1 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_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.2]# make
#隐藏nginx版本号
[root@nginx-node1 nginx-1.24.0]# cd src/
[root@nginx-node1 src]# cd core/
[root@nginx-node1 core]# vim nginx.h
#把之前的旧版的nginx命令备份
[root@nginx-node1 nginx-1.26.2]# ls
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README
[root@nginx-node1 objs]# cd /usr/local/nginx/sbin/
[root@nginx-node1 sbin]# ls
nginx
[root@nginx-node1 sbin]# cp nginx nginx.bak
[root@nginx-node1 sbin]# ls
nginx nginx.bak
#把新版本的nginx命令复制过去
[root@nginx-node1 sbin]# \cp -f /root/nginx-1.26.2/objs/nginx /usr/local/nginx/sbin/nginx
[root@nginx-node1 sbin]# ps ax | grep nginx
root 38374 0.0 0.0 9836 2612 ? Ss 14:09 0:00 nginx: master process ./nginx
nginx 38375 0.0 0.1 13724 5296 ? S 14:09 0:00 nginx: worker process
root 45466 0.0 0.0 221680 2344 pts/2 S+ 16:01 0:00 grep --color=autonginx
[root@nginx-node1 sbin]# pidof nginx
38375 38374
[root@nginx-node1 sbin]# kill -USR2 38375
[root@nginx-node1 sbin]# ps aux | grep nginx
root 38374 0.0 0.0 9836 2612 ? Ss 14:09 0:00 nginx: master process ./nginx
nginx 38375 0.0 0.1 13724 5296 ? S 14:09 0:00 nginx: worker process
root 39004 0.0 0.0 9936 2612 ? S 14:09 0:00 nginx: master process ./nginx
nginx 39005 0.0 0.1 13724 5496 ? S 16:07 0:00 nginx: worker process
root 45480 0.0 0.0 221680 2356 pts/2 S+ 16:08 0:00 grep --color=autonginx
#回收旧版本
[root@nginx-node1 sbin]# kill -WINCH 38374
[root@nginx-node1 sbin]# ps aux | grep nginx
root 38374 0.0 0.0 9836 2612 ? Ss 14:09 0:00 nginx: master process ./nginx
root 39004 0.0 0.0 9936 4711? S 14:09 0:00 nginx: master process
nginx 39005 0.0 0.1 13724 5496 ? S 16:07 0:00 nginx: worker process
root 45483 0.0 0.0 221680 2312 pts/2 S+ 16:14 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]# kill -HUP 38374
[root@nginx-node1 sbin]# ps aux | grep nginx
root 38374 0.0 0.0 9836 2612 ? Ss 14:09 0:00 nginx: master process ./nginx
root 39004 0.0 0.0 9936 4711? S 14:09 0:00 nginx: master process
nginx 39005 0.0 0.1 13724 5496 ? S 14:09 0:00 nginx: worker process
nginx 39014 0.0 0.1 13700 5490 ? S 16:14 0:00 nginx: worker process
root 45483 0.0 0.0 221680 2312 pts/2 S+ 16:14 0:00 grep --color=auto nginx
#回滚:如果升级的版本发现问题需要回滚,可以重新拉起旧版本的worker
[root@nginx-node1 sbin]# cp nginx nginx.new
[root@nginx-node1 sbin]# ls
nginx nginx.new nginx.old
[root@nginx-node1 sbin]# \cp -f nginx.old nginx
[root@nginx-node1 sbin]# ls
nginx nginx.new nginx.old
[root@nginx-node1 sbin]# kill -9 38374
三、Nginx的全局配置
相关参数
-?,-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: /etc/nginx/) #指定Nginx 目录
-c filename : set configuration file (default: /etc/nginx/nginx.conf) #配置文件路径
-g directives : set global directives out of configuration file #设置全局指令,注意和配置文件不要同时配置,否则冲突
示例:
#获取nginx版本信息
[root@nginx-node1 ~]# nginx -V
nginx version: zf/1.0
built by gcc 11.3.1 20220421 (Red Hat 11.3.1-2) (GCC)
built with OpenSSL 3.0.1 14 Dec 2021
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
#检查nginx配置文件的语法
[root@nginx-node1 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-node1 nginx-1.24.0]# nginx -s reload
[root@nginx-node1 nginx-1.24.0]# ps aux | grep nginx
root 38217 0.0 0.0 9836 3556 ? Ss 20:39 0:00 nginx: master process nginx
nginx 38226 0.0 0.1 13736 5000 ? S 20:42 0:00 nginx: worker process
root 38228 0.0 0.0 221680 2360 pts/1 S+ 20:42 0:00 grep --color=auto nginx
#Nginx 会启动 6 个工作进程来处理请求
[root@nginx-node1 nginx-1.24.0]# nginx -s stop
[root@nginx-node1 nginx-1.24.0]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node1 nginx-1.24.0]# nginx -g "worker_processes 6;"
Nginx 启动文件
[root@nginx-node1 sbin]# vim /lib/systemd/system/nginx.service
[root@nginx-node1 sbin]# systemctl daemon-reload
[root@nginx-node1 sbin]# nginx -s stop
[root@nginx-node1 sbin]# ps aux | grep nginx
root 38334 0.0 0.0 221680 2332 pts/1 S+ 20:55 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]# systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@nginx-node1 sbin]# ps aux | grep nginx
root 38359 0.0 0.0 9836 928 ? Ss 20:56 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 38360 0.0 0.1 13724 4792 ? S 20:56 0:00 nginx: worker process
root 38362 0.0 0.0 221680 2320 pts/1 S+ 20:56 0:00 grep --color=auto nginx
Nginx全局配置参数优化调整
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node1 logs]# 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) 14260
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
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) 14260
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
#修改所有worker进程能打开的文件数量上限
[root@nginx-node1 logs]# vim /etc/security/limits.conf
[root@nginx-node1 logs]# 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) 14260
max locked memory (kbytes, -l) 64
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) 14260
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
实现 nginx 的高并发配置
[root@nginx-node1 logs]#dnf install httpd-tools -y #安装压缩工具
[root@nginx-node1 logs]# ab -n 10000 -c 500 http://172.25.254.100/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 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.24.0
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.470 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 8480000 bytes
HTML transferred: 6150000 bytes
Requests per second: 21254.35 [#/sec] (mean)
Time per request: 23.525 [ms] (mean)
Time per request: 0.047 [ms] (mean, across all concurrent requests)
Transfer rate: 17601.26 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 11 3.0 11 19
Processing: 2 12 3.7 12 24
Waiting: 0 8 3.6 8 22
Total: 3 23 3.7 23 35
Percentage of the requests served within a certain time (ms)
50% 23
66% 24
75% 25
80% 25
90% 27
95% 28
98% 29
99% 30
100% 35 (longest request
四、核心配置示例
新建一个 PC web 站点
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
[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 /date/web/html
[root@nginx-node1 ~]# echo www.zf.org > /date/web/html/index.html
[root@nginx-node1 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-node1 ~]# nginx -s reload
测试访问:
在C:\Windows\System32\drivers\etc 下添加解析地址
浏览器访问:
root 与 alias
root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location
root示例
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# mkdir -p /data/web/test1
[root@nginx-node1 ~]# echo /data/web/test1 > /data/web/test1/index.html
[root@nginx-node1 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-node1 ~]# nginx -s reload
网页测试:
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
网页测试:
location 的详细使用
#语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }
= #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求
^~ #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头
#对uri的最左边部分做匹配检查,不区分字符大小写
~ #用于标准uri前,表示包含正则表达式,并且区分大小写
~* #用于标准uri前,表示包含正则表达式,并且不区分大写
不带符号 #匹配起始于此uri的所有的uri
\ #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号
#匹配优先级从高到低:
=, ^~, ~/~*, 不带符号
①不带符号
#匹配起始于此uri的所有的uri
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# mkdir /data/web/test -p
[root@nginx-node1 ~]# echo test page > /data/web/test/index.html
[root@nginx-node1 ~]# nginx -s reload
网页测试:
② =
#用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求
网页测试:
[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
网页测试:
③^~
#用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头
[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/lee
[root@nginx-node1 ~]# echo lee > /data/web1/lee/index.html
[root@nginx-node1 ~]# nginx -s reload
访问测试:只有以"t"开头,才能访问成功
④~
#用于标准uri前,表示包含正则表达式,并且区分大小写
网页测试:
⑤~*
#用于标准uri前,表示包含正则表达式,并且不区分大写
网页测试:
⑥\
#用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# echo index.lee > /data/web1/lee/index.lee
[root@nginx-node1 ~]# nginx -s reload
网页测试:
⑦匹配优先级
从高到低: =, ^~, ~/~*, 不带符号
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# nginx -s reload
[root@nginx-node1 ~]# mkdir -p /data/web{1..5}
[root@nginx-node1 ~]# mkdir -p /data/web{1..5}/test
[root@nginx-node1 ~]# echo web1 > /data/web1/test/index.html
[root@nginx-node1 ~]# echo web2 > /data/web2/test/index.html
[root@nginx-node1 ~]# echo web3 > /data/web3/test/index.html
[root@nginx-node1 ~]# echo web4 > /data/web4/test/index.html
[root@nginx-node1 ~]# echo web5 > /data/web5/test/index.html
网页测试:可知~优先级最高
注释掉~的location
Nginx 账户认证功能
[root@nginx-node1 ~]# htpasswd -cm /usr/local/nginx/.htpasswd admin
New password:
Re-type new password:
Adding password for user admin
[root@nginx-node1 ~]# htpasswd -m /usr/local/nginx/.htpasswd zf
New password:
Re-type new password:
Adding password for user zf
[root@nginx-node1 ~]# cat /usr/local/nginx/.htpasswd
admin:$apr1$wn0/Pth.$mig7wz/FvYfxmIV7QogFn/
zf:$apr1$J4.S8lLd$9PuFBD9TAPKKGti3BAl4..
[root@nginx-node1 ~]# mkdir /data/web/lee
[root@nginx-node1 ~]# echo lee > /data/web/lee/index.html
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# nginx -s reload
再次编辑主配置文件:
网页测试:
自定义错误页面
以下为访问报错的默认页面
[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 ~]# nginx -s reload
网页测试:
自定义错误日志
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# mkdir -p /var/log/zf.org
[root@nginx-node1 ~]# nginx -s reload
检测文件是否存在
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# nginx -s reload
长连接配置
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
测试:下载telnet软件包
[root@nginx-node1 ~]# dnf install telnet -y
[root@nginx-node1 ~]# telnet www.zf.org 80
Trying 64.190.63.222...
Connected to www.zf.org.
Escape character is '^]'.
HTTP/1.1 408 Request Time-out
Content-length: 110
Cache-Control: no-cache
Connection: close
Content-Type: text/html
<html><body><h1>408 Request Time-out</h1>
Your browser didn't send a complete request in time.
</body></html>
Connection closed by foreign host.
[root@nginx-node1 ~]# curl -v www.zf.org
* Trying 64.190.63.222:80...
* Connected to www.zf.org (64.190.63.222) port 80 (#0)
> GET / HTTP/1.1
> Host: www.zf.org
> User-Agent: curl/7.76.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< date: Fri, 16 Aug 2024 11:57:41 GMT
< content-type: text/html; charset=UTF-8
< transfer-encoding: chunked
< vary: Accept-Encoding
< expires: Mon, 26 Jul 1997 05:00:00 GMT
< cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< pragma: no-cache
< x-adblock-key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANnylWw2vLY4hUn9w06zQKbhKBfvjFUCsdFlb6TdQhxb9RXWXuI4t31c+o8fYOv/s8q1LGPga3DE1L/tHU4LENMCAwEAAQ==_zm2jGc26HiosLbMuTonf5NgXzUAklfI9JyXDmynEQNB2x6OUIPj1EzQzw5KevJKIU1/KuGx5oTlmdc73yQNi0w==
< last-modified: Fri, 16 Aug 2024 11:57:41 GMT
< x-cache-miss-from: parking-68fdcdc496-rgl2t
< server: Parking/1.0
<
作为下载服务器配置
[root@nginx-node1 ~]# mkdir /data/web/download
[root@nginx-node1 ~]# dd if=/dev/zero of=/data/web/download/leefile bs=1M count=100
记录了100+0 的读入
记录了100+0 的写出
104857600字节(105 MB,100 MiB)已复制,0.112032 s,936 MB/s
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
[root@nginx-node1 ~]# nginx -s reload
网页测试:
变更时间为本地时间
显示文件的粗略大小
限制文件下载速度
网页测试:
五、Nginx 高级配置
Nginx 状态页
[root@nginx-node1 ~]# cd /usr/local/nginx/conf.d/
[root@nginx-node1 conf.d]# vim status.conf
[root@nginx-node1 conf.d]# nginx -s reload
本机上添加解析:
网页测试:
指定用户登录
[root@nginx-node1 conf.d]# vim /etc/hosts;
[root@nginx-node1 conf.d]# curl status.zf.org/status/
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.24.0</center>
</body>
</html>
Nginx 压缩功能
开启压缩功能
[root@nginx-node1 conf.d]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-node1 ~]# mkdir /data/web/html/small.html
[root@nginx-node1 ~]# rm -fr /data/web/html/small.html
[root@nginx-node1 ~]# echo hello zf > /data/web/html/small.html
[root@nginx-node1 ~]# du -sh /usr/local/nginx/logs/
1.1M /usr/local/nginx/logs/
[root@nginx-node1 ~]# cat /usr/local/nginx/logs/ > /data/web/html/big.html
[root@nginx-node1 ~]# curl --head --compressed 172.25.254.100 /small.html
HTTP/1.1 200 OK
Server: nginx/1.26.2
Date: Sat, 17 Aug 2024 01:48:19 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Keep-Alive: timeout=60
[root@nginx-node1 ~]# curl --head --compressed 172.25.254.100 /big.html
HTTP/1.1 200 OK
Server: nginx/1.26.2
Date: Sat, 17 Aug 2024 01:49:45 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Keep-Alive: timeout=60
Content-Encoding:gzip
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为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有
横线需要替换为下划线
#示例:
echo $http_user_agent;
echo $http_host;
$sent_http_<name>
#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有
问题
echo $sent_http_server;
$arg_<name>
#此变量存放了URL中的指定参数,name为请求url中指定的参数
echo $arg_id;
详细配置:
nginx的内置变量
[root@nginx-node1 conf.d]# vim var.conf
[root@nginx-node1 conf.d]# nginx -s reload
测试命令
[root@nginx-node1 conf.d]#curl -b "key1=zf,key2=zf1" -u zf:lee var.zf.org/var?name=zf&&id=6666
"var.zf.org/var?search=zf&&id=666666"
172.25.254.100
search=zf&&id=666666
/data/web/html/zf.org/zf
/var
var.zf.org
curl/7.29.0
/data/web/nginx/zf.org/zf/var
http
http://var.zf.org/var?search=zf&&id=666666
title=zf;key1=var,key2=zf
zf
*/
六、Nginx Rewrite 相关功能
= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false
#if判定示例
[root@nginx-node1 conf.d]# vim var.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl var.zf.org/test2/index.html
/data/web/html/test2/index.html is not exsit.
测试时注释掉return 409;
#break示例
[root@nginx-node1 conf.d]# vim var.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl var.zf.org/break
zf
666
[root@nginx-node1 conf.d]# curl -A "firefox" var.zf.org/break
zf
666
#return示例
[root@nginx-node1 conf.d]# vim var.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl -I var.zf.org/return
HTTP/1.1 301 Moved Permanently
Server: nginx/1.26.2
Date: Sun, 18 Aug 2024 09:48:51 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Keep-Alive: timeout=60
Location: http://www.baidu.com
[root@nginx-node1 conf.d]# mkdir -p /data/web/html/return
[root@nginx-node1 conf.d]# curl -I var.zf.org/return
HTTP/1.1 200 OK
Server: nginx/1.26.2
Date: Sun, 18 Aug 2024 09:51:02 GMT
Content-Type: text/html
Connection: keep-alive
Keep-Alive: timeout=60
Vary: Accept-Encoding
#rewirte示例
[root@nginx-node1 conf.d]# vim var.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# curl -I var.zf.org
HTTP/1.1 301 Moved Permanently
Server: nginx/1.26.2
Date: Sun, 18 Aug 2024 09:54:15 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
Keep-Alive: timeout=60
Location: http://www.zf.com
先注释掉以下内容
打开一个注释:
[root@nginx-node1 conf.d]# curl var.zf.org
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.26.2</center>center>
</body>
</html>
浏览器访问:
#break 和last示例
[root@nginx-node1 conf.d]# vim var.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# mkdir /data/web/html/{test1,test2,break,last} -p
[root@nginx-node1 conf.d]# echo test1 > /data/web/html/test1/index.html
[root@nginx-node1 conf.d]# echo test2 > /data/web/html/test2/index.html
[root@nginx-node1 conf.d]# echo last > /data/web/html/last/index.html
[root@nginx-node1 conf.d]# echo break > /data/web/html/break/index.html
浏览器访问测试:
企业实战
#全站加密
[root@nginx-node1 nginx]# mkdir certs
[root@nginx-node1 nginx]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/nginx/certs/zf.org.key -x509 -days 365 -out /usr/local/nginx/certs/zf.org.crt
[root@nginx-node1 nginx]# cd /usr/local/nginx/certs
[root@nginx-node1 certs]# ls
zf.org.crt zf.org.key
[root@nginx-node1 conf.d]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
测试:
[root@nginx-node1 conf.d]# curl -I var.zf.org
HTTP/1.1 301 Moved Permanently
Server: nginx/1.26.2
Date: Sun, 18 Aug 2024 14:35:53 GMT
Content-Type: text/html
Content-Length: 147
Connection: keep-alive
Keep-Alive: timeout=60
Location: http://www.zf.org
自动跳转 https
七、Nginx 防盗链
[root@nginx-node1 conf.d]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 conf.d]# mkdir -p /data/web/html/images
[root@nginx-node1 conf.d]# ls /data/web/html/images
daolian.jpg
[root@web10 ~]# cd /var/www/html/
[root@web10 html]# vim index.html
[root@web10 html]# systemctl
八、Nginx 反向代理功能
反向代理 web 服务器
[root@nginx-node1 conf.d]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
重启nginx测试
非缓存场景压测及缓存配置
[root@web10 html]# ab -n1000 -c100 http://www.zf.org/static/index.html
Concurrency Level: 100
Time taken for tests: 3.238 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 281000 bytes
HTML transferred: 20100 bytes
Requests per second: 43.03 [#/sec] (mean)
Time per request: 283.789 [ms] (mean)
Time per request: 3.238 [ms] (mean, across all concurrent requests)
Transfer rate: 84521.97 [Kbytes/sec] received
[root@nginx-node1 conf.d]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
测试命令:
[root@web10 html]# ab -n1000 -c100 http://www.zf.org/static/index.html
http 反向代理负载均衡
相关参数
#ip_hash; 哈希算法
#hash $request_uri consistent; 哈希一致性
#hash $cookie_lee
#least_conn;
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
使用hash算法
在web服务器上添加172.25.254.100的解析,并访问测试
[root@web10 html]# vim /etc/hosts
[root@web10 html]# curl www.zf.org
172.25.254.10
使用hash $request_uri consistent
测试:
[C:\~]$ curl www.zf.org
172.25.254.20
[C:\~]$ curl www.zf.org
172.25.254.20
[root@web10 html]# mkdir -p /var/www/html/static
[root@web10 html]# echo 172.25.254.10 static > /var/www/html/static/index.html
测试:
[C:\~]$ curl www.zf.org/static/
172.25.254.10 static
[C:\~]$ curl www.zf.org/
172.25.254.20
使用hash $cookie_zf
测试:
[C:\~]$ curl -b "zf=1" www.zf.org
172.25.254.10
[C:\~]$ curl -b "zf=2" www.zf.org
172.25.254.20
tcp负载均衡配置
在2台web上安装DNS
[root@web10 html]# dnf install bind -y
[root@web20 html]# dnf install bind -y
编辑主配置文件
[root@web10 html]# vim /etc/named.conf
[root@web10 html]# vim /etc/named.rfc1912.zones
[root@web10 html]# cd /var/named
[root@web10 named]# cp named.localhost zf.org.zone -p
[root@web10 named]# vim zf.org.zone
[root@web10 named]# systemctl start named
[root@web10 named]# dig www.zf.org @172.25.254.10
; <<>> DiG 9.16.23-RH <<>> www.zf.org @172.25.254.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25353
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;www.zf.org. IN A
;; ANSWER SECTION:
www.zf.org. 23100 IN A 172.25.254.10
;; Query time: 564 msec
;; SERVER: 172.25.254.10#53(172.25.254.10)
;; WHEN: Sun Aug 18 19:56:54 CST 2024
;; MSG SIZE rcvd: 90
为另一台主机配置:
[root@web10 named]# scp -p /etc/named.{conf,rfc1912.zones} root@172.25.254.20:/etc
[root@web20 named]# ll /etc/named.conf
-rw-r----- 1 root named 1727 8月 18 20:01 /etc/named.conf
[root@web10 named]# ll /etc/named.rfc1912.zones
-rw-r----- 1 root named 1133 8月 18 20:02 /etc/named.rfc1912.zones
[root@web10 named]# scp -p /var/named/zf.org.zone root@172.25.254.20:/var/named/zf.org.zone
[root@web20 named]# vim /var/named/zf.org.zone
[root@web20 named]# systemctl start named
[root@nginx-node1 conf.d]# vim dns.conf
[root@nginx-node1 conf.d]# vim /usr/local/nginx/conf/nginx.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 -t
[root@nginx-node1 conf.d]# vim dns.conf
测试命令:
[root@nginx-node1 tcpconf.d]# dig www.zf.org @172.25.254.100
负载均衡实例: MySQL
安装数据库软件
[root@web10 named]# dnf install mariadb-server -y
[root@web20 named]# dnf install mariadb-server -y
[root@web10 named]# vim /etc/my.cnf.d/mariadb-server.cnf
[root@web20 named]# vim /etc/my.cnf.d/mariadb-server.cnf
[root@web10 named]# systemctl start mariadb
[root@web20 named]# systemctl start mariadb
在2台主机上做ssh登录
[root@nginx-node1 tcpconf.d]# vim dns.conf
[root@nginx-node1 tcpconf.d]# nginx -s reload
安装MySQL客户端
[root@nginx-node1 tcpconf.d]# dnf install mysql -y
连接MYSQL
[root@nginx-node1 tcpconf.d]# mysql -u zf -p -h 172.25.254.100
MariaDB [(none)]> SELECT @@server_id;
+-------------+
| @@server_id |
+-------------+
| 10 |
+-------------+
1 row in set (0.001 sec)
九、实现FastCGI
传统的 CGI(Common Gateway Interface)每次处理一个请求时都需要启动一个新的进程,这会带来较大的系统开销,尤其是在高并发的情况下,频繁地创建和销毁进程会严重影响服务器的性能。而 FastCGI 则采用了一种更为高效的方式,它启动一个或多个持久的进程来处理请求,这些进程可以在多个请求之间重复使用,避免了频繁启动新进程的开销,从而大大提高了服务器的性能和响应速度。
源码编译php
先上传相关软件包,并解压
添加相关模块,开始编译
[root@nginx-node1 ~]# cd nginx-1.24.0/
[root@nginx-node1 nginx-1.24.0]# ./configure --prefix=/usr/local/nginx \
> --add-module=/root/echo-nginx-module-0.63 \
> --add-module=/root/memc-nginx-module-0.20 \
> --add-module=/root/srcache-nginx-module-0.33 \
> --user=nginx \
> --group=nginx \
> --with-http_v2_module \
> --with-http_realip_module \
> --with-http_stub_status_module \
> --with-http_gzip_static_module \
> --with-stream \
> --with-stream_ssl_module \
> --with-stream_realip_module \
> --with-pcre
启动nginx,安装PHP
[root@nginx-node1 nginx-1.24.0]# systemctl start nginx
[root@nginx-node1 ~]# ls
anaconda-ks.cfg php-8.3.9
echo-nginx-module-0.63 php-8.3.9.tar.gz
echo-nginx-module-0.63.tar.gz srcache-nginx-module-0.33
memc-nginx-module-0.20 srcache-nginx-module-0.33.tar.gz
memc-nginx-module-0.20.tar.gz var.conf
nginx-1.24.0 vars.conf
openresty-1.25.3.1.tar.gz
[root@nginx-node1 ~]# cd php-8.3.9/
[root@nginx-node1 php-8.3.9]# dnf install systemd-devel -y
[root@nginx-node1 php-8.3.9]# dnf install libxml2-devel-2.9.13-2.el9.x86_64 -y
[root@nginx-node1 php-8.3.9]# dnf install sqlite-devel.x86_64 -y
[root@nginx-node1 php-8.3.9]# dnf install libcurl-devel-7.76.1-19.el9.x86_64 -y
[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]# cd /mnt/
[root@nginx-node1 mnt]# ls
hgfs oniguruma-devel-6.9.6-1.el9.5.x86_64.rpm
oniguruma-devel-6.9.6-1.el9.5.0.1.x86_64.rpm
[root@nginx-node1 mnt]# dnf install oniguruma-devel-6.9.6-1.el9.5.x86_64.rpm -y
[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
编译结果:
php的配置方法
[root@nginx-node1 ~]# 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]# vim php-fpm.conf
[root@nginx-node1 etc]# cd php-fpm.d/
[root@nginx-node1 php-fpm.d]# cp www.conf.default www.conf -p
[root@nginx-node1 php-fpm.d]# cd /root/php-8.3.9/
[root@nginx-node1 php-8.3.9]# ls
appveyor CONTRIBUTING.md Makefile.objects SECURITY.md
benchmark docs modules tests
build ext NEWS travis
buildconf EXTENSIONS pear TSRM
buildconf.bat include php.ini-development UPGRADING
CODING_STANDARDS.md libs php.ini-production UPGRADING.INTERNALS
config.log libtool README.md win32
config.nice LICENSE README.REDIST.BINS Zend
config.status main run-tests.php
configure Makefile sapi
configure.ac Makefile.fragments scripts
生成php的配置文件
[root@nginx-node1 php-8.3.9]# cp php.ini-production /usr/local/php/etc/php.ini
[root@nginx-node1 ~]# cd /usr/local/php/etc
[root@nginx-node1 etc]# vim php.ini
修改时区
生成启动文件
[root@nginx-node1 etc]# cd /root/php-8.3.9/
[root@nginx-node1 php-8.3.9]# ls
appveyor CONTRIBUTING.md Makefile.objects SECURITY.md
benchmark docs modules tests
build ext NEWS travis
buildconf EXTENSIONS pear TSRM
buildconf.bat include php.ini-development UPGRADING
CODING_STANDARDS.md libs php.ini-production UPGRADING.INTERNALS
config.log libtool README.md win32
config.nice LICENSE README.REDIST.BINS Zend
config.status main run-tests.php
configure Makefile sapi
configure.ac Makefile.fragments scripts
[root@nginx-node1 php-8.3.9]# cd sapi/
[root@nginx-node1 sapi]# cd fpm/
[root@nginx-node1 fpm]# ls
config.m4 init.d.php-fpm.in php-fpm.8 php-fpm.service tests
CREDITS LICENSE php-fpm.8.in php-fpm.service.in www.conf
fpm Makefile.frag php-fpm.conf status.html www.conf.in
init.d.php-fpm php-fpm php-fpm.conf.in status.html.in
[root@nginx-node1 fpm]# cp php-fpm.service /lib/systemd/system/
[root@nginx-node1 fpm]# vim /lib/systemd/system/php-fpm.service
[root@nginx-node1 fpm]# systemctl daemon-reload
[root@nginx-node1 fpm]# systemctl start php-fpm.service
[root@nginx-node1 fpm]# netstat -antlupe | grep php
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 0 184974 162872/php-fpm: mas
nginx和php的整合
php命令添加到环境变量
[root@nginx-node1 bin]# vim ~/.bash_profile
[root@nginx-node1 bin]# source ~/.bash_profile
[root@nginx-node1 ~]# mkdir -p /data/web/php
[root@nginx-node1 bin]# cd /data/web/php/
[root@nginx-node1 php]# ls
[root@nginx-node1 php]# vim index.php
[root@nginx-node1 nginx]# mkdir conf.d
[root@nginx-node1 nginx]# vim conf/nginx.conf
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -s reload
[root@nginx-node1 conf.d]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-node1 conf.d]# vim /usr/local/php/etc/php-fpm.d/www.conf
[root@nginx-node1 conf.d]# systemctl restart php-fpm.service
网页测试:
php的缓存优化
出现的问题:
[root@nginx-node1 ~]# ab -n1000 http://www.zf.org/index.php
配置php加载memcache模块
[root@nginx-node1 ~]# ls
anaconda-ks.cfg php-8.3.9
echo-nginx-module-0.63 php-8.3.9.tar.gz
echo-nginx-module-0.63.tar.gz srcache-nginx-module-0.33
memcache-8.2.tgz srcache-nginx-module-0.33.tar.gz
memc-nginx-module-0.20 var.conf
memc-nginx-module-0.20.tar.gz vars.conf
nginx-1.24.0 vhosts.conf
openresty-1.25.3.1.tar.gz
[root@nginx-node1 ~]# tar zxf memcache-8.2.tgz
[root@nginx-node1 ~]# cd memcache-8.2
[root@nginx-node1 memcache-8.2]# ls
config9.m4 CREDITS example.php README
config.m4 docker LICENSE src
config.w32 Dockerfile memcache.php tests
[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]# ls
autom4te.cache config.m4 CREDITS LICENSE src
build configure docker memcache.php tests
config9.m4 configure.ac Dockerfile README
config.h.in config.w32 example.php run-tests.php
执行编译
[root@nginx-node1 memcache-8.2]# ./configure && make && make install
[root@nginx-node1 memcache-8.2]# cd
[root@nginx-node1 ~]# cd /usr/local/php/lib/php/extensions/no-debug-non-zts-20230831/
[root@nginx-node1 no-debug-non-zts-20230831]# ls
memcache.so opcache.so
[root@nginx-node1 ~]# systemctl restart php-fpm.service
加载memcache模块
[root@nginx-node1 ~]# cd /usr/local/php/
[root@nginx-node1 php]# cd etc/
[root@nginx-node1 etc]# vim php.ini
[root@nginx-node1 etc]# systemctl restart php-fpm.service
[root@nginx-node1 lib]# cp /usr/local/php/etc/php.ini /usr/local/php/lib/
[root@nginx-node1 lib]# ls
php php.ini
[root@nginx-node1 lib]# php -m
[root@nginx-node1 etc]# dnf install memcached -y
[root@nginx-node1 etc]# vim /etc/sysconfig/memcached
[root@nginx-node1 etc]# systemctl restart memcached.service
[root@nginx-node1 etc]# netstat -antlupe | grep memcache
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 977 203594 168642/memcached
tcp6 0 0 ::1:11211 :::* LISTEN 977 203595 168642/memcached
[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]# ab -n1000 http://www.zf.org/index.php
逐渐减少:
php高速缓存
[root@nginx-node1 ~]# cd /usr/local/nginx/conf.d/
[root@nginx-node1 conf.d]# vim vhosts.conf
[root@nginx-node1 conf.d]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-node1 conf.d]# nginx -s reload
性能检测:
[root@nginx-node1 conf.d]# ab -n1000 http://www.zf.org/index.php
十、nginx 二次开发版本
先关闭nginx服务
[root@nginx-node1 ~]# systemctl stop nginx
[root@nginx-node1 ~]# netstat -antupe | grep nginx
[root@nginx-node1 ~]# ps aux |grep nginx
avahi 918 0.0 0.1 15520 5104 ? Ss 02:22 0:00 avahi-daemon: running [nginx-node1.local]
nginx 168377 0.0 0.4 264748 15060 ? S 13:36 0:00 php-fpm: pool www
nginx 168378 0.0 0.4 264748 15944 ? S 13:36 0:00 php-fpm: pool www
root 168854 0.0 0.0 221812 2328 pts/3 R+ 14:36 0:00 grep --color=auto nginx
安装openresty
[root@nginx-node1 ~]# tar zxf openresty-1.25.3.1.tar.gz
[root@nginx-node1 ~]# ls
anaconda-ks.cfg openresty-1.25.3.1.tar.gz
echo-nginx-module-0.63 package.xml
echo-nginx-module-0.63.tar.gz php-8.3.9
memcache-8.2 php-8.3.9.tar.gz
memcache-8.2.tgz srcache-nginx-module-0.33
memc-nginx-module-0.20 srcache-nginx-module-0.33.tar.gz
memc-nginx-module-0.20.tar.gz var.conf
nginx-1.24.0 vars.conf
openresty-1.25.3.1 vhosts.conf
编译openresty
[root@nginx-node1 ~]# cd openresty-1.25.3.1/
[root@nginx-node1 openresty-1.25.3.1]# ./configure --prefix=/usr/local/openresty \
> --with_http_realip_module \
> --with-http_sub_module \
> --with-http_gzip_static_module \
> --with-http_stub_status_module \
> --without-http_memcached_module \
> --with-stream \
> --with-stream_ssl_module \
> --with-stream_realip_module \
> --with-pcre \
> --with-http_ssl_module