目录
1.2.2.2.1 阻塞型 I/O 模型(blocking IO)
1.2.2.2.2 非阻塞型 I/O 模型 (nonblocking IO)
1.2.2.2.3 多路复用 I/O 型(I/O multiplexing)
1.2.2.2.4 信号驱动式 I/O 模型 (signal-driven IO)
1.2.2.2.5 异步 I/O 模型 (asynchronous IO)
1.3.2.1 MMAP ( Memory Mapping )
5.4.1 rewrite案例:域名永久与临时重定向(permanent和redirect)
5.4.2.1 rewrite-自动跳转https(全站加密)
一、Web服务的基础介绍
正常情况下单次web服务访问的流程简图:
1.1 Web服务介绍
这里介绍的是 Apache 和 NGINX
1.1.1 Apache 经典的Web服务端
1.1.1.1 Apache perfork 模型
- 预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024
- 每个子进程有一个独立的线程响应用户请求
- 相对比较占用内存,但是比较稳定,可以设置最大和最小进程数
- 是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景
1.1.1.2 Apache worker 模型
- 一种多进程和多线程混合的模型
- 有一个控制进程,启动多个子进程
- 每个子进程里面包含固定的线程
- 使用线程程来处理请求
- 当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,
- 由于其使用了线程处理请求,因此可以承受更高的并发
1.1.1.3 Apache event模型
1.2 Nginx-高性能的Web服务端
NGINX的工作场景:
1.2.1服务端 I/O 流程
- 磁盘I/O
- 网络I/O : 一切皆文件,本质为对socket文件的读写
1.2.1.1 磁盘 I/O
机械磁盘的寻道时间、旋转延迟和数据传输时间:寻道时间:是指磁头移动到正确的磁道上所花费的时间,寻道时间越短则 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.17ms10000 转的机械盘平均延迟: 60*1000/10000/2 = 3ms15000 转的机械盘平均延迟: 60*1000/15000/2 = 2ms每秒最大 IOPS 的计算方法:7200 转的磁盘 IOPS 计算方式: 1000 毫秒 /(9 毫秒的寻道时间 +4.17 毫秒的平均旋转延迟时间 )=1000/13.13=75.9 IOPS10000 转的磁盘的 IOPS 计算方式: 1000 毫秒 /(6 毫秒的寻道时间 +3 毫秒的平均旋转延迟时间 )=1000/9=111IOPS15000 转的磁盘的 IOPS 计算方式: 15000 毫秒 /(4 毫秒的寻道时间 +2 毫秒的平均旋转延迟时间 )=1000/6=166.6 IOPS
1.2.1.2 网络 I/O
- 获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求(1-3)
- 构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成(4)
- 返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端(5-7)
- 第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长
- 第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短
1.2.2 I/O 模型
1.2.2.1 I/O 模型相关概念
- 同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事
- 情是否处理完成
- 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态
- 阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂 起,干不了别的事情。
- 非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。
1.2.2.2 网络 I/O模型
1.2.2.2.1 阻塞型 I/O 模型(blocking IO)
- 阻塞IO模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞
- 用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间。内核等到数据包到达后,然 后将接收的数据拷贝到用户空间,完成read操作
- 用户需要等待read将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线 程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够
1.2.2.2.2 非阻塞型 I/O 模型 (nonblocking IO)
1.2.2.2.3 多路复用 I/O 型(I/O multiplexing)
- 优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述符一个线程),这样可以大大节省系统资源
- 缺点:当连接数较少时效率相比多线程+阻塞 I/O 模型效率较低,可能延迟更大,因为单个连接处理 需要 2 次系统调用,占用时间会有增加
IO多路复用适用如下场合:
- 当客户端处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用
- 当一个客户端同时处理多个套接字时,此情况可能的但很少出现
- 当一个服务器既要处理监听套接字,又要处理已连接套接字,一般也要用到I/O复用
- 当一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用
- 当一个服务器要处理多个服务或多个协议,一般要使用I/O复用
1.2.2.2.4 信号驱动式 I/O 模型 (signal-driven IO)
1.2.2.2.5 异步 I/O 模型 (asynchronous IO)
1.3 零拷贝介绍
1.3.1 什么是零拷贝
1.3.2 零拷页相关技术
1.3.2.1 MMAP ( Memory Mapping )
1.3.2.2 SENDFILE
1.3.2.3 DMA 辅助的 SENDFILE
二、Nginx的架构和安装
2.1 Nginx的概述
- Tengine:由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加 了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了 很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。从2011年12月开始, Tengine成为一个开源项目官网: http://tengine.taobao.org/
- OpenResty:基于 Nginx 与 Lua 语言的高性能 Web 平台, 章亦春团队开发,官网:http://openr esty.org/cn/
2.1.1 Nginx的功能介绍
- 静态的web资源服务器html,图片,js,css,txt等静态资源
- http/https协议的反向代理
- 结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
- tcp/udp协议的请求转发(反向代理)
- imap4/pop3协议的反向代理
2.1.2 基础特性
- 模块化设计,较好的扩展性
- 高可靠性
- 支持热部署:不停机更新配置文件,升级版本,更换日志文件
- 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
2.1.3 Web 服务相关的功能
- 虚拟主机(server)
- 支持 keep-alive 和管道连接(利用一个连接做多次请求)
- 访问日志(支持基于日志缓冲提高其性能)url rewirte
- 路径别名
- 基于IP及用户的访问控制
- 支持速率限制及并发数限制
- 重新配置和在线升级而无须中断客户的工作进程
2.2 Nginx 架构和进程
2.2.1 Nginx 进程结构
- 多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直 到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务 器资源耗尽而无法提供请求
- 多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程和此客 户端进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器 对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可 以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作 了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。
主进程 (master process) 的功能:
- 对外接口:接收外部的操作(信号)
- 对内转发:根据外部的操作的不同,通过信号管理 Worker
- 监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
- 读取Nginx 配置文件并验证其有效性和正确性
- 建立、绑定和关闭socket连接
- 按照配置生成、管理和结束工作进程
- 接受外界指令,比如重启、升级及退出服务器等指令
- 不中断服务,实现平滑升级,重启服务并应用新的配置
- 开启日志文件,获取文件描述符
- 不中断服务,实现平滑升级,升级失败进行回滚处理
- 编译和处理perl脚本
- 工作进程(worker process)的功能:
- 所有 Worker 进程都是平等的
- 实际处理:网络请求,由 Worker 进程处理
- Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争
- CPU资源,
- 增加上下文切换的损耗
- 接受处理客户的请求
- 将请求依次送入各个功能模块进行处理
- I/O调用,获取响应数据
- 与后端服务器通信,接收后端服务器的处理结果
- 缓存数据,访问缓存索引,查询和调用缓存数据
- 发送请求结果,响应客户的请求
- 接收主程序指令,比如重启、升级和退出等
2.2.2 Nginx 进程间通信
worker进程之间的通信原理基本上和主进程与 worker 进程之间的通信是一样的,只要 worker 进程之间能够 取得彼此的信息,建立管道即可通信,但是由于worker 进程之间是完全隔离的,因此一个进程想要知道另外一 个进程的状态信息, 就只能通过主进程来实现。为了实现worker 进程之间的交互, master 进程在生成 worker 进程之后,在 worker 进程表中进行遍历,将该新进程的PID 以及针对该进程建立的管道句柄传递给 worker 进程中的其他程,为 worker 进程之间的通信做准备,当worker 进程 1 向 worker 进程 2 发送指令的时候,首先在 master 进程给它的其他 worker 进程工作信息中找到2 的进程 PID ,然后将正确的指令写入向进程 2 的管道, worker 进程 2 捕获到管道中的事件后,解析指令并进行相关操作,这样就完成了worker 进程之间的通信。另worker 进程可以通过共享内存来通讯的,比如 upstream 中的 zone ,或者 limit_req 、 limit_conn 中的zone等。操作系统提供了共享内存机制
2.2.3 Nginx 启动和 HTTP 连接建立
- Nginx 启动时,Master 进程,加载配置文件
- Master 进程,初始化监听的 socket
- Master 进程,fork 出多个 Worker 进程
- Worker 进程,竞争新的连接,获胜方通过三次握手,建立 Socket 连接,并处理请求
2.2.4 HTTP处理过程
2.3 Nginx 模块介绍
nginx 有多种模块
- 核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件
- 驱动机制 、进程管理等核心功能
- 标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 HTTP响应 头设置 等等
- 可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如: Flash多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
- 邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持
- Stream服务模块: 实现反向代理功能,包括TCP协议代理
- 第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等
nginx 高度模块化,但其模块早期不支持 DSO 机制 ;1.9.11 版本支持动态装载和卸载
2.4 Nginx安装
2.4.1 Nginx版本和安装方式
Nginx版本
-
Mainline version 主要开发版本,一般为奇数版本号,比如1.19
-
Stable version 当前最新稳定版,一般为偶数版本,如:1.20
-
Legacy versions 旧的稳定版,一般为偶数版本,如:1.18
Nginx安装可以使用yum或源码安装,但是推荐使用源码编译安装
-
yum的版本比较旧
-
编译安装可以更方便自定义相关路径
-
使用源码编译可以自定义相关功能,更方便业务的上的使用
2.4.2 Nginx 编译安装
编译器介绍
源码安装需要提前准备标准的编译器,GCC的全称是(GNU Compiler collection),其有GNU开发,并以GPL即LGPL许可,是自由的类UNIX即苹果电脑Mac OS X操作系统的标准编译器,因为GCC原本只能处理C语
言,所以原名为GNU C语言编译器,后来得到快速发展,可以处理C++,Fortran,pascal,objective C,java以及Ada等其他语言,此外还需要Automake工具,以完成自动创建Makefile的工作,Nginx的一些模块需要依赖第三方库,比如: pcre(支持rewrite),zlib(支持gzip模块)和openssl(支持ssl模块)等
2.4.2.1 编译安装Nginx
拖入软件压缩包到xshell
示例:
安装:
[root@nginx-node1 ~]# tar zxf nginx-1.24.0.tar.gz ---解压
进入目录:
[root@nginx-node1 ~]# cd nginx-1.24.0/
[root@nginx-node1 nginx-1.24.0]#
安装依赖性:
[root@nginx-node1 nginx-1.24.0]# dnf install gcc pcre-devel zlib-devel openssl-devel -y
[root@nginx-node1 nginx-1.24.0]# useradd -s /sbin/nologin -M nginx ---- 添加使用用户
编译模块:
[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 \
--add-module=/root/echo-nginx-module-0.63 \
--add-module=/root/memc-nginx-module-0.20 \
--add-module=/root/srcache-nginx-module-0.33
过了之后会生成Makefile文件,make规则
make clean ---- 可以让之前做的编译模块还原
执行make install
[root@nginx-node1 nginx-1.24.0]# make && make install
把nginx软件的命令执行添加到环境变量中
[root@nginx-node1 ~]# 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 ---- 添加这个
[root@nginx-node1 ~]# source ~/.bash_profile
[root@nginx-node1 ~]# du -sh /usr/local/nginx/sbin/nginx
进到这个目录下开启nginx:
[root@nginx-node1 ~]# cd /usr/local/nginx/sbin/
[root@nginx-node1 sbin]# ls
nginx
[root@nginx-node1 sbin]#
[root@nginx-node1 sbin]# ./nginx
[root@nginx-node1 sbin]#
查看进程和端口:
[root@nginx-node1 sbin]# ps aux | grep nginx
root 10018 0.0 0.0 9868 2056 ? Ss 08:55 0:00 nginx: master process ./nginx
nginx 10019 0.0 0.1 14200 5128 ? S 08:55 0:00 nginx: worker process
root 10021 0.0 0.0 221664 2304 pts/1 S+ 08:56 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 44612 10018/nginx: master
[root@nginx-node1 sbin]#
如何关闭nginx:
[root@nginx-node1 ~]# /usr/local/nginx/sbin/nginx -s stop
关闭debug模式:
[root@nginx-node1 nginx-1.24.0]# vim auto/cc/gcc
查看版本:
[root@nginx-node1 ~]# curl -I 172.25.254.200
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Thu, 15 Aug 2024 13:15:50 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 15 Aug 2024 12:54:39 GMT
Connection: keep-alive
ETag: "66bdfa8f-267"
Accept-Ranges: bytes
更改版本名:
[root@nginx-node1 ~]# cd nginx-1.24.0/
[root@nginx-node1 nginx-1.24.0]# cd src/
[root@nginx-node1 src]# cd core/
[root@nginx-node1 core]# ls
[root@nginx-node1 core]# vim nginx.h
/*
* Copyright (C) Igor Sysoev
* Copyright (C) Nginx, Inc.
*/
#ifndef _NGINX_H_INCLUDED_
#define _NGINX_H_INCLUDED_
#define nginx_version 1024000
#define NGINX_VERSION "1.0"
#define NGINX_VER "timingding/" NGINX_VERSION ---- 这里更改
#ifdef NGX_BUILD
#define NGINX_VER_BUILD NGINX_VER " (" NGX_BUILD ")"
#else
#define NGINX_VER_BUILD NGINX_VER
#endif
#define NGINX_VAR "NGINX"
#define NGX_OLDPID_EXT ".oldbin"
#endif /* _NGINX_H_INCLUDED_ */
2.4.2.2 正则表达式访问文件优先级:
2.4.2.3 正则表达式访问目录优先级:
三、Nginx的核心配置
3.1 nginx的平滑升级及版本回滚
输入网址nginx.org,然后找到新版本复制链接用wget命令下载
[root@nginx-node1 ~]# wget https://nginx.org/download/nginx-1.26.2.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 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
这里直接make就可以了
[root@nginx-node1 nginx-1.26.2]# make
平滑升级:
对旧版本的命令进行备份:
旧版本:
[root@nginx-node1 sbin]# nginx -s stop
[root@nginx-node1 ~]# rm -rf /usr/local/nginx/
[root@nginx-node1 ~]# cd /root/nginx-1.24.0/
[root@nginx-node1 nginx-1.24.0]# make install
[root@nginx-node1 nginx-1.24.0]# cd /usr/local/nginx/
[root@nginx-node1 nginx]# ls
conf html logs sbin
[root@nginx-node1 nginx]# cd sbin/
[root@nginx-node1 sbin]# ls
nginx
[root@nginx-node1 sbin]# nginx
root@nginx-node1 objs]# cd /usr/local/nginx/sbin/
[root@nginx-node1 sbin]# ls
nginx
[root@nginx-node1 sbin]# cp nginx nginx.old
[root@nginx-node1 sbin]#
[root@nginx-node1 sbin]# \cp -f /root/nginx-1.26.2/objs/nginx /usr/local/nginx/sbin/
[root@nginx-node1 sbin]# ps aux | grep nginx
root 14254 0.0 0.0 9868 1928 ? Ss 09:54 0:00 nginx: master process nginx
nginx 14255 0.0 0.1 14200 5128 ? S 09:54 0:00 nginx: worker process
root 14275 0.0 0.0 221664 2304 pts/2 S+ 09:58 0:00 grep --color=auto nginx
使用kill -USR2创建新的worker进程,但不会监听端口:
[root@nginx-node1 sbin]# kill -USR2 14254
[root@nginx-node1 sbin]# ps aux | grep nginx
root 14254 0.0 0.0 9868 2184 ? Ss 09:54 0:00 nginx: master process nginx
nginx 14255 0.0 0.1 14200 5128 ? S 09:54 0:00 nginx: worker process
root 14276 0.0 0.1 9896 6656 ? S 09:59 0:00 nginx: master process nginx
nginx 14277 0.0 0.1 14228 5136 ? S 09:59 0:00 nginx: worker process
root 14279 0.0 0.0 221664 2304 pts/2 S+ 09:59 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]#
把旧的worker进程回收:
[root@nginx-node1 sbin]# kill -WINCH 14254
[root@nginx-node1 sbin]# ps aux | grep nginx
root 14254 0.0 0.0 9868 2184 ? Ss 09:54 0:00 nginx: master process nginx
root 14276 0.0 0.1 9896 6656 ? S 09:59 0:00 nginx: master process nginx
nginx 14277 0.0 0.1 14228 5136 ? S 09:59 0:00 nginx: worker process
root 14293 0.0 0.0 221664 2304 pts/2 S+ 10:04 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]#
[root@nginx-node1 ~]# cd nginx-1.24.0/
[root@nginx-node1 nginx-1.24.0]# cd src/
[root@nginx-node1 src]# cd core/
[root@nginx-node1 core]# curl -I 172.25.254.200
HTTP/1.1 200 OK
Server: nginx/1.26.2 ----- 平滑升级成功
Date: Thu, 15 Aug 2024 14:10:49 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 15 Aug 2024 13:53:46 GMT
Connection: keep-alive
ETag: "66be086a-267"
Accept-Ranges: bytes
版本回滚:
把旧版本激活,新版本回收:
激活:
[root@nginx-node1 sbin]# kill -HUP 14254
[root@nginx-node1 sbin]# ps aux | grep nginx
root 14254 0.0 0.0 9868 2184 ? Ss 09:54 0:00 nginx: master process nginx
root 14276 0.0 0.1 9896 6656 ? S 09:59 0:00 nginx: master process nginx
nginx 14277 0.0 0.1 14228 5392 ? S 09:59 0:00 nginx: worker process
nginx 14339 0.0 0.1 14200 5144 ? S 10:12 0:00 nginx: worker process --- 新的
root 14341 0.0 0.0 221664 2304 pts/2 S+ 10:12 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]#
回收:
[root@nginx-node1 sbin]# kill -WINCH 14276
[root@nginx-node1 sbin]# ps aux | grep nginx
root 14254 0.0 0.0 9868 2184 ? Ss 09:54 0:00 nginx: master process nginx
root 14276 0.0 0.1 9896 6656 ? S 09:59 0:00 nginx: master process nginx
nginx 14339 0.0 0.1 14200 5144 ? S 10:12 0:00 nginx: worker process
root 14343 0.0 0.0 221664 2304 pts/2 S+ 10:14 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]#
回到旧版本了:
[root@nginx-node1 core]# curl -I 172.25.254.200
HTTP/1.1 200 OK
Server: timingding/1.0
Date: Thu, 15 Aug 2024 14:15:36 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 15 Aug 2024 13:53:46 GMT
Connection: keep-alive
ETag: "66be086a-267"
Accept-Ranges: bytes
把新的进程杀掉:
[root@nginx-node1 sbin]# cp nginx nginx.new
[root@nginx-node1 sbin]# \cp -f nginx.old nginx
[root@nginx-node1 sbin]# ls
nginx nginx.new nginx.old
[root@nginx-node1 sbin]# ps aux | grep nginx
root 14254 0.0 0.0 9868 2184 ? Ss 09:54 0:00 nginx: master process nginx
root 14276 0.0 0.1 9896 6656 ? S 09:59 0:00 nginx: master process nginx
nginx 14339 0.0 0.1 14200 5400 ? S 10:12 0:00 nginx: worker process
root 14362 0.0 0.0 221664 2304 pts/2 S+ 10:17 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]# kill -9 14276
[root@nginx-node1 sbin]# ps aux | grep nginx
root 14254 0.0 0.0 9868 2184 ? Ss 09:54 0:00 nginx: master process nginx
nginx 14339 0.0 0.1 14200 5400 ? S 10:12 0:00 nginx: worker process
root 14364 0.0 0.0 221664 2304 pts/2 S+ 10:18 0:00 grep --color=auto nginx
[root@nginx-node1 sbin]#
3.2 启动脚本的编写
[root@nginx-node1 sbin]# vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root@nginx-node1 logs]# systemctl daemon-reload
[root@nginx-node1 logs]# nginx -s stop
[root@nginx-node1 logs]# ps aux | grep nginx
root 14510 0.0 0.0 221664 2304 pts/2 S+ 10:22 0:00 grep --color=auto nginx
[root@nginx-node1 logs]# systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@nginx-node1 logs]# ps aux | grep nginx
root 14544 0.0 0.0 9864 2052 ? Ss 10:23 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 14545 0.0 0.1 14196 4996 ? S 10:23 0:00 nginx: worker process
root 14547 0.0 0.0 221664 2304 pts/2 S+ 10:23 0:00 grep --color=auto nginx
[root@nginx-node1 logs]#
3.3 nginx配置中的root和alias
新建一个web站点:
[root@nginx-node1 core]# vim /usr/local/nginx/conf/nginx.conf
events {
worker_connections 1024;
use epoll; ---- 加上这个,运用epoll
}
#gzip on;
include "/usr/local/nginx/conf.d/*.conf"; ------ 再加上子配置文件
创建子配置文件目录:
[root@nginx-node1 core]# mkdir /usr/local/nginx/conf.d -p
[root@nginx-node1 core]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.timingding.org;
root /data/web/html;
index index.html;
}
[root@nginx-node1 core]# mkdir -p /data/web/html
[root@nginx-node1 core]# echo www.timingding.org > /data/web/html/index.html
[root@nginx-node1 core]# 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 core]# nginx -s reload ---- 刷新
访问172.25.254.200
去访问另外的路径,root和alias
[root@nginx-node1 core]# vim /usr/local/nginx/conf.d/vhost.conf
root:
server {
listen 80;
server_name www.timingding.org;
root /data/web/html;
index index.html;
location /test1/ {
root /data/web;
}
}
[root@nginx-node1 core]# mkdir /data/web/test1 -p
[root@nginx-node1 core]# echo /data/web/test1 > /data/web/test1/index.html
[root@nginx-node1 core]# nginx -s reload --- 刷新一下
访问172.25.254.100/test1
alias:
[root@nginx-node1 core]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.timingding.org;
root /data/web/html;
index index.html;
location /test1/ {
root /data/web;
}
location /test2 {
alias /data/web/test1;
}
}
[root@nginx-node1 core]# nginx -s reload --- 刷新一下
访问172.25.254.200/test2/
3.4 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 ding
New password:
Re-type new password:
Adding password for user ding
[root@nginx-node1 ~]#
[root@nginx-node1 ~]# cat /usr/local/nginx/.htpasswd
admin:$apr1$m/VIu7Dx$D.uCAJi2GsAR4MVbn2caY0
ding:$apr1$mJBsFc9R$BzRaDwhgw2E/qQ9sYqBPf1
[root@nginx-node1 ~]#
编写配置文件
[root@nginx-node1 ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.timingding.org;
root /data/web/html;
index index.html;
location /ding {
root /data/web;
auth_basic "login passwd !!!";
auth_basic_user_file "/usr/local/nginx/.htpasswd";
}
}
创建文件目录:
[root@nginx-node1 ~]# mkdir /data/web/ding
[root@nginx-node1 ~]# echo ding > /data/web/ding/index.html
[root@nginx-node1 ~]# nginx -s reload
访问www.timingding.org/ding
3.5 nginx的自定义错误页面
创建文件目录:
[root@nginx ~]# mkdir /data/web/errorpage -p
[root@nginx ~]# echo error page > /data/web/erroepage/40x.html
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.timingding.org;
root /data/web/html;
index index.html;
error_page 404 /40x.html;
#error_log /var/log/timingding.org/error.log;
#access_log /var/log/timingding.org/access.log;
location /ding {
root /data/web;
auth_basic "login passwd";
auth_basic_user_file "/usr/local/nginx/.htpasswd";
}
location = /40x.html {
root /data/web/errorpage;
}
}
[root@nginx ~]# systemctl restart nginx.service
网页访问,输入一个错误的uri,172.25.254.100/ppd
3.6 nginx-自定义日志
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.timingding.org;
root /data/web/html;
index index.html;
error_page 404 /40x.html;
error_log /var/log/timingding.org/error.log; ----- 加这两行
access_log /var/log/timingding.org/access.log;
location /ding {
root /data/web;
auth_basic "login passwd";
auth_basic_user_file "/usr/local/nginx/.htpasswd";
}
location /40x.html {
root /data/web/errorpage;
}
}
建立日志文件目录:
[root@nginx ~]# mkdir /var/log/timingding.org/ -p
[root@nginx ~]# systemctl restart nginx.service
[root@nginx ~]# curl www.timingding.org
www.timingding.org
访问正确的域名:
[root@nginx ~]# curl www.timingding.org
www.timingding.org
[root@nginx ~]# cat /var/log/timingding.org/access.log
172.25.254.100 - - [16/Aug/2024:08:07:07 -0400] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1"
访问错误的域名:
[root@nginx ~]# curl www.timingding.org/aaad
error page
[root@nginx ~]# cat /var/log/timingding.org/error.log
2024/08/16 08:07:51 [error] 15474#0: *2 open() "/data/web/html/aaad" failed (2: No such file or directory), client: 172.25.254.100, server: www.timingding.org, request: "GET /aaad HTTP/1.1", host: "www.timingding.org"
[root@nginx ~]#
3.7nginx中的文件检测
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.timingding.org;
root /data/web/html;
index index.html;
error_page 404 /40x.html;
error_log /var/log/timingding.org/error.log;
access_log /var/log/timingding.org/access.log;
try_files $uri $uri.html $uri/index.html /error/default.html;
location /ding {
root /data/web;
auth_basic "login passwd";
auth_basic_user_file "/usr/local/nginx/.htpasswd";
}
location /40x.html {
root /data/web/errorpage;
}
}
[root@nginx ~]# systemctl restart nginx.service
[root@nginx ~]# rm -rf /data/web/html/index.html
[root@nginx ~]# rm -rf /data/web/html/error
[root@nginx ~]# curl www.timingding.org ---- 现在检测到文件都没有,报500的错
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.24.0</center>
</body>
</html>
创建检测文件的目录:
[root@nginx ~]# mkdir /data/web/html/error
[root@nginx ~]# echo error default > /data/web/html/error/default.html
[root@nginx ~]# curl www.timingding.org
error default
[root@nginx ~]#
还原回来
[root@nginx ~]# echo www.timingding.org > /data/web/html/index.html
3.8 nginx中的长链接管理
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
#keepalive_timeout 0;
keepalive_timeout 65 60; #----65长链接默认的保持时间,后面没有请求报文了,这里设置多少时间,时间到了就自动退出
60设定了之后,客户会看到这个长链接保持的时间
keepalive_requests 2; #默认是100,请求过程中发出的长链接数量不能超过多少
安装长链接测试用的工具telnet
[root@nginx ~]# dnf install telnet -y
[root@nginx ~]# telnet www.timingding.org 80
Trying 172.25.254.100...
Connected to www.timingding.org.
Escape character is '^]'.
GET / HTTP/1.1 ----- 手动写入请求的报文
HOST: www.timingding.org ----- 访问的域名,端口
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Fri, 16 Aug 2024 12:45:43 GMT
Content-Type: text/html
Content-Length: 19
Last-Modified: Fri, 16 Aug 2024 12:45:12 GMT
Connection: keep-alive
ETag: "66bf49d8-13"
Accept-Ranges: bytes
www.timingding.org
这里设置了两次,请求两次之后就会退出。
企业中一般不能断开,要一直请求访问
3.9 nginx-下载服务器的设定及优化
创建下载文件的目录:
[root@nginx ~]# mkdir /data/web/download -p
[root@nginx ~]# dd if=/dev/zero of=/data/web/download/dingfile bs=1M count=100 ---- 做一个大小为100M的文件,并放到刚才创建的目录。创建的一个数据。
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.0394146 s, 2.7 GB/s
[root@nginx ~]#
写一个location,访问路径
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.timingding.org;
root /data/web/html;
index index.html;
error_page 404 /40x.html;
error_log /var/log/timingding.org/error.log;
access_log /var/log/timingding.org/access.log;
try_files $uri $uri.html $uri/index.html /error/default.html;
location /ding {
root /data/web;
auth_basic "login passwd";
auth_basic_user_file "/usr/local/nginx/.htpasswd";
}
location /40x.html {
root /data/web/errorpage;
}
location /download {
root /data/web;
autoindex on; ----- 让文件可以长列表显示
autoindex_localtime on; -----on表示显示本机时间而非GMT(格林威治)时间,默为为off显示GMT时间
autoindex_exact_size off; ---- 计算文件确切大小(单位bytes),此为默认值,off只显示大概大小(单位kb、mb、gb)
limit_rate 1024k; -------- 限速,默认不限速 }
}
}
[root@nginx ~]# wget www.timingding.org/download/dingfile
--2024-08-16 09:11:02-- http://www.timingding.org/download/dingfile
Resolving www.timingding.org (www.timingding.org)... 172.25.254.100
Connecting to www.timingding.org (www.timingding.org)|172.25.254.100|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: ‘dingfile.1’
dingfile.1 26%[===================> ] 26.00M 1.04MB/s eta 71s
四、Nginx的高级配置
4.1 nginx-数据压缩功能
Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module,默认是内置模块
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
gzip on;
gzip_comp_level 4;
gzip_min_length 1k;
gzip_http_version 1.0;
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 ~]# nginx -t ----检测下语法是否有错
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]#
[root@nginx ~]# systemctl restart nginx.service
测试:
[root@nginx ~]# echo hello nginx > /data/web/html/small.html ----- 写入一个小于1k的文件
[root@nginx ~]# du -sh /usr/local/nginx/logs/access.log
208K /usr/local/nginx/logs/access.log
[root@nginx ~]# cat /usr/local/nginx/logs/access.log > /data/web/html/big.html ----写入一个大于1k的文件
[root@nginx ~]#
[root@nginx ~]# curl --head --compressed 172.25.254.100/small.html ---- 小于1k不会被压缩
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Fri, 16 Aug 2024 13:32:39 GMT
Content-Type: text/html
Content-Length: 12
Last-Modified: Fri, 16 Aug 2024 13:29:43 GMT
Connection: keep-alive
ETag: "66bf5447-c"
Accept-Ranges: bytes
(--head只看响应报文的头部内容不看)
[root@nginx ~]# curl --head --compressed 172.25.254.100/big.html ----- 大于1k会被压缩
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Fri, 16 Aug 2024 13:32:46 GMT
Content-Type: text/html
Last-Modified: Fri, 16 Aug 2024 13:31:01 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: W/"66bf5495-33553"
Content-Encoding: gzip
[root@nginx ~]#
这里压缩并不是给文件本身压缩,是文件在传输过程中被压缩。
4.2 内置变量的使用
$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;
4.2.1 nginx -- 内置变量
内置变量示例:
[root@nginx ~]# vim /usr/local/nginx/conf.d/vars.conf
server {
listen 80;
server_name var.timingding.org;
root /data/web/html;
index index.html;
location /var {
default_type /text/html;
echo $remote_addr; ---------- 存放了客户端的地址,注意是客户端的公网IP
echo $args; ---------- 变量中存放了URL中的所有参数
echo $is_args; ---------- 如果有参数为? 否则为空
echo $document_root; ---------- 保存了针对当前资源的请求的系统根目录
echo $document_uri; ---------- 保存了当前请求中不包含参数的URI,注意是不包含请求的指令
echo $host; ---------- 存放了请求的host名称
echo $remote_port; ---------- 客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
echo $remote_user; ---------- 已经经过Auth Basic Module验证的用户名
echo $request_method; ---------- 请求资源的方式,GET/PUT/DELETE等
echo $request_filename; --------- 当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径
echo $request_uri; --------- 包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args
echo $scheme; --------- 请求的协议,例如:http,https,ftp等
echo $server_protocol; ---------- 保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等
echo $server_addr; ---------- 保存了服务器的IP地址
echo $server_name; ---------- 虚拟主机的主机名
echo $server_port; ---------- 虚拟主机的端口号
echo $http_user_agent; ---------- 客户端浏览器的详细信息
echo $http_cookie; ---------- 客户端的所有cookie信息
echo $cookie_key2; ---------- name为任意请求报文首部字部cookie的key名
}
}
测试:
[root@nginx conf.d]# curl -b "key1=ding,key2=xiaoding" -u ding:123 var.timingding.org/var?name=DZ&&id=203621
172.25.254.100
name=DZ
?
/data/web/html
/var
var.timingding.org
48002
ding
GET
/data/web/html/var
/var?name=DZ
http
HTTP/1.1
172.25.254.100
var.timingding.org
80
curl/7.76.1
key1=ding,key2=xiaoding
xiaoding
[root@nginx conf.d]#
4.2.2 Nginx -- 自定义变量
自定义变量示例:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vars.conf
server {
listen 80;
server_name var.timinglee.org;
root /data/web/html;
index index.html;
location /var {
default_type text/html;
set $timingding xiaoding;
echo $timingding;
}
测试:
[root@nginx conf.d]# curl var.timingding.org/var
xiaoding
[root@nginx conf.d]#
五、nginx 中rewrite模块功能
5.1 if指令
示例:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vars.conf
server {
listen 80;
server_name var.timingding.org;
root /data/web/html;
index index.html;
location /test2 {
if ( !-e $request_filename ){
echo "$request_filename is not exist";
}
}
}
测试:
此时不存在test2的目录
[root@nginx conf.d]# curl var.timingding.org/test2/index.html
/data/web/html/test2/index.html is not exist
[root@nginx conf.d]#
测试:
存在test2的目录,有的话就直接显示内容
创建一个:
[root@nginx conf.d]# mkdir -p /data/web/html/test2/
[root@nginx conf.d]# echo test2 > /data/web/html/test2/index.html
[root@nginx conf.d]# curl var.timingding.org/test2/index.html
test2
[root@nginx conf.d]#
5.2 set 指令
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timingding.org;
root /data/nginx/timingding.org/ding;
location /test2{
set $name ding;
echo $name;
}
}
测试:
[root@nginx ~]# curl lee.timingding.org/test2
ding
5.3 break指令
示例:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vars.conf
server {
listen 80;
server_name var.timingding.org;
root /data/web/html;
index index.html;
location /test2 {
if ( !-e $request_filename ){
echo "$request_filename is not exist";
#return 409;
}
}
location /break {
default_type text/html;
set $name ding;
echo $name;
set $id 203621;
echo $id;
}
}
[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# curl var.timingding.org/break
ding
203621
[root@nginx conf.d]#
配合if再加上break:
location /break {
default_type text/html;
set $name ding;
echo $name;
if ( $http_user_agent = "curl/7.76.1"){
break;
}
set $id 203621;
echo $id;
}
[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# curl var.timingding.org/break
ding
[root@nginx conf.d]#
指定下别的浏览器,break就不生效:
[root@nginx conf.d]# curl -A "fileding" var.timingding.org/break
ding
203621
[root@nginx conf.d]#
5.4 return指令
根据上面的实验接着往下面加,示例:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vars.conf
location /return {
default_type text/html;
if ( !-e $request_filename ){
echo "$request_filename is not exist";
return 301 http://www.baidu.com;
}
echo "$request_filename is not exist";
}
}
现在没有return的目录,会定向到www.baidu.com,并且会报301
测试:
[root@nginx conf.d]# curl -I var.timingding.org/return
HTTP/1.1 301 Moved Permanently
Server: xiaoding/1.1
Date: Sun, 18 Aug 2024 11:12:55 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Keep-Alive: timeout=60
Location: http://www.baidu.com
存在return目录
测试:
[root@nginx conf.d]# mkdir -p /data/web/html/return/
[root@nginx conf.d]#
[root@nginx conf.d]# curl -I var.timingding.org/return
HTTP/1.1 200 OK
Server: xiaoding/1.1
Date: Sun, 18 Aug 2024 11:15:25 GMT
Content-Type: text/html
Connection: keep-alive
Keep-Alive: timeout=60
Vary: Accept-Encoding
[root@nginx conf.d]#
5.4.1 rewrite案例:域名永久与临时重定向(permanent和redirect)
永久:
示例:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vars.conf
location / {
root /data/web/var;
index index.html;
rewrite / http://www.timingding.com permanent; --- 永久重定向 301 两个不能同时启用
#rewrite / http://www.timingding.com redirext; --- 临时重定向 302
}
[root@nginx conf.d]# mkdir -p /data/web/var
[root@nginx conf.d]# echo var page > /data/web/var/index.html
[root@nginx conf.d]# nginx -s reload
测试:
curl 不支持重定向
永久的301:
[root@nginx conf.d]# curl -I var.timingding.org
HTTP/1.1 301 Moved Permanently
Server: xiaoding/1.1
Date: Sun, 18 Aug 2024 11:40:30 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Keep-Alive: timeout=60
Location: http://www.timingding.com
[root@nginx conf.d]#
临时:
换成临时的302:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vars.conf
location / {
root /data/web/var;
index index.html;
#rewrite / http://www.timingding.com permanent;
rewrite / http://www.timingding.com redirext;
}
5.4.2 break和last
示例:
创建目录:
[root@nginx conf.d]# mkdir /data/web/html/{test1,test2,break,last} -p
[root@nginx conf.d]# echo test1 > /data/web/html/test1/index.html
[root@nginx conf.d]# echo test2 > /data/web/html/test2/index.html
[root@nginx conf.d]# echo break > /data/web/html/break/index.html
[root@nginx conf.d]# echo last > /data/web/html/last/index.html
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vars.conf
server {
listen 80;
server_name var.timingding.org;
root /data/web/html;
index index.html;
location /break {
rewrite ^/break/(.*) /test1/$1;
rewrite ^/test1/(.*) /test2/$1;
}
location /last {
rewrite ^/last/(.*) /test1/$1;
rewrite ^/test1/(.*) /test2/$1;
}
location /test1 {
default_type text/html;
return 203 "xiaoding hahahahaha";
}
location /test2 {
root /data/web/html;
}
}
访问:
[root@nginx conf.d]# curl var.timingding.org/break/
test2
[root@nginx conf.d]# curl var.timingding.org/last/
test2
[root@nginx conf.d]# curl var.timingding.org/test1/
xiaoding hahahahaha
[root@nginx conf.d]# curl var.timingding.org/test2/
test2
break和last效果示例:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vars.conf
server {
listen 80;
server_name var.timingding.org;
root /data/web/html;
index index.html;
location /break {
root /data/web/html;
rewrite ^/break/(.*) /test1/$1 break; ----- 加上break,执行到这里就不访问下面的了,看的是test1里面的内容
rewrite ^/test1/(.*) /test2/$1;
}
location /last {
root /data/web/html;
rewrite ^/last/(.*) /test1/$1 last;
rewrite ^/test1/(.*) /test2/$1;
}
location /test1 {
default_type text/html;
return 203 "xiaoding hahahahaha";
}
location /test2 {
root /data/web/html;
}
}
测试
[root@nginx ~]# nginx -s reload
[root@nginx ~]# curl var.timingding.org/break/index.html #访问break时,会终止,但不会跳出当前的location
test1
[root@nginx ~]#
[root@nginx~]# curl var.timingding.org/last/index.html #访问last时,也会终止,但是会跳出当前的location,继续寻找路径
xiaoding hahahahaha
[root@nginx ~]#
5.4.2.1 rewrite-自动跳转https(全站加密)
制作证书:
[root@nginx ~]# cd /usr/local/nginx/certs/
[root@nginx certs]#openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/nginx/certs/timingding.org.key
-x509 -days 365 -out /usr/local/nginx/certs/timingding.org.crt
[root@nginx certs]# ls
timingding.org.crt timingding.org.key
[root@nginx certs]#
写配置:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
listen 443 ssl;
server_name www.timingding.org;
root /data/web/html;
index index.html;
ssl_certificate /usr/local/nginx/certs/timingding.org.crt;
ssl_certificate_key /usr/local/nginx/certs/timingding.org.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
location / {
if ( $scheme = http ) {
rewrite /(.*) https://$host/$1 redirect;
}
}
[root@nginx conf.d]# echo www.timingding.org > /data/web/html/index.html
网页访问www.timingding.org
5.4.2.2 访问不存在的文件,自动跳转到本地路径访问
示例:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
listen 443 ssl;
server_name www.timingding.org;
root /data/web/html;
index index.html;
ssl_certificate /usr/local/nginx/certs/timingding.org.crt;
ssl_certificate_key /usr/local/nginx/certs/timingding.org.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;
}
}
}
此时访问www.timingding.org后面跟上不存在的文件路径,自动跳转到本地路径,访问内容。
例如:www.timingding.org/a/b/a/
5.5 nginx-盗链及防盗链
none : ------- 请求报文首部没有 referer 首部,比如用户直接在浏览器输入域名访问web网站,就没有 referer 信息。blocked: ------- 请求报文有 referer 首部,但无有效值,比如为空。server_names :------- referer 首部中包含本主机名及即 nginx 监听的 server_name 。arbitrary_string :--------- 自定义指定字符串,但可使用 * 作通配符。示例 : *.timingding.orgwww.timingding.*regular expression : --------- 被指定的正则表达式模式匹配到的字符串 , 要使用 ~ 开头例如: ~.*\.timingding\.com
示例:
[root@nginx conf.d]# mkdir -p /data/web/html/images
拖入你喜欢的照片
[root@nginx conf.d]# cd /data/web/html/images/
[root@nginx images]# ls
zrn.jpg
网页访问172.25.254.100/images/zrn.jpg
5.5.1 实现盗链
另一台主机托入盗链:
[root@nginx-node1 ~]# dnf install httpd -y
[root@nginx-node1 ~]# cd /var/www/html/
[root@nginx-node1 html]# ls
daolian.png
[root@nginx-node1 html]# mv daolian.png /var/www/html/index.html
[root@nginx-node1 html]# ls
index.html
[root@nginx-node1 html]# cat index.html
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>盗链</title>
</head>
<body>
<img src="http://www.timingding.org/images/zrn.jpg" >
<h1 style="color:red">章若楠最乖</h1>
<p><a href=http://www.timingding.org>狂戳若楠</a>见到若楠</p>
</body>
</html>
[root@nginx-node1 html]# systemctl start httpd
去网页访问172.25.254.10
5.5.2 防盗链
示例:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
listen 443 ssl;
server_name www.timingding.org;
root /data/web/html;
index index.html;
ssl_certificate /usr/local/nginx/certs/timingding.org.crt;
ssl_certificate_key /usr/local/nginx/certs/timingding.org.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
location /images {
valid_referers none blocked server_names *.timingding.org ~/.baidu/.;
if ( $invalid_referer ){
return 404;
}
}
}
此时访问172.25.254.10就访问不到图片了
让别人访问过来看到的不是想要的图片:
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
listen 443 ssl;
server_name www.timingding.org;
root /data/web/html;
index index.html;
ssl_certificate /usr/local/nginx/certs/timingding.org.crt;
ssl_certificate_key /usr/local/nginx/certs/timingding.org.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
#location / {
# valid_referers none blocked server_names *.timingding.org ~/.baidu/.;
# if ( $invalid_referer ){
# return 404;
#}
#}
location /images {
valid_referers none blocked server_names *.timingding.org ~/.baidu/.;
if ( $invalid_referer ){
rewrite ^/ http://www.timingding.org/tupi.jpg;
}
}
}
六、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 协议转发至指定服务器处理
6.1 反向代理的配置参数
proxy_pass; ------ 用来设置将客户端请求转发给的后端服务器的主机可以是主机名(将转发至后端服务做为主机头首部)、IP 地址:端口的方式也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持proxy_hide_header field; ------- 用于 nginx 作为反向代理的时候在返回给客户端http响应时隐藏后端服务器相应头部的信息可以设置在http,server或location块proxy_pass_header field; ---------- 透传默认 nginx 在响应报文中不传递后端服务器的首部字段 Date, Server, X-Pad, X-Accel 等参数如果要传递的话则要使用 proxy_pass_header field 声明将后端服务器返回的值传递给客户端field 首部字段大小不敏感proxy_pass_request_body on | off;是否向后端服务器发送HTTP 实体部分 , 可以设置在 http,server 或 location 块,默认即为开启proxy_pass_request_headers on | off;是否将客户端的请求头部转发给后端服务器,可以设置在 http,server 或 location 块,默认即为开启proxy_set_header;可更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实IP 的 时候,就要更改每一个报文的头部proxy_connect_timeout time;配置 nginx 服务器与后端服务器尝试建立连接的超时时间,默认为 60 秒proxy_read_timeout time;配置 nginx 服务器向后端服务器或服务器组发起 read 请求后,等待的超时时间,默认 60sproxy_send_timeout time;配置 nginx 项后端服务器或服务器组发起 write 请求后,等待的超时 时间,默认 60sproxy_http_version 1.0;用于设置 nginx 提供代理服务的 HTTP 协议的版本,默认 http 1.0proxy_ignore_client_abort off;当客户端网络中断请求时,nginx 服务器中断其对后端服务器的请求。即如果此项设置为 on 开启,则服务器、 会忽略客户端中断并一直等着代理服务执行返回,如果设置为off ,则客户端中断后 Nginx 也会中断客户端请求并立即记录499 日志,默认为 off 。
6.1.1 指定 location 实现反向代理
[root@nginx-node1 ~]# dnf install php -y
[root@nginx-node1 ~]# systemctl restart httpd
[root@nginx-node1 ~]# vim /var/www/html/index.php
<?php
phpinfo();
?>
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.timingding.org;
location ~ \.php$ {
proxy_pass http://172.25.254.10:80;
}
location /static {
proxy_pass http://172.25.254.20:8080;
}
}
[root@nginx ~]# nginx -s reload
网页访问www.timingding.org/index.php = 172.25.254.10
访问www.timingding.org/static/
6.1.2 针对特定资源实现反向代理
示例:
两台主机:
172.25.254.10:
[root@nginx-node1 ~]# echo 172.25.254.10 > /var/www/html/index.html
172.25.254.20:
[root@nginx-node2 ~]# echo 172.25.254.20 > /var/www/html/index.html
[root@nginx-node2 ~]# systemctl restart httpd
[root@nginx-node2 ~]# mkdir -p /var/www/html/static
[root@nginx-node2 ~]# echo static 172.25.254.20 > /var/www/html/static/index.html
172.25.254.100:
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.timingding.org;
location / {
proxy_pass http://172.25.254.10:80;
}
location /static {
proxy_pass http://172.25.254.20:8080;
}
}
访问: www.timingding.org
6.1.3 nginx反向代理的缓存功能
作压测:
示例:
[root@nginx-node1 ~]# ab -n1000 -c100 http://www.timingding.org/static/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 www.timingding.org (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software: Apache/2.4.57
Server Hostname: www.timingding.org
Server Port: 80
Document Path: /static/index.html
Document Length: 196 bytes
Concurrency Level: 100
Time taken for tests: 0.062 seconds
Complete requests: 1000
Failed requests: 0
Non-2xx responses: 1000
Total transferred: 394000 bytes
HTML transferred: 196000 bytes
Requests per second: 16169.72 [#/sec] (mean)
Time per request: 6.184 [ms] (mean)
Time per request: 0.062 [ms] (mean, across all concurrent requests)
Transfer rate: 6221.55 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.3 0 1
Processing: 1 6 2.0 6 13
Waiting: 1 5 2.0 6 13
Total: 2 6 1.7 6 13
Percentage of the requests served within a certain time (ms)
50% 6
66% 7
75% 7
80% 7
90% 8
95% 8
98% 9
99% 11
100% 13 (longest request)
[root@nginx-node1 ~]#
做缓存:
作缓存:
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
#gzip on;
proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m
inactive=120s max_size=1g;
server {
listen 80;
server_name www.timingding.org;
location ~ \.php$ {
proxy_pass http://172.25.254.10:80;
}
location /static {
proxy_pass http://172.25.254.20:8080;
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 10m;
proxy_cache_valid any 1m;
}
}
[root@nginx ~]# nginx -s reload
[root@nginx-node1 ~]# ab -n1000 -c100 http://www.timingding.org/static/index.html
缓存的路径,缓存到proxy_cache里面:
[root@nginx nginx]# tree proxy_cache/
proxy_cache/
└── e
└── 50
└── 99
└── 319432ef3663735a9d3cb4e0c1d9950e3 directories, 1 file
[root@nginx nginx]#
6.2 HTTP反向代理的负载均衡
6.2.1 七层:
配置nginx反向代理
示例:
[root@nginx nginx]# vim /usr/local/nginx/conf.d/vhost.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.timingding.org;
location / {
proxy_pass http://webcluster;
}
}
[root@nginx nginx]# nginx -s reload
默认是轮询
写算法:
[root@nginx nginx]# vim /usr/local/nginx/conf.d/vhost.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; --- hash写完不能加backup 防止调度到backup上面去
}
server {
listen 80;
server_name www.timingding.org;
location / {
proxy_pass http://webcluster;
}
}
[root@nginx nginx]# nginx -s reload
访问的都是同一个主机
[root@nginx nginx]# vim /usr/local/nginx/conf.d/vhost.conf
upstream webcluster {
#ip_hash;
hash $request_uri consistent; ---- 动态算法,hash一致性
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.timingding.org;
location / {
proxy_pass http://webcluster;
}
}
[root@nginx nginx]# nginx -s reload
uri没变,一直访问的是20
172.25.254.10:
[root@nginx-node1 ~]# mkdir -p /var/www/html/static
[root@nginx-node1 ~]# echo 172.25.254.10 static > /var/www/html/static/index.html
改uri,这就是对uri进行hash,一致的
对cookie进行hash
[root@nginx nginx]# vim /usr/local/nginx/conf.d/vhost.conf
upstream webcluster {
#ip_hash;
#hash $request_uri consistent;
hash $cookie_ding; ------- 对cookie进行hash
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.timingding.org;
location / {
proxy_pass http://webcluster;
}
}
[root@nginx nginx]# nginx -s reload
对cookie值进行hash,ding=1 or ding=2 对后面的值进行hash
6.2.2 四层:
注意:tcp的负载均衡要写在http语句块外面
stream { #定义stream相关的服务; Context:main upstream backend { #定义后端服务器 hash $remote_addr consistent; #定义调度算法 server backend1.example.com:12345 weight=5; #定义具体server server 127.0.0.1:12345 max_fails=3 fail_timeout=30s; server unix:/tmp/backend3; } upstream dns { #定义后端服务器 server 10.0.0.1:53; #定义具体server server dns.example.com:53; } server { #定义server listen 12345; #监听IP:PORT proxy_connect_timeout 1s; #连接超时时间 proxy_timeout 3s; #转发超时时间 proxy_pass backend; #转发到具体服务器组 } server { listen 127.0.0.1:53 udp reuseport; proxy_timeout 20s; proxy_pass dns; } server { listen [::1]:12345; proxy_pass unix:/tmp/stream.socket; } }
6.2.2.1 DNS 负载均衡(udp)
示例:
172.25.254.10和20 安装bind
配置DNS
[root@nginx-node1 ~]# dnf install bind -y
[root@nginx-node2 ~]# dnf install bind -y
[root@nginx-node1 ~]# vim /etc/named.conf
// listen-on port 53 { 127.0.0.1; };
// listen-on-v6 port 53 { ::1; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
secroots-file "/var/named/data/named.secroots";
recursing-file "/var/named/data/named.recursing";
// allow-query { localhost; };
dnssec-validation no; --- 改为no
[root@nginx-node1 ~]# vim /etc/named.rfc1912.zones
zone "timingding.org" IN {
type master;
file "timingding.org.zone";
allow-update { none; };
};
[root@nginx-node1 ~]# cd /var/named/
[root@nginx-node1 named]#
[root@nginx-node1 named]# cp named.localhost timingding.org.zone -p
[root@nginx-node1 named]# vim timingding.org.zone
$TTL 1D
@ IN SOA ns.timingding.org. root.timingding.org. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS ns.timingding.org.
ns A 172.25.254.10
www A 172.25.254.10
[root@nginx-node1 named]# systemctl start named
[root@nginx-node1 named]# systemctl start named
[root@nginx-node1 named]# dig www.timingding.org @172.25.254.10
; <<>> DiG 9.16.23-RH <<>> www.timingding.org @172.25.254.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27004
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 783e7ecaf1c29da10100000066c22dd4285bd72eb63c17c1 (good)
;; QUESTION SECTION:
;www.timingding.org. IN A
;; ANSWER SECTION:
www.timingding.org. 86400 IN A 172.25.254.10
;; Query time: 0 msec
;; SERVER: 172.25.254.10#53(172.25.254.10)
;; WHEN: Sun Aug 18 13:22:28 EDT 2024
;; MSG SIZE rcvd: 91
[root@nginx-node1 named]#
直接传到172.25.254,20上面
[root@nginx-node1 named]# scp -p /etc/named.{conf,rfc1912.zones} root@172.25.254.20:/etc/
The authenticity of host '172.25.254.20 (172.25.254.20)' can't be established.
ED25519 key fingerprint is SHA256:JAc5p6OZrNZsG8UQHYDL8RDEOeKmzy1IWQlXlmvsuSw.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '172.25.254.20' (ED25519) to the list of known hosts.
root@172.25.254.20's password:
named.conf 100% 1727 3.0MB/s 00:00
named.rfc1912.zones 100% 1129 2.8MB/s 00:00
[root@nginx-node1 named]#
[root@nginx-node1 named]# scp -p /var/named/timingding.org.zone \ root@172.25.254.20:/var/named/timingding.org.zone
root@172.25.254.20's password:
timingding.org.zone 100% 210 394.6KB/s 00:00
[root@nginx-node1 named]#
[root@nginx-node2 ~]# vim /var/named/timingding.org.zone
$TTL 1D
@ IN SOA ns.timingding.org. root.timingding.org. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS ns.timingding.org.
ns A 172.25.254.20
www A 172.25.254.20
[root@nginx-node2 named]# chgrp named timingding.org.zone
[root@nginx-node2 ~]# systemctl start named
[root@nginx-node2 named]# dig www.timingding.org @172.25.254.20
; <<>> DiG 9.16.23-RH <<>> www.timingding.org @172.25.254.20
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48200
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 3da0f57e7816a0bb0100000066c22fd3ea997c832e0fcd37 (good)
;; QUESTION SECTION:
;www.timingding.org. IN A
;; ANSWER SECTION:
www.timingding.org. 86400 IN A 172.25.254.20
;; Query time: 0 msec
;; SERVER: 172.25.254.20#53(172.25.254.20)
;; WHEN: Sun Aug 18 13:30:59 EDT 2024
;; MSG SIZE rcvd: 91
[root@nginx-node2 named]#
[root@nginx nginx]# vim /usr/local/nginx/conf/nginx.conf
include "/usr/local/nginx/tcpconf.d/*.conf"; ---- 要写在http外面
[root@nginx nginx]# vim /usr/local/nginx/conf.d/dns.conf
stream {
upstream dns {
server 172.25.254.10:53 fail_timeout=15s max_fails=3;
server 172.25.254.20:53 fail_timeout=15s max_fails=3;
}
server {
listen 53 udp reuseport;
proxy_timeout 20s;
proxy_pass dns;
}
}
创建目录:
[root@nginx nginx]# mkdir -p /usr/local/nginx/tcpconf.d
[root@nginx nginx]# cd /usr/local/nginx/conf.d
[root@nginx conf.d]#
[root@nginx conf.d]# mv dns.conf /usr/local/nginx/tcpconf.d/
[root@nginx tcpconf.d]# nginx -s reload
[root@nginx tcpconf.d]# netstat -antlupe | grep 53
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 0 25391 981/cupsd
tcp6 0 0 ::1:631 :::* LISTEN 0 25390 981/cupsd
udp 0 0 0.0.0.0:5353 0.0.0.0:* 70 23648 851/avahi-daemon: r
udp 0 0 0.0.0.0:53 0.0.0.0:* 0 86748 3832/nginx: master
udp6 0 0 :::5353 :::* 70 23649 851/avahi-daemon: r
[root@nginx tcpconf.d]#
此时就能解析到172.25.254.10和20了
[root@nginx tcpconf.d]# dig www.timingding.org @172.25.254.100
; <<>> DiG 9.16.23-RH <<>> www.timingding.org @172.25.254.100
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15189
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 8c6fc39065ed27c50100000066c23599d6924761de822212 (good)
;; QUESTION SECTION:
;www.timingding.org. IN A
;; ANSWER SECTION:
www.timingding.org. 86400 IN A 172.25.254.10
;; Query time: 1 msec
;; SERVER: 172.25.254.100#53(172.25.254.100)
;; WHEN: Sun Aug 18 13:55:37 EDT 2024
;; MSG SIZE rcvd: 91
[root@nginx tcpconf.d]# dig www.timingding.org @172.25.254.100
; <<>> DiG 9.16.23-RH <<>> www.timingding.org @172.25.254.100
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31342
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 33a6b4e9a5b11f920100000066c235be1ce27ff22fb787ad (good)
;; QUESTION SECTION:
;www.timingding.org. IN A
;; ANSWER SECTION:
www.timingding.org. 86400 IN A 172.25.254.20
;; Query time: 1 msec
;; SERVER: 172.25.254.100#53(172.25.254.100)
;; WHEN: Sun Aug 18 13:56:14 EDT 2024
;; MSG SIZE rcvd: 91
[root@nginx tcpconf.d]#
6.2.2.2 MySQL的四层负载均衡
安装数据库:
[root@nginx-node1 named]# dnf install mariadb-server -y
[root@nginx-node2 named]# dnf install mariadb-server -y
[root@nginx-node1 named]# vim /etc/my.cnf.d/mariadb-server.cnf
[root@nginx-node2 named]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=20(10) ---- 两台机子都加个ID,用于区分
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/run/mariadb/mariadb.pid
[root@nginx-node1 named]# systemctl start mariadb
[root@nginx-node2 named]# systemctl start mariadb
[root@nginx-node1 named]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 10.5.22-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE USER ding@'%' identified by 'ding';
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> GRANT ALL ON *.* to ding@'%';
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]>
172.25.254.100主机上面:
[root@nginx ~]#vim /usr/local/nginx/tcpconf.d/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 60;
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 88742 3832/nginx: master
[root@nginx tcpconf.d]# dnf install mariadb -y
[root@nginx tcpconf.d]# mysql -u ding -p -h 172.25.254.100
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.5.22-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> SELECT @@server_id
-> ;
+-------------+
| @@server_id |
+-------------+
| 10 |
+-------------+
1 row in set (0.001 sec)
MariaDB [(none)]>
再连一次:
[root@nginx tcpconf.d]# mysql -u ding -p -h 172.25.254.100
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.5.22-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> SELECT @@server_id;
+-------------+
| @@server_id |
+-------------+
| 20 |
+-------------+
1 row in set (0.001 sec)
MariaDB [(none)]>
6.3 FastCGI
PHP-FPM(FastCGI Process Manager:
- FastCGI进程管理器)是一个实现了Fastcgi的程序,并且提供进程管理的功能。
- 进程包括master进程和worker进程。master进程只有一个,负责监听端口,接受来自web server 的请求
- worker进程一般会有多个,每个进程中会嵌入一个PHP解析器,进行PHP代码的处理。
6.3.1 FastCGI配置指令
fastcgi_pass address:port;
转发请求到后端服务器, address 为后端的 fastcgi server 的地址,可用位置: location, if inlocationfastcgi_index name; -------- fastcgi默认的主页资源,示例: fastcgi_index index.php;fastcgi_param parameter value [if_not_empty];设置传递给FastCGI 服务器的参数值,可以是文本,变量或组合,可用于将 Nginx 的内置变量赋值给自定义keyfastcgi_param REMOTE_ADDR $remote_addr; ----------- 客户端源 IPfastcgi_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
6.3.2 Nginx与php-fpm在同一服务器
6.3.2.1 源码编译php
源码编译Nginx:
安装Nginx编译所需的依赖性:
[root@nginx nginx-1.26.1]# dnf install gcc pcre-devel zlib-devel openssl-devel -y
[root@nginx ~]# cd nginx-1.26.1/
[root@nginx nginx-1.26.1]# useradd -s /sbin/nologin -M nginx
[root@nginx nginx-1.26.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --add-module=/root/echo-nginx-module-0.63 --add-module=/root/memc-nginx-module-0.20 --add-module=/root/srcache-nginx-module-0.33
[root@nginx nginx-1.26.1]# make && make install
[root@nginx ~]# vim auto/cc/gcc
# debug
#CFLAGS="$CFLAGS -g"
[root@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 ---- 添加这个
[root@nginx ~]# source ~/.bash_profile
[root@nginx ~]# cd /usr/local/nginx/sbin/
[root@nginx sbin]# ./nginx
源码编译php:
安装所需依赖性:
[root@nginx ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel
[root@nginx ~]# yum install libcurl-devel-7.76.1-29.el9_4.x86_64
[root@nginx ~]# wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
[root@nginx ~]# yum install oniguruma-devel
解压源码并开始安装:
[root@nginx ~]# cd php-8.3.9/
[root@nginx php-8.3.9]# ./configure --prefix=/usr/local/php \
> --with-config-file-path=/usr/local/php/etc \
> --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 php-8.3.9]# make && make install
[root@nginx php-8.3.9]# vim /usr/local/nginx/conf/nginx.conf
建议写到http后面
include "/usr/local/nginx/conf.d/*.conf";
[root@nginx conf]# mkdir -p /usr/local/nginx/conf.d/
php相关配置优化:
[root@nginx php-8.3.9]# cd /usr/local/php/etc/
[root@nginx etc]# cp php-fpm.conf.default php-fpm.conf
[root@nginx etc]# vim php-fpm.conf
[global]
; Pid file
; Note: the default prefix is /usr/local/php/var
; Default Value: none
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]# vim 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 php-8.3.9]# 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 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 daemon-reload
[root@nginx php-8.3.9]# systemctl start php-fpm.service
[root@nginx php-8.3.9]# netstat -antlupe | grep php
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 0 201110 149942/php-fpm: mas
[root@nginx php-8.3.9]#
6.3.2.2 Nginx和php整合
把php路径添加到环境变量中:
[root@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 ~]# source ~/.bash_profile
创建php目录,存放php页面
[root@nginx ~]# mkdir -p /data/web/php
[root@nginx bin]# vim /data/web/php/index.php
<?php
phpinfo();
?>
[root@nginx php]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.xiaoding.org;
root /data/web/php;
index index.html;
location ~ \.php$ {
fastcgi_pass 0.0.0.0:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}
[root@nginx php]# nginx -s reload
网页访问:www.xiaoding.org/index.php/
6.3.3 Nginx-php的缓存优化
安装memcache模块并解压
[root@nginx ~]# tar zxf memcache-8.2.tgz
[root@nginx ~]# cd memcache-8.2/
[root@nginx memcache-8.2]# yum install autoconf
[root@nginx memcache-8.2]# phpize ---- 用来生成configure file
Configuring for:
PHP Api Version: 20230831
Zend Module Api No: 20230831
Zend Extension Api No: 420230831
[root@nginx memcache-8.2]#
[root@nginx memcache-8.2]# ./configure && make && make install
查看是否生成模块:
[root@nginx ~]# cd /usr/local/php/lib/php/extensions/no-debug-non-zts-20230831/
[root@nginx no-debug-non-zts-20230831]# ls
memcache.so opcache.so
[root@nginx no-debug-non-zts-20230831]# cd
[root@nginx ~]# systemctl restart php-fpm.service
配置php加载memcache模块
[root@nginx ~]# vim /usr/local/php/etc/php.ini
;extension=soap
;extension=sockets
;extension=sodium
;extension=sqlite3
;extension=tidy
;extension=xsl
;extension=zip
;zend_extension=opcache
extension=memcache ---------- 加上memcache模块
;;;;;;;;;;;;;;;;;;;
; Module Settings ;
;;;;;;;;;;;;;;;;;;;
[root@nginx ~]# systemctl restart php-fpm.service
复制测试文件到nginx发布目录中
[root@nginx memcache-8.2]# cp example.php memcache.php /data/web/php/ ---- 模拟向memcache发送数据,看效果
[root@nginx memcache-8.2]# vim /data/web/php/memcache.php
安装memcache模块
[root@nginx ~]# dnf install memcached -y
[root@nginx ~]# systemctl enable --now memcached.service
Created symlink /etc/systemd/system/multi-user.target.wants/memcached.service → /usr/lib/systemd/system/memcached.service.
[root@nginx ~]#
[root@nginx ~]# vim /etc/sysconfig/memcached ------ 查看信息
[root@nginx ~]# systemctl start memcached.service
[root@nginx ~]# netstat -antlupe | grep mem ---- 查看端口是否开启
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 980 192566 187646/memcached
tcp6 0 0 ::1:11211 :::* LISTEN 980 192567 187646/memcached
[root@nginx ~]#
去网页访问:http://www.xiaoding.org/example.php
http://www.xiaoding.org/memcache.php
http://www.xiaoding.org/example.php
这个网页刷新的越多,memcache网页绿色柱状就会越多
绿色表示直接从memcache中取的值,橙色的表示不在memcache里,从外面取的值。
压测查看:
内存比较小,看不出来什么效果
[root@nginx ~]# ab -n1000 -c10 http://www.xiaoding.org/index.php
再来一次
[root@nginx ~]# ab -n1000 -c10 http://www.xiaoding.org/index.php
6.3.3.1 Nginx-memcache高速缓存
示例:
[root@nginx ~]# vim /usr/local/nginx/conf.d/php.conf
upstream memcache{
server 127.0.0.1:11211;
keepalive 512;
}
server {
listen 80;
server_name www.xiaoding.org;
root /data/web/php;
index index.html;
location /memc {
internal;
memc_connect_timeout 100ms;
memc_send_timeout 100ms;
memc_read_timeout 100ms;
set $mem_key $query_string;
set $memc_exptime 300;
memc_pass memcache;
}
location ~ \.php$ {
set $key $uri$args;
srcache_fetch GET /memc $key;
srcache_store PUT /memc $key;
fastcgi_pass 172.25.254.120:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}
[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
再进行压测:
ab -n500 -c10 http://www.xiaoding.org/index.php
七、 Nginx-二次开发版本
7.1 openresty
7.2 编译安装openresty
示例:
[root@nginx ~]# nginx -s stop ---- 停掉Nginx,别让它占用80端口
[root@nginx ~]# netstat -antlupe | grep nginx
[root@nginx ~]#
[root@nginx ~]# tar zxf openresty-1.25.3.1.tar.gz
[root@nginx ~]# cd openresty-1.25.3.1/
[root@nginx openresty-1.25.3.1]# dnf -y install gcc pcre-devel openssl-devel perl
[root@nginx openresty-1.25.3.1]# cd /usr/local/src
[root@nginx src]# wget https://openresty.org/download/openresty-1.17.8.2.tar.gz
编译安装openresty
[root@nginx openresty-1.25.3.1]# ./configure --prefix=/usr/local/openresty --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-http_sub_module --without-http_memcached_module --with-stream_realip_module
[root@nginx openresty-1.25.3.1]# make && make install
[root@nginx 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 -antlupe | grep 80
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 980 206856 187885/memcached
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 255222 211989/nginx: maste
tcp 0 0 0.0.0.0:9000 0.0.0.0:* LISTEN 0 230905 188036/php-fpm: mas
tcp6 0 0 ::1:11211 :::* LISTEN 980 206857 187885/memcached
udp 0 0 0.0.0.0:5353 0.0.0.0:* 70 24380 850/avahi-daemon: r
[root@nginx bin]#
网页访问172.25.254.120