Nginx 配置要点与最佳实践
文章目录
一、Web服务器基本介绍
1.1 Web服务器内容
Web 服务器是一种在网络上运行的软件或硬件设备,其主要功能是接收来自客户端(通常是 Web 浏览器)的 HTTP 请求,并根据请求提供相应的 Web 资源(如 HTML 页面、图片、视频、文件等)。
Web 服务器的工作步骤:
监听网络端口
:通常监听 80(HTTP)或 443(HTTPS)端口,等待客户端发送的连接请求。接收请求
:当客户端发起请求时,Web 服务器接收请求消息,其中包含了请求的方法(如 GET、POST 等)、请求的 URL 以及其他相关的头信息。处理请求
:Web 服务器解析请求,并根据请求的 URL 和服务器的配置来确定要提供的资源。获取资源
:从服务器的文件系统、数据库或其他数据源获取所请求的资源。生成响应
:将获取到的资源转换为 HTTP 响应消息,包括响应状态码(如 200 表示成功,404 表示未找到等)、响应头和响应体(即实际的资源内容)。发送响应
:将生成的响应通过网络发送回客户端。
处理类型
-
静态资源
:不用处理,通过磁盘可以直接获取。内容不依赖于服务器端的实时处理和生成,其内容在服务器上是固定不变的。 -
动态资源
:需要处理,对代码进行解析,把结果传递给web服务器。则需要服务器端在接收到请求时进行实时的处理和生成。例如,通过服务器端脚本语言(如 PHP、Python、Java 等)生成的网页内容、根据用户请求从数据库中获取并动态构建的页面等。Web 服务器会将对动态资源的请求转发给相应的应用服务器或脚本解释器进行处理,然后将生成的动态内容返回给客户端。
1.2 Web服务器分类
名称 | 介绍 |
---|---|
Apache HTTP Server | 是一款广泛使用的开源 Web 服务器,具有丰富的功能和强大的扩展性。 例如,许多大型网站和企业级应用都选择 Apache 作为其 Web 服务器。 |
Nginx | 以高性能和低资源消耗著称,常用于高并发场景和反向代理。 像一些知名的互联网公司,如腾讯、淘宝等,都在其架构中大量使用了 Nginx。 |
IIS(Internet Information Services) | 是微软开发的 Windows 平台下的 Web 服务器。 常用于运行基于 Windows Server 操作系统的网站和应用程序。 |
Lighttpd | 一款轻量级的 Web 服务器,对内存和 CPU 资源的需求较小。 |
Tomcat | 主要用于运行 Java Servlet 和 JavaServer Pages(JSP)的 Web 应用程序。 |
Jetty | 也是一个基于 Java 的 Web 服务器,常用于小型和中型项目。 |
Gunicorn | 常与 Python Web 框架(如 Django、Flask 等)配合使用。 |
Node.js | 不仅可以用于编写服务器端的 JavaScript 应用,也可以作为 Web 服务器使用。 |
二、 Apache
prefork模型
工作流程: Prefork 模式是 Apache HTTP 服务器的一种多进程工作模式。在这种模式下,服务器会预先启动多个子进程。每个子进程在等待连接请求到来时处于空闲状态。当有新的连接请求时,系统会分配一个空闲的子进程来处理该请求。
优点:
稳定性高
:由于每个请求都由独立的子进程处理,一个进程的故障不会影响到其他进程,从而提高了服务器的稳定性。
例如,如果某个子进程出现崩溃,其他子进程仍能继续处理请求,不会导致整个服务器瘫痪。兼容性好
:对于一些不支持线程安全的模块和应用程序,Prefork 模式能够很好地兼容。资源隔离
:每个子进程都有自己独立的资源,包括内存空间等,避免了资源竞争和冲突。
缺点:
资源消耗大
:因为预先启动了多个子进程,会消耗较多的系统资源,如内存。例如,在高并发场景下,大量的子进程可能会导致系统内存不足。并发处理能力有限
:由于进程创建和切换的开销较大,Prefork 模式在处理大量并发请求时的性能可能不如其他模式。扩展性较差
:随着并发请求的增加,需要不断增加子进程的数量,可能会受到系统资源的限制。
worker模型
工作流程:Worker 模式使用了多进程与多线程的混合模型。服务器启动时会创建多个进程,每个进程会创建一定数量的线程。每个线程都可以处理连接请求。
优点:
资源利用率高
:相较于 Prefork 模式,Worker 模式在处理并发请求时,由于线程比进程更轻量级,资源消耗相对较少,能够更好地利用系统资源。例如,在相同的硬件配置下,可以处理更多的并发连接。并发处理能力强
:因为线程切换的开销小于进程切换,所以在高并发场景下,能够更快速地响应请求。内存使用更优化
:由于线程共享进程的资源,减少了内存的重复占用。
缺点:
稳定性稍逊
:一个线程的崩溃可能会影响到同一进程中的其他线程。比如,一个线程出现内存泄漏,可能导致同一进程内的其他线程也受到影响。线程安全问题
:对于一些不是线程安全的模块,可能会出现问题。调试和错误排查相对复杂
:由于线程之间的交互较为复杂,当出现问题时,调试和错误排查的难度较大。
event模型
工作流程:Event 模式是在 Apache 2.4 版本中引入的一种新的工作模式。它基于事件驱动机制,使用异步非阻塞的方式来处理连接请求。 在这种模式下,会有一个主线程不断地接收新的连接请求,并将其分配给可用的工作线程。同时,它还会处理一些事件,如读事件和写事件。当一个连接处于等待数据的状态时,不会阻塞其他连接的处理,从而提高了服务器的并发处理能力和资源利用率。
优点:
高并发性能出色
:能够处理大量的并发连接,特别适合高并发的场景。资源利用高效
:减少了不必要的阻塞,充分利用系统资源。响应迅速
:能够快速处理请求,减少了请求的等待时间。
缺点:
配置复杂
:需要更精细的配置来优化性能,对于新手来说可能具有一定的难度。兼容性问题
:某些旧的模块可能不兼容 Event 模式。依赖系统支持
:对操作系统的异步 I/O 支持有一定要求,如果系统不支持,可能无法发挥其最佳性能。
关于Apache服务的基本配置和解析见文章
基础服务:http://t.csdnimg.cn/byYcg
高级配置:http://t.csdnimg.cn/CtJj3
三、 Nginx
Nginx 是一款轻量级的高性能 Web 服务器、反向代理服务器以及电子邮件(IMAP/POP3)代理服务器。
3.1 I/O
I/O是Input/Output,即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一。IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处理的I/O请求数量为单位,I/O请求通常为读或写数据操作请求。
- 磁盘I/O
磁盘 I/O 主要涉及对磁盘的读写操作。当计算机系统需要从磁盘读取数据时,就会发起一个磁盘输入操作,例如当你打开一个存储在硬盘上的文件时,操作系统会从磁盘中读取该文件的数据并加载到内存中供程序使用。而当需要将数据保存到磁盘时,就会进行磁盘输出操作,比如保存一个文档到硬盘。
7200转 10000转 15000转 指的是每分钟的转速
IOPS即每秒的输入输出操作次数。计算每秒最大 IOPS 的方法会因存储设备类型和使用场景的不同而有所差异,以下是一些常见的计算方法及考虑因素。
· IOPS = 1000 /(平均寻道时间 + 平均旋转延迟)
- 网络I/O
网络 I/O 主要涉及计算机系统通过网络进行数据的接收和发送操作。当计算机系统从网络上接收数据时,这是一个网络输入操作;而当系统向网络发送数据时,就是网络输出操作。例如,当你在浏览器中访问一个网页时,你的计算机就会通过网络 I/O 从服务器接收网页的数据。
一切皆文件,本质为对socket文件的读写
3.2 I/O模型
- 事件驱动机制
NGINX 启动后,会创建一个主进程(Master Process)和多个工作进程(Worker Process)。主进程主要负责管理工作进程,如读取配置文件、启动工作进程、平滑升级等。工作进程负责实际的请求处理。
工作进程使用事件驱动机制来高效处理网络连接和请求。它会将网络套接字(Socket)设置为非阻塞模式,这样当进行 I/O 操作(如读取客户端请求或向客户端发送响应)时,如果当前没有数据可读或可写,不会阻塞等待,而是立即返回并继续处理其他事件。
工作进程会不断地检查和处理各种事件,如连接建立事件、可读事件(客户端发送了数据)、可写事件(可以向客户端发送响应)等。通过这种方式,NGINX 可以在一个工作进程中同时处理大量的连接,而不会因为某个连接的阻塞而影响其他连接的处理。
- 异步处理
当一个新的连接建立时,工作进程会快速接受连接,并将其添加到事件队列中等待后续处理。当有可读事件发生时,工作进程会快速读取客户端请求数据,并进行请求解析和处理。如果请求需要访问后端服务器获取数据,NGINX 会发起异步的后端连接,并继续处理其他事件,而不是等待后端服务器的响应。
当后端服务器返回数据时,会触发可写事件,工作进程会将数据写入客户端连接,并继续处理其他事件。这种异步处理方式使得 NGINX 可以在处理大量并发连接时保持高效,不会因为等待某个操作的完成而浪费时间。
- 高效的内存管理
NGINX 在处理请求时,会尽量减少内存复制操作。例如,当读取客户端请求数据时,会直接将数据读取到预先分配的内存缓冲区中,避免不必要的内存复制。在向客户端发送响应时,也会尽量使用高效的内存管理策略,减少内存分配和释放的开销。
总之,NGINX 的 I/O 模型通过事件驱动的异步非阻塞机制和高效的内存管理,能够在处理大量并发连接时保持高性能和低资源消耗,成为一款非常高效的 Web 服务器和反向代理服务器。
- 阻塞型I/O模型(blocking IO)
阻塞型 I/O 模型是一种常见的输入/输出模型。在这种模型下,当一个进程发起一个 I/O 操作时,例如读取文件或从网络接收数据,进程会被阻塞,直到这个 I/O 操作完成。
当进程调用一个 I/O 函数(如 read、recvfrom 等)时,进程会进入等待状态。此时,内核会开始处理这个 I/O 请求,从外部设备(如磁盘、网络等)读取数据或者向外部设备写入数据。在这个过程中,进程一直处于阻塞状态,不能进行其他操作。只有当内核完成 I/O 操作,并将数据准备好后,进程才会被唤醒,继续执行后续的代码。
特点
简单直观
:实现相对简单,易于理解和编程。同步操作
:进程在进行 I/O 操作时是同步的,必须等待 I/O 操作完成才能继续执行。低效率
:在 I/O 操作期间,进程被阻塞,无法进行其他有用的工作,这可能导致系统的整体性能较低,特别是在处理大量并发 I/O 请求时。
- 非阻塞型I/O(nonblocking IO)
非阻塞型 I/O 模型是一种与阻塞型 I/O 模型相对的输入/输出处理方式。
在非阻塞型 I/O 模型中,当进程发起一个 I/O 操作时,系统不会让进程进入阻塞状态等待 I/O 操作完成。相反,系统会立即返回一个结果,告诉进程 I/O 操作是否已经完成。如果 I/O 操作还没有完成,进程可以选择继续执行其他任务,或者稍后再次检查 I/O 操作的状态。
例如,当进程调用一个非阻塞的 read 函数读取文件时,如果此时文件中的数据还没有准备好,read 函数会立即返回一个错误码,表示数据不可读。进程可以根据这个错误码判断 I/O 操作没有完成,然后继续执行其他代码,过一段时间后再次尝试读取文件。
特点
高效性
:进程不会因为等待 I/O 操作而被阻塞,能够充分利用 CPU 时间执行其他任务,提高系统的整体效率。复杂性增加
:由于需要不断地检查 I/O 操作的状态,编程相对复杂。而且频繁地检查状态可能会消耗较多的 CPU 资源。适用于并发场景
:特别适合处理大量并发的 I/O 请求,因为进程可以在等待 I/O 操作完成的同时处理其他请求。
- 多路复用I/O型(I/O multiplexing)
多路复用 I/O 模型是一种高效处理多个 I/O 操作的输入/输出模型。
多路复用 I/O 主要通过一个特殊的系统调用(如 select、poll、epoll 等)来实现。这个系统调用可以同时监视多个文件描述符(代表着不同的 I/O 资源,如网络连接、文件等)的状态,判断是否有数据可读、可写或出现错误。 当进程调用这个系统调用时,进程会被阻塞,直到有一个或多个文件描述符的状态发生变化。一旦有文件描述符状态改变,系统会通知进程,进程便可以针对这些发生变化的文件描述符进行相应的 I/O 操作。 例如,在一个网络服务器中,服务器进程可以使用多路复用 I/O 同时监视多个客户端连接的文件描述符。当某个客户端发送数据过来时,对应的文件描述符状态发生变化,服务器进程就可以读取该连接上的数据并进行处理。
特点
高效性
:能够同时处理多个 I/O 操作,避免了为每个 I/O 操作都创建一个单独的线程或进程,从而减少了系统资源的消耗,提高了系统的性能和可扩展性。事件驱动
:进程是基于事件(文件描述符状态变化)来进行 I/O 操作的,这种事件驱动的方式使得程序的逻辑更加清晰,易于维护。适用于高并发场景
:特别适合处理大量并发连接的情况,如高并发的网络服务器、数据库服务器等。
- 信号驱动式I/O模型 (signal-driven IO)
信号驱动式 I/O 模型是一种特殊的输入/输出处理方式。
在信号驱动式 I/O 模型中,进程首先通过系统调用安装一个信号处理函数,然后发起一个 I/O 操作。当内核完成 I/O 操作时,会发送一个信号给进程。进程接收到信号后,便可以在信号处理函数中进行相应的 I/O 操作处理。
例如,一个进程要从网络中接收数据。它先安装一个信号处理函数用于接收数据完成的信号,然后发起接收数据的请求。此时进程不会被阻塞,而是继续执行其他任务。当网络数据到达并被内核接收并存入缓冲区后,内核会发送一个信号给进程。进程接收到信号后,在信号处理函数中从缓冲区读取数据进行处理。
特点
异步通知
:通过信号机制实现异步通知,进程不需要主动轮询或阻塞等待 I/O 操作完成,提高了进程的响应速度和效率。编程复杂
:需要处理信号的安装、信号处理函数的编写等,编程相对复杂。而且信号的处理可能会受到其他信号的干扰,需要谨慎处理。适用于特定场景
:对于那些需要及时响应 I/O 事件,但又不希望被阻塞或频繁轮询的应用场景比较适用。
- 异步 I/O 模型 (asynchronous IO)
异步 I/O 模型是一种高效的输入/输出处理方式。
在异步 I/O 模型中,当进程发起一个 I/O 操作后,立即返回,不会被阻塞。内核会在 I/O 操作完成后,通知进程。进程可以在等待 I/O 操作完成的时间里执行其他任务。 具体来说,进程调用异步 I/O 函数(如 aio_read、aio_write 等)发起一个 I/O 操作,并提供一个回调函数。当内核完成 I/O 操作后,会调用这个回调函数通知进程 I/O 操作的结果。
例如,一个进程要从磁盘读取一个文件。它发起异步读取请求后,就可以继续处理其他任务。当磁盘读取完成后,内核会调用进程提供的回调函数,通知进程文件读取完成,并将读取的数据传递给进程。
特点
- 真正的异步操作:进程在发起 I/O 操作后完全不需要等待,可以继续执行其他任务,直到内核通知 I/O 操作完成。这与其他模型(如阻塞型、非阻塞型、多路复用型和信号驱动型)有很大的区别,那些模型在某种程度上仍然需要进程主动检查或等待 I/O 操作的状态。
- 高效性:充分利用了系统资源,提高了系统的整体性能。特别是在处理大量并发 I/O 请求时,异步 I/O 模型可以显著提高系统的吞吐量和响应速度。
- 编程复杂:异步编程通常比同步编程更加复杂,需要处理回调函数、错误处理、并发控制等问题。而且不同的操作系统对异步 I/O 的支持程度也不一样,这增加了跨平台开发的难度。
3.3 Nginx进程结构
web请求处理机制
多进程方式
:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求
多线程方式
:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程和此客户端进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。
3.4 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
#发送信号,reload信号 会生成新的worker,但master不会重新生成
-s signal : send signal to a master process: stop, quit, reopen, reload
-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
#设置全局指令,注意和配置文件不要同时配置,否则冲突
3.5 Nginx启动文件
[root@Nginx01 ~]# vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root@Nginx ~]# systemctl daemon-reload
[root@Nginx ~]# systemctl start nginx
四、实验
源码编译
#在主机中创建nginx目录
[root@Nginx01 ~]# mkdir /nginx
#进入/nginx目录将nginx1.24的压缩包移入该目录下,解压
[root@Nginx01 ~]# cd /nginx/
[root@Nginx01 nginx]# tar zxf nginx-1.24.0.tar.gz
#下载需要的软件包
[root@Nginx01 nginx]# dnf install gcc pcre-devel zlib-devel openssl-devel -y
#进入解压后的目录,执行环境检测和模块安装命令
[root@Nginx01 nginx]# cd nginx-1.24.0/
[root@Nginx01 nginx-1.24.0]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src
[root@Nginx01 nginx-1.24.0]# ./configure --prefix=/usr/local/nginx
--user=nginx \ # 指定nginx运行用户
--group=nginx \ # 指定nginx运行组
--with-http_ssl_module \ # 支持https://
--with-http_v2_module \ # 支持http版本2
--with-http_realip_module \ # 支持ip透传
--with-http_stub_status_module \ # 支持状态页面
--with-http_gzip_static_module \ # 支持压缩
--with-pcre \ # 支持正则
--with-stream \ # 支持tcp反向代理
--with-stream_ssl_module # 支持tcp的ssl加密
#编译模块make,make install 将objs的文件内容拷贝到指定位置
[root@Nginx01 nginx-1.24.0]# make && make install
[root@Nginx01 nginx-1.24.0]# ls #生成了Makefile文件和objs文件
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README
#关闭debug功能
[root@Nginx01 nginx-1.24.0]# vim auto/cc/gcc
# debug
#CFLAGS="$CFLAGS -g"
#将nginx命令配置在环境变量中
[root@Nginx01 ~]# vim ~/.bash_profile
export PATH=$PATH:/usr/local/nginx/sbin
[root@Nginx01 ~]# source ~/.bash_profile
#为Nginx创建用户
[root@Nginx01 ~]#useradd -s /sbin/nologin -M nginx
#启动nginx
[root@Nginx01 ~]# nginx
#查看nginx版本
[root@Nginx01 ~]# nginx -v
nginx version: nginx/1.24.0
#查看nginx进程
[root@Nginx01 ~]# ps aux | grep nginx
#查看nginx端口
[root@Nginx01 ~]# netstat -lnput | grep 80
#测试
[root@Nginx01 ~]# curl 172.25.250.200
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
平滑升级
#在/nginx的目录中添加1.26.2版本和“echo-nginx-module-0.63.tar.gz”的压缩包,并解压
[root@Nginx01 nginx]# ll
总用量 2360
drwxrwxr-x 5 root root 174 8月 1 2022 echo-nginx-module-0.63
-rw-r--r-- 1 root root 53421 8月 15 13:21 echo-nginx-module-0.63.tar.gz
drwxr-xr-x 9 nginx nginx 186 8月 18 15:18 nginx-1.24.0
-rw-r--r-- 1 root root 1112471 8月 15 10:54 nginx-1.24.0.tar.gz
drwxr-xr-x 8 502 games 158 5月 29 22:30 nginx-1.26.1
-rw-r--r-- 1 root root 1244738 8月 15 11:39 nginx-1.26.1.tar.gz
#进入1.26的文件,编译并添加模块
[root@Nginx01 nginx-1.26.1]# ./configure --prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--add-module=/nginx/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
#备份原本的nginx版本
[root@Nginx01 sbin]# cp nginx nginx.24
#将1.26版本的nginx复制到该目录下
[root@Nginx01 sbin]# \cp -f /nginx/nginx-1.26.1/objs/nginx /usr/local/nginx/sbin/
#查看当前nginx进程
[root@Nginx01 sbin]# ps aux | grep nginx
root 46728 0.0 0.1 9896 1936 ? Ss 16:11 0:00 nginx: master process nginx
nginx 46729 0.0 0.2 14240 5008 ? S 16:11 0:00 nginx: worker process
root 46842 0.0 0.1 221680 2304 pts/1 S+ 16:18 0:00 grep --color=auto nginx
#创建新进程
[root@Nginx01 sbin]# kill -USR2 46728
#再次查看nginx进程
[root@Nginx01 sbin]# ps aux | grep nginx
root 46728 0.0 0.1 9896 2448 ? Ss 16:11 0:00 nginx: master process nginx
nginx 46729 0.0 0.2 14240 5008 ? S 16:11 0:00 nginx: worker process
root 46843 0.0 0.3 9764 6528 ? S 16:18 0:00 nginx: master process nginx
nginx 46844 0.0 0.2 14228 5004 ? S 16:18 0:00 nginx: worker process
root 46846 0.0 0.1 221680 2304 pts/1 S+ 16:18 0:00 grep --color=auto nginx
#查看nginx版本
[root@Nginx01 sbin]# nginx -v
nginx version: nginx/1.26.1
平滑升级成功
页面部署
#编辑nginx配置文件
[root@Nginx01 ~]# vim /usr/local/nginx/conf/nginx.conf
... ...
events {
worker_connections 100000;
use epoll;
}
... ...
#gzip on;
include "/usr/local/nginx/conf.d/*.conf";
#创建nginx目录,便于配置
[root@Nginx01 ~]# mkdir /data/web/html -p
[root@Nginx01 ~]# mkdir /data/web/test01 -p
[root@Nginx01 ~]# echo "This is a test." > /data/web/html/index.html
[root@Nginx01 ~]# echo "This is test page one ." > /data/web/test01/index.html
#创建配置文件目录
[root@Nginx01 ~]# mkdir -p /usr/local/nginx/conf.d
[root@Nginx01 ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.hahaha01.com;
root /data/web/html;
index index.html;
location /test01/ {
root /data/web;
}
}
#检测配置文件,重启nginx
[root@Nginx01 ~]# 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@Nginx01 ~]# nginx -s reload
#Windows系统中做本地解析
172.25.250.200 www.hahaha01.com
#网页测试结果如下
用户加密
#创建管理员账户
[root@Nginx01 ~]# htpasswd -cm /usr/local/nginx/.htpasswd admin
New password:
Re-type new password:
Adding password for user admin
#查看密码是否生效
[root@Nginx01 ~]# cat /usr/local/nginx/.htpasswd
admin:$apr1$9PpQbEZy$PXt0S7n6tUxMch4/L6Eh61
#创建普通用户
[root@Nginx01 ~]# htpasswd -cm /usr/local/nginx/.htpasswd yin
New password:
Re-type new password:
Adding password for user yin
#检测密码
[root@Nginx01 ~]# cat /usr/local/nginx/.htpasswd
yin:$apr1$UaKxaus5$f5oStK27hK6UgyDEPs4pe/
#创建普通用户网页目录
[root@Nginx01 ~]# mkdir /data/web/yin
[root@Nginx01 ~]# echo yin > /data/web/yin/index.html
#编辑配置文件
[root@Nginx01 ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.hahaha01.com;
root /data/web/html;
index index.html;
location /yin {
root /data/web;
auth_basic "input your password!";
auth_basic_user_file "/usr/local/nginx/.htpasswd";
}
}
#重启nginx
[root@Nginx01 ~]# nginx -s reload
#测试
自定义错误页面
#编辑配置文件
[root@Nginx01 ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.hahaha01.com;
root /data/web/html;
index index.html;
error_page 404 /40x.html;
location /yin {
root /data/web;
auth_basic "input your password!";
auth_basic_user_file "/usr/local/nginx/.htpasswd";
}
location = /40x.html {
root /data/web/errorpage;
}
}
#创建错误页面目录
[root@Nginx01 ~]# mkdir -p /data/web/errorpage
[root@Nginx01 ~]# echo Wrong Page. > /data/web/errorpage/40x.html
#重启nginx
[root@Nginx01 ~]# nginx -s reload
#查看nginx页面目录
[root@Nginx01 ~]# cd /data/web/
[root@Nginx01 web]# ls
errorpage html test test01 yin
#网页测试
自定义日志
#编辑配置文件
[root@Nginx01 ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.hahaha01.com;
root /data/web/html;
index index.html;
error_page 404 /40x.html;
error_log /var/log/hahaha01/error.log;
access_log /var/log/hahaha01/access.log;
location /yin {
root /data/web;
auth_basic "input your password!";
auth_basic_user_file "/usr/local/nginx/.htpasswd";
}
location = /40x.html {
root /data/web/errorpage;
}
}
#创建日志目录
[root@Nginx01 ~]# mkdir /var/log/hahaha01.org
#重启nginx
[root@Nginx01 ~]# nginx -s reload
#添加本地解析
[root@Nginx01 ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.250.200 Nginx01.example.com
172.25.250.200 www.hahaha01.org
#测试
[root@Nginx01 ~]# curl www.hahaha01.com
www.hahaha01.org
[root@Nginx01 ~]# cat /var/log/hahaha01.com/access.log
172.25.250.200 - - [17/Aug/2024:14:37:52 +0800] "GET / HTTP/1.1" 200 14 "-"
"curl/7.76.1"
[root@Nginx01 ~]# curl www.hahaha01.com/123
error page
[root@Nginx01 ~]# cat /var/log/qwert.org/error.log
2024/08/19 16:38:26 [error] 56859#0: *10258 open() "/data/web/html/123" failed
(2: No such file or directory), client: 172.25.250.200, server: www.hahaha01.com,
request: "GET /123 HTTP/1.1", host: "www.hahaha01.com"
文件检测
#编辑配置文件
[root@Nginx01 ~]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
server_name www.hahaha01.com;
root /data/web/html;
index index.html;
error_page 404 /40x.html;
error_log /var/log/www.hahaha01.com/error.log;
access_log /var/log/www.hahaha01.com/access.log;
try_files $uri $uri.html $uri/index.html /error/default.html;
location /yin {
root /data/web;
auth_basic "input your password!";
auth_basic_user_file "/usr/local/nginx/.htpasswd";
}
location = /40x.html {
root /data/web/errorpage;
}
}
#重启nginx
[root@Nginx01 ~]# nginx -s reload
#测试
[root@Nginx01 ~]# curl www.hahaha01.com
www.hahaha01.com
[root@Nginx01 ~]# rm -rf /data/web/html/index.html
[root@Nginx01 ~]# rm -rf /data/web/html/error
[root@Nginx01 ~]# curl www.qwert.org
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.26.1</center>
</body>
</html>
[root@Nginx01 ~]# mkdir -p /data/web/html/error
[root@Nginx01 ~]# echo error default > /data/web/html/error/default.html
[root@Nginx01 ~]# curl www.hahaha01.com
error default
状态页
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
上面三个数字分别对应accepts,handled,requests三个值
Reading: 6 Writing: 179 Waiting: 106
Active connections: #当前处于活动状态的客户端连接数
#包括连接等待空闲连接数=reading+writing+waiting
accepts: #统计总值,Nginx自启动后已经接受的客户端请求连接的总数。
handled: #统计总值,Nginx自启动后已经处理完成的客户端请求连接总数,通常等于accepts,除非有因
worker_connections限制等被拒绝的连接
requests: #统计总值,Nginx自启动后客户端发来的总的请求数
Reading: #当前状态,正在读取客户端请求报文首部的连接的连接数,数值越大,说明排队现象严重,性能不
足
Writing: #当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明访问量很大
Waiting: #当前状态,正在等待客户端发出请求的空闲连接数
开启 keep-alive的情况下,这个值等于active –(reading+writing)
配置
[root@Nginx01 ~]# cd /usr/local/nginx/conf.d/
[root@Nginx01 conf.d]# vim status.conf
server {
listen 80;
server_name status.qwert.org;
root /data/web/html;
index index.html;
location /status {
stub_status;
}
}
[root@Nginx01 conf.d]# nginx -s reload
#在Windows主机中添加本地解析
172.25.250.200 www.hahaha01.com
数据压缩
#启用或禁用gzip压缩,默认关闭
gzip on | off;
#压缩比由低到高从1到9,默认为1,值越高压缩后文件越小,但是消耗cpu比较高。基本设定未4或者5
gzip_comp_level 4;
#禁用IE6 gzip功能,早期的IE6之前的版本不支持压缩
gzip_disable "MSIE [1-6]\.";
#gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
#启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
#指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
#如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”,一般建议打开
gzip_vary on | off;
#预压缩,即直接从磁盘找到对应文件的gz后缀的式的压缩文件返回给用户,无需消耗服务器CPU
#注意: 来自于ngx_http_gzip_static_module模块
gzip_static on | off;
部署
[root@Nginx01 ~]# vim /usr/local/nginx/conf/nginx.conf
... ...
#keepalive_timeout 0;
keepalive_timeout 65 60;
keepalive_requests 2;
gzip on; # 打开压缩功能
gzip_comp_level 5;
gzip_min_length 1k;
gzip_http_version 1.1;
gzip_vary on;
gzip_types text/plain application/javascript application/x-javascript
text/css application/xml text/javascript application/x-httpd-php image/gif
image/png;
... ...
[root@Nginx01 ~]# 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@Nginx01 ~]# nginx -s reload
[root@Nginx01 ~]# echo hello hello > /data/web/html/small.html
[root@Nginx01 ~]# du -sh /usr/local/nginx/logs/access.log
1.1M /usr/local/nginx/logs/access.log
[root@Nginx01 ~]# cat /usr/local/nginx/logs/access.log > /data/web/html/02.html
#测试
[root@Nginx01 ~]# curl --head --compressed 172.25.250.200/01.html
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Sat, 17 Aug 2024 08:40:39 GMT
Content-Type: text/html
Content-Length: 12
Last-Modified: Sat, 17 Aug 2024 08:37:51 GMT
Connection: keep-alive
Keep-Alive: timeout=60
ETag: "66c0615f-c"
Accept-Ranges: bytes
[root@Nginx01 ~]# curl --head --compressed 172.25.250.200/02.html
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Sat, 17 Aug 2024 08:40:46 GMT
Content-Type: text/html
Last-Modified: Sat, 17 Aug 2024 08:39:14 GMT
Connection: keep-alive
Keep-Alive: timeout=60
Vary: Accept-Encoding
ETag: W/"66c061b2-106ac8"
Content-Encoding: gzip
全站加密
[root@Nginx01 ~]# cd /usr/local/nginx/
[root@Nginx01 nginx]# mkdir certs
[root@Nginx01 nginx]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout
/usr/local/nginx/certs/qwert.org.key -x509 -days 365 -out
/usr/local/nginx/certs/qwert.org.crt
[root@Nginx01 nginx]# vim /usr/local/nginx/conf.d/vhost.conf
server {
listen 80;
listen 443 ssl;
server_name www.qwert.org;
root /data/web/html;
index index.html;
ssl_certificate /usr/local/nginx/certs/qwert.org.crt;
ssl_certificate_key /usr/local/nginx/certs/qwert.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;
}
}
}
[root@Nginx01 nginx]# nginx -s reload
PHP部署
#停止nginx进程,删除/usr/local/nginx下的所有内容
[root@Nginx01 ~]# systemctl stop nginx
[root@Nginx01 ~]# rm -rf /usr/local/nginx/*
#将压缩包放在要解压的目录下并解压
[root@Nginx01 nginx]# tar zxf memc-nginx-module-0.20.tar.gz
[root@Nginx01 nginx]# tar zxf srcache-nginx-module-0.33.tar.gz
[root@Nginx01 nginx]# tar zxf php-8.3.9.tar.gz
#检测编译环境并添加模块
[root@Nginx01 nginx-1.26.1]# ./configure --prefix=/usr/local/nginx \
--add-module=/nginx/echo-nginx-module-0.63/ \
--add-module=/nginx/memc-nginx-module-0.20/ \
--add-module=/nginx//srcache-nginx-module-0.33/ \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module
#编译模块
make && make install
#启动nginx
[root@Nginx01 nginx-1.26.1]# nginx
#安装软件包
[root@Nginx01 nginx-1.26.1]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel oniguruma-devel
#进入php解压后的目录,检测模块环境
[root@Nginx01 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@Nginx01 php-8.3.9]# make && make install
#编辑管理器文件,将配置文件的模版复制出来
[root@Nginx01 php-8.3.9]# cd /usr/local/php/etc/
[root@Nginx01 etc]# ls
php-fpm.conf.default php-fpm.d
[root@Nginx01 etc]# cp -p php-fpm.conf.default php-fpm.conf
[root@Nginx01 etc]# ls
php-fpm.conf php-fpm.conf.default php-fpm.d
[root@Nginx01 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
#生成子配置文件
[root@Nginx01 etc]# cd php-fpm.d/
[root@Nginx01 php-fpm.d]# ls
www.conf.default
[root@Nginx01 php-fpm.d]# cp www.conf.default www.conf -p
[root@Nginx01 php-fpm.d]# ls
www.conf www.conf.default
#
[root@Nginx01 php-8.3.9]# cp php.ini-production /usr/local/php/etc/php.ini
[root@Nginx01 php-8.3.9]# vim /usr/local/php/etc/php
php-fpm.conf php-fpm.conf.default php-fpm.d/ php.ini
[root@Nginx01 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@Nginx01 php-8.3.9]# cd sapi/fpm/
[root@Nginx01 php-8.3.9]# cp php-fpm.service /lib/systemd/system
[root@Nginx01 php-8.3.9]# vim /lib/systemd/system/php-fpm.service
[root@Nginx01 /]# systemctl daemon-reload
[root@Nginx01 /]# systemctl start php-fpm.service
重启成功说明php部署成功
测试页面
#将PHP配置到环境变量中
[root@Nginx01 /]# 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@Nginx01 /]# source ~/.bash_profile
#编写php页面
[root@Nginx01 ~]# mkdir -p /data/web/php/
[root@Nginx01 ~]# vim /data/web/php/index.php
<?php
phpinfo();
?>
#为php配置文件创建目录,编写nginx的配置文件,引入php
[root@Nginx01 ~]# mkdir /usr/local/nginx/conf.d
[root@Nginx01 nginx]# vim conf/nginx.conf
#### 添加在第一个server的 " } " 后
include "/usr/local/nginx/conf.d/*.conf";
#在刚创建的目录中添加php页面相关配置
[root@Nginx01 nginx]# vim conf.d/vhosts.conf
server {
listen 80;
server_name www.hahaha01.com;
root /data/web/html;
index index.html;
location ~ \.php$ {
root /data/web/php/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}
#修改访问端口,修改如下
[root@Nginx01 nginx]# vim /usr/local/php/etc/php-fpm.d/www.conf
; Note: This value is mandatory.
listen = 0.0.0.0:9000
#重启nginx,php
[root@Nginx01 ~]# nginx -s reload
[root@Nginx01 ~]# systemctl daemon-reload
[root@Nginx01 ~]# systemctl restart php-fpm.service
在本机电脑的hosts文件中加入本地解析