Web 服务是在网络环境中运行的应用程序,负责处理客户端的请求并提供相应的响应。在众多 Web 服务中,Apache 和 Nginx 是两款备受关注和广泛使用的服务器软件。
Apache 是历史悠久且非常流行的开源 Web 服务器。它具有以下特点:
例如,许多大型企业网站和政府机构网站都选择 Apache 作为其 Web 服务,因为其稳定可靠的性能能够满足高流量和复杂业务需求。
在 Prefork 模型中,服务器会预先启动多个子进程。每个子进程在等待连接请求时处于空闲状态。当有新的连接请求到达时,一个空闲的子进程会被激活来处理该请求。
这种模型的优点包括:
稳定性较高:由于每个请求都由独立的子进程处理,一个进程的故障不会影响到其他进程,从而保证了服务的稳定性。
兼容性好:对于一些旧的、不支持多线程的模块能够很好地兼容。
然而,Prefork 模型也存在一些缺点:
资源消耗较大:因为预先启动了多个子进程,会消耗较多的系统资源,如内存等。
扩展性有限:在处理大量并发连接时,创建过多的进程可能会导致系统性能下降。
例如,在一个小型的企业内部网站,如果并发访问量不是特别大,且使用了一些旧的不支持多线程的模块,Prefork 模型可能是一个合适的选择。但对于像大型电商网站那样的高并发场景,可能就需要考虑其他更高效的模型或服务器软件。
在 Worker 模型中,服务器会启动多个进程,每个进程又会生成多个线程。这些线程共同处理客户端的请求。
Worker 模型具有以下特点和优势:
优点:
资源利用率高:相比 Prefork 模型,Worker 模型在处理并发请求时能够更有效地利用系统资源,因为线程比进程更轻量级,创建和切换的开销较小。
并发处理能力强:多个线程可以同时处理多个请求,提高了服务器的并发处理能力,能够更好地应对高并发的场景。
内存使用更优化:由于线程共享进程的资源,相较于 Prefork 模型,内存的使用更加节省。
缺点:
稳定性稍逊:由于线程共享进程资源,如果一个线程出现问题,可能会影响到同一进程中的其他线程。
部分模块不兼容:某些不支持线程安全的模块可能无法在 Worker 模式下正常工作。
举例来说,对于一个流量适中、需要较好地节省资源并且对并发处理有一定要求的网站,Worker 模型可能是一个比较合适的选择。但如果网站使用了一些特定的不兼容模块,就需要谨慎考虑是否采用此模型。
在 Event 模型中,它采用了异步非阻塞的方式来处理连接。这意味着服务器能够在一个线程中同时处理多个连接,而无需为每个连接创建新的进程或线程。
Event 模型的主要特点和优势包括:
优点:
极高的并发处理能力:能够处理大量的并发连接,尤其适合高并发的场景,如大型社交网站或热门的在线服务。
资源消耗低:由于采用异步方式,减少了进程和线程的创建,从而降低了系统资源的消耗。
响应迅速:能够更快地响应请求,减少了请求的等待时间,提供更流畅的用户体验。
缺点:
配置复杂:相比其他模型,Event 模型的配置可能更为复杂,需要对服务器的参数有更深入的理解和调整。
模块兼容性问题:某些模块可能不兼容 Event 模型,需要进行仔细的筛选和测试。
例如,对于像双十一期间的电商平台这种瞬间流量巨大的情况,Apache 的 Event 模型能够更好地应对,确保网站的稳定运行和快速响应,避免出现服务器崩溃或响应迟缓的问题。但在使用之前,需要对网站所依赖的模块进行充分的测试,以确保其在 Event 模型下正常工作。
Nginx 是一款高性能的 Web 服务器和反向代理服务器。
比如,一些高流量的互联网公司,如淘宝、腾讯等,会使用 Nginx 来处理海量的用户请求,确保网站的快速响应和稳定运行。
服务端的 I/O(输入 / 输出)流程是指服务器处理来自客户端的数据输入以及向客户端发送数据输出的过程。
一般来说,服务端的 I/O 流程可以分为以下几个主要步骤:
建立连接:客户端向服务器发起连接请求,服务器接受连接并建立通信通道。这通常基于网络协议,如 TCP 协议。
接收请求:服务器等待并接收客户端发送的数据请求。
解析请求:服务器对收到的请求数据进行解析,理解客户端的需求。
处理请求:根据解析出的请求内容,服务器执行相应的处理逻辑。这可能包括从数据库读取数据、进行计算、调用其他服务等。
准备响应:服务器根据处理结果准备要发送回客户端的数据。
发送响应:将准备好的响应数据通过网络发送回客户端。
关闭连接:在完成数据交互后,根据协议和配置,关闭连接或保持连接以处理后续请求。
在整个 I/O 流程中,可能会涉及到不同的 I/O 模式,如阻塞 I/O、非阻塞 I/O、异步 I/O 等,以适应不同的性能和场景需求。
例如,在一个在线游戏服务器中,当玩家进行操作时,服务器按照上述流程接收、处理请求,并及时发送响应,以实现游戏的实时交互。又比如,在文件下载服务器中,服务器接收客户端的下载请求,读取文件数据并发送给客户端,完成文件传输的 I/O 过程。
服务器的I/O 磁盘I/O 网络I/O : 一切皆文件,本质为对socket文件的读写磁盘 I/O(输入 / 输出)是指计算机系统与磁盘设备之间的数据交换过程。
磁盘 I/O 主要包括读操作和写操作:
读操作:
当系统需要从磁盘获取数据时,会发出读请求。操作系统会将请求发送到磁盘控制器,磁盘控制器控制磁盘的机械部件定位到存储所需数据的磁道和扇区,然后将数据读取到磁盘缓冲区,并最终传输到系统内存供应用程序使用。
写操作:
当系统要将数据保存到磁盘时,会发起写请求。数据首先从内存传输到磁盘缓冲区,然后磁盘控制器将缓冲区中的数据写入到磁盘的指定位置。
磁盘 I/O 性能对计算机系统的整体性能有重要影响。一些影响磁盘 I/O 性能的因素包括:
例如,在数据库服务器中,如果频繁进行大量数据的读写操作,磁盘 I/O 性能不足可能导致数据库响应迟缓,影响整个系统的运行效率。又比如,在视频编辑软件中,处理大型视频文件时,如果磁盘 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.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(输入 / 输出)是指计算机系统通过网络进行数据的接收和发送过程。
在网络 I/O 中,主要包括以下几种常见的操作模式:
阻塞式 I/O:在进行数据读取或发送时,程序会一直等待,直到操作完成。如果数据尚未准备好,程序会被阻塞,无法进行其他操作。
socket
编程,在调用 recv
函数接收数据时,如果没有数据到达,程序会一直阻塞在那里。非阻塞式 I/O:程序不会被阻塞,而是立即返回一个状态,表示操作是否完成。如果操作未完成,需要通过轮询不断检查状态,直到数据准备好。
I/O 多路复用:通过一个线程或进程同时监控多个网络连接,当有数据可读写时,通知相应的程序进行处理。常见的实现方式有 select
、poll
和 epoll
等。
epoll
可以高效地管理这些连接,而无需为每个连接创建单独的线程。异步 I/O:程序发起一个 I/O 操作后,无需等待操作完成,操作完成后会通过回调函数或其他方式通知程序。
网络 I/O 性能受到多种因素的影响,如网络带宽、延迟、数据包丢失率等。
例如,在一个高并发的 Web 服务器中,如果采用不合适的网络 I/O 模式,可能会导致大量连接请求被阻塞,服务器响应变慢。而使用高效的 I/O 多路复用或异步 I/O 模式,可以显著提高服务器的并发处理能力和性能。又如,在实时在线游戏中,低延迟的网络 I/O 对于保证游戏的流畅性和玩家体验至关重要,如果网络 I/O 出现延迟或卡顿,可能会导致游戏中的操作不及时响应
网络 I/O 的处理过程通常包括以下几个主要阶段:
创建套接字(Socket):应用程序创建一个套接字来与网络进行通信。套接字是网络通信的端点,它定义了通信的协议(如 TCP 或 UDP)、本地地址和端口以及远程地址和端口等信息。
绑定(Binding):如果需要指定本地的地址和端口,应用程序将套接字与这些信息进行绑定。
连接(Connecting)(对于 TCP):在使用 TCP 协议时,如果是客户端,需要向服务器发起连接请求。服务器端则会监听并接受连接请求。
监听(Listening)(对于服务器):服务器端通过监听套接字等待客户端的连接请求。
数据发送(Sending Data):应用程序将要发送的数据写入到套接字的发送缓冲区。
数据传输:
数据接收(Receiving Data):
错误处理:在整个网络 I/O 过程中,可能会出现各种错误,如连接失败、数据包丢失、超时等,应用程序需要进行相应的错误处理。
例如,在一个文件下载的场景中:
在一个在线聊天应用中:
这些阶段共同构成了网络 I/O 的处理过程,不同的应用和网络环境可能会对这些阶段进行优化和调整,以实现更高效和可靠的网络通信。
recv
函数的线程会被阻塞,直到有数据到达。recv
函数而没有数据时,函数会立即返回 -1
和错误码 EWOULDBLOCK
,表示当前没有数据可接收。select
函数可以同时监听多个套接字,当其中某个套接字有数据可读或可写时,select
函数返回,并告知哪些套接字处于就绪状态。select
和 poll
在处理大量文件描述符时效率较低,epoll
在大规模并发场景下表现更好。aio_read
,发起读操作后进程继续执行其他任务,当读操作完成时,通过回调函数或其他方式通知进程。select
:poll
:select
,但没有文件描述符数量的限制。select
一样,每次调用都需要重新设置描述符集合,并且返回时需要遍历。epoll
:零拷贝(Zero-Copy)是一种在计算机系统中优化数据传输操作的技术,旨在减少数据在内存之间的不必要复制,从而提高数据传输的性能和效率。
在传统的数据传输过程中,通常需要多次的数据拷贝操作。例如,从磁盘读取文件并通过网络发送时,数据可能要从磁盘拷贝到内核缓冲区,然后再从内核缓冲区拷贝到用户空间缓冲区,最后从用户空间缓冲区拷贝到网络缓冲区进行发送。
而零拷贝技术通过避免或减少这些不必要的拷贝,直接将数据从源(如磁盘)传输到目标(如网络),或者在某些情况下,只进行一次必要的拷贝。
零拷贝技术的优点包括:
常见的实现零拷贝的方式有:
mmap
(内存映射):将文件映射到进程的地址空间,减少了一次数据拷贝。sendfile
系统调用:在支持的操作系统中,可以直接将数据从文件描述符传输到网络套接字,避免了用户空间和内核空间之间的数据拷贝。例如,在一个高性能的文件服务器中,如果需要频繁地将大文件发送给客户端,使用零拷贝技术可以极大地提高文件传输的速度,提升服务器的整体性能和响应能力。
Nginx 是一款轻量级、高性能的 Web 服务器和反向代理服务器,具有以下显著特点和优势:
特点:
优势:
应用场景:
例如,许多大型网站如淘宝、腾讯等都使用 Nginx 来处理高并发的用户请求,保证网站的快速稳定运行。对于中小企业的网站,Nginx 也能以其高效的性能和简单的配置,满足业务需求,降低服务器成本。
Web 服务器功能:
反向代理功能:
负载均衡功能:
缓存功能:
SSL/TLS 加密支持:
访问控制和权限管理:
Gzip 压缩:
Rewrite 重写规则:
监控和日志记录:
上传安装包
解压缩
[root@nginx ~]# tar zxf nginx-1.24.0.tar.gz
下载存在的依赖关系
[root@nginx nginx-1.24.0]# yum install gcc pcre-devel zlib-devel openssl-devel -y
环境检测
注意不能有报错
开始编译
创建用户
启动
关闭
测试
关闭nginx的debug功能
编写环境变量(把nginx软件的命令执行路径添加到环境变量中)
[root@nginx ~]# vim ~/.bash_profile
[root@nginx ~]# source ~/.bash_profile
下载安装包
nginx: 下载
上传需要加载的模块
解压缩
[root@nginx ~]# tar zxf echo-nginx-module-0.63.tar.gz
[root@nginx ~]# tar zxf nginx-1.26.2.tar.gz
开始编译新版本
需要加入echo-nginx-module-0.63这个模块
编译完成make一下,注意不能make install
可以选择隐藏nginx的版本
需要编辑/root/nginx-1.24.0/src/core下的nginx.h这个文件
修个这块即可
主进程(Master Process):
SIGHUP
信号(通常用于重新加载配置)时,主进程会重新读取配置文件,并向工作进程发送指令以重新加载配置。工作进程(Worker Process):
缓存加载进程(Cache Loader Process):
缓存管理器进程(Cache Manager Process):
例如,假设一个网站在高峰期每秒收到 1000 个请求,Nginx 的多个工作进程可以同时处理这些请求,快速地将响应返回给客户端。而主进程则在后台监控整个系统的运行状态,确保一切正常。如果需要修改配置,比如增加新的虚拟主机配置,主进程会重新读取配置并指示工作进程应用新的配置,而整个过程中服务不会中断。
信号(Signals):
SIGHUP
用于重新加载配置,SIGTERM
用于优雅地关闭进程等。SIGHUP
信号,主进程接收到信号后会重新读取配置并通知工作进程重新加载配置。共享内存(Shared Memory):
套接字(Sockets):
文件锁(File Locks):
核心模块(Core Modules):
http_module
:处理 HTTP 相关的基本功能,如请求解析、响应生成等。event_module
:提供了对不同事件模型的支持,如 epoll
、kqueue
等,以提高网络性能。HTTP 模块(HTTP Modules):
http_gzip_module
:对响应数据进行 Gzip 压缩,减少数据传输量,提高传输效率。http_rewrite_module
:用于重写 URL,实现 URL 跳转和规则匹配。http_proxy_module
:支持反向代理功能,将请求转发到后端服务器。http_ssl_module
:处理 HTTPS 协议相关的配置和加密解密操作。负载均衡模块(Load Balancing Modules):
upstream_module
:定义上游服务器组,并实现负载均衡策略,如轮询、加权轮询、IP 哈希等。访问控制模块(Access Control Modules):
http_access_module
:基于 IP 地址或网络段来控制对服务器的访问权限。http_auth_basic_module
:实现基本的 HTTP 认证功能。缓存模块(Caching Modules):
proxy_cache_module
:为反向代理提供缓存功能,提高响应速度。[root@nginx ~]# nginx -v nginx version: nginx/1.18.0 Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives] Options: -?,-h : this help -v : show version and exit -V : show version and configure options then exit #显示版本和编译参数 -t : test configuration and exit #测试配置文件是否异 -T : test configuration, dump it and exit #测试并打印 -q : suppress non-error messages during configuration testing #静默 模式 -s signal : send signal to a master process: stop, quit, reopen, reload # 发送信号,reload信号 会生成新的worker,但master不会重新生成 -p prefix : set prefix path (default: /etc/nginx/) #指定Nginx 目录 -c filename : set configuration file (default: /etc/nginx/nginx.conf) # 配置文件路径 -g directives : set global directives out of configuration file #设置全局指令,注意和 配置文件不要同时配置,否则冲突
[root@nginx ~]# vim /lib/systemd/system/nginx.service
Description 描述
After 启动nginx服务时,这些服务会被自动激活
wants 依赖性
Type 类型
PIDFile pid的路径
ExecStartPre 启动nginx服务时,检查配置文件是否有错误
ExecStart 真实启动的命令
nginx 官方帮助文档:http://nginx.org/en/docs/ Nginx的配置文件的组成部分: 主配置文件:nginx.conf 子配置文件: include conf.d/*.conf fastcgi, uwsgi,scgi 等协议相关的配置文件 mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮 件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某 种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动 使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
配置文件由指令与指令块构成 每条指令以;分号结尾,指令与值之间以空格符号分隔 可以将多条指令放在同一行,用分号分隔即可,但可读性差,不推荐 指令块以{ }大括号将多条指令组织在一起,且可以嵌套指令块 include语句允许组合多个配置文件以提升可维护性 使用#符号添加注释,提高可读性 使用$符号使用变量 部分指令的参数支持正则表达式
main block:主配置段,即全局配置段,对http,mail都有效 #事件驱动相关的配置 event { ... } #http/https 协议相关配置段 http {... } #默认配置文件不包括下面两个块 #mail 协议相关配置段 mail { ... } #stream 服务器相关配置段 stream { ... }
#全局配置端,对全局生效,主要设置nginx的启动用户/组,启动的工作进程数量,工作模式,Nginx的PID路 径,日志路径等。 user nginx nginx; worker_processes 1; #启动工作进程数数量 events { #events #设置快,主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多 个网络连接,使用哪种事件驱动模型 #处理请求,每个工作进程可以同时支持的 最大连接数,是否开启对多工作进程下的网络连接进行序列化等。 worker_connections 1024; #设置单个nginx工作进程可以接受的最大并发,作为web服务器 的时候最大并发数为 #worker_connections * worker_processes,作为反向代理的时候为 #(worker_connections * worker_processes)/2 } http { #http块是Nginx服务器配置中的重要部分,缓存、代理和日志格 式定义等绝大多数功能和第三方模块都 #可以在这设置,http块可 以包含多个server块,而一个server块中又可以包含多个location块, #server块可以配置文件引入、MIME-Type定义、日志自定义、是 否启用sendfile、连接超时时间和 #单个链接的请求上限等。 include mime.types; default_type application/octet-stream; sendfile on; #作为web服务器的时候打开sendfile加快静态文件传输,指定是 否使用 #sendfile系统调用来传输文件 #sendfile系统调用在两个文件描述符之间直接传递数据(完全在 内核中操作) #从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率 很高,被称之为零拷贝, #硬盘 >> kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈。 keepalive_timeout 65; #长连接超时时间,单位是秒 server { #设置一个虚拟机主机,可以包含自己的全局快,同时也可以包含多 个location模块 #比如本虚拟机监听的端口、本虚拟机的名称和IP配置,多个 server 可以使用一个端口比如都使用 #80端口提供web服务 listen 80; #配置server监听的端口server_name localhost; #本server的名称,当访问此名称的时候nginx会调用当前serevr 内部的配置进程匹配。 location / { #location其实是server的一个指令,为nginx服务器提供比较 多而且灵活的指令 #都是在location中体现的,主要是基于nginx接受到的请求字符 串 #对用户请求的UIL进行匹配,并对特定的指令进行处理 #包括地址重定向、数据缓存和应答控制等功能都是在这部分实现 #另外很多第三方模块的配置也是在location模块中配置。 root html; #相当于默认页面的目录名称,默认是安装目录的相对路径,可以使 用绝对路径配置。 index index.html index.htm; #默认的页面文件名称 } error_page 500 502 503 504 /50x.html; #错误页面的文件名称 location = /50x.html { #location处理对应的不同错误码的页面定 义到/50x.html #这个跟对应其server中定义的目录下。 root html; #定义默认页面所在的目录 } } #和邮件相关的配置 #mail { # ... # } mail 协议相关配置段 #tcp代理配置,1.9版本以上支持 #stream { # ... # } stream 服务器相关配置段 #导入其他路径的配置文件 #include /apps/nginx/conf.d/*.conf }
[root@nginx ~]# vim /etc/security/limits.conf
root #给定的路径对应于location中的/uri左侧的/ alias #给定的路径对应于location中的/uri的完整路径
我们新建一个子配置文件(注意要写在前面,写到后面不生效)
写解析
root
alias
在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射; ngnix会根据用户请求的URI来检查定义的所有location,按一定的优先级找出一个最佳匹配, 而后应用其配置在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最 高的一个uri uri是用户请求的字符串,即域名后面的web文件路径 然后使用该location模块中的正则url和字符串,如果匹配成功就结束搜索,并使用此location处理 此请求。
#语法规则: location [ = | ~ | ~* | ^~ ] uri { ... } = #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立 即处理请求 ^~ #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头 #对uri的最左边部分做匹配检查,不区分字符大小写 ~ #用于标准uri前,表示包含正则表达式,并且区分大小写 ~* #用于标准uri前,表示包含正则表达式,并且不区分大写 不带符号 #匹配起始于此uri的所有的uri \ #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号优先级
(~* = ~)> 不带符号 > ^~ > =
= #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立
两个比较一下(无符号的优先级大于 “=” 的优先级)
~ #用于标准uri前,表示包含正则表达式,并且区分大小写
由 ngx_http_auth_basic_module 模块提供此功能
Syntax: try_files file ... uri; try_files file ... =code; Default: — Context: server, location
keepalive_timeout timeout [header_timeout]; #设定保持连接超时时长,0表示禁止长连接, 默认为75s #通常配置在http字段作为站点全局配置 keepalive_requests 数字; #在一次长连接上所允许请求的资源的最大数量 #默认为100次,建议适当调大,比如:500 keepalive_requests 3; keepalive_timeout 65 60; #开启长连接后,返回客户端的会话保持时间为60s,单次长连接累计请求达到指定次数请求或65秒就会被断 开,第二个数字60为发送给客户端应答报文头部中显示的超时时间设置为60s:如不设置客户端将不显示超时时 间。 Keep-Alive:timeout=60 #浏览器收到的服务器返回的报文 #如果设置为0表示关闭会话保持功能,将如下显示: #Connection:close 浏览器收到的服务器返回的报文
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
这里是主配置文件不是子配置文件
下载测试工具
相关指令:
autoindex on | off; #自动文件索引功能,默为off autoindex_exact_size on | off; #计算文件确切大小(单位bytes),off 显示大概大小(单位K、 M),默认on autoindex_localtime on | off ; #显示本机时间而非GMT(格林威治)时间,默认off autoindex_format html | xml | json | jsonp; #显示索引的页面文件风格,默认html limit_rate rate; #限制响应客户端传输速率(除GET和HEAD以外的所有方法),单位 B/s,bytes/second, #默认值0,表示无限制,此指令由 ngx_http_core_module提供 set $limit_rate 4k; #也可以通变量限速,单位B/s,同时设置,此项优级高.
点击可直接下载
这里的时间不是本地的时间,是格林尼治时间
文件粗略大小
限速(默认不限速)
#配置示例: location /nginx_status { stub_status; auth_basic "auth login"; auth_basic_user_file /apps/nginx/conf/.htpasswd; allow 192.168.0.0/16; allow 127.0.0.1; deny all; } #状态页用于输出nginx的基本状态信息: #输出信息示例: Active connections: 291 server accepts handled requests 16630948 16630948 31070465 上面三个数字分别对应accepts,handled,requests三个值 Reading: 6 Writing: 179 Waiting: 106 Active connections: #当前处于活动状态的客户端连接数 #包括连接等待空闲连接数=reading+writing+waiting accepts: #统计总值,Nginx自启动后已经接受的客户端请求连接的总数。 handled: #统计总值,Nginx自启动后已经处理完成的客户端请求连接总数 #通常等于accepts,除非有因worker_connections限制等被拒绝的 连接 requests: #统计总值,Nginx自启动后客户端发来的总的请求数Reading: #当前状态,正在读取客户端请求报文首部的连接的连接数 #数值越大,说明排队现象严重,性能不足 Writing: #当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明 访问量很大 Waiting: #当前状态,正在等待客户端发出请求的空闲连接数 开启 keep-alive的情况下,这个值等于active – (reading+writing)
但是状态也不能随便让人去看,需要指定
#启用或禁用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;
在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为任意请求报文首部字部cookie的key名 $http_ #name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有横线需要替换为下划线
假如需要自定义变量名称和值,使用指令set $variable value;
Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求 此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库 rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能 比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的 链接,就可以设置为访问 另外还可以在一定程度上提高网站的安全性。
if (条件匹配) { action }使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接:
= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false != #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false ~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假 !~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假 ~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假 !~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真 -f 和 !-f #判断请求的文件是否存在和是否不存在 -d 和 !-d #判断请求的目录是否存在和是否不存在 -x 和 !-x #判断文件是否可执行和是否不可执行 -e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接) #注意: #如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。 #nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false
rewrite regex replacement [flag];rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI 注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制 如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向301 正则表达式格式
. #匹配除换行符以外的任意字符 \w #匹配字母或数字或下划线或汉字 \s #匹配任意的空白符 \d #匹配数字 \b #匹配单词的开始或结束 ^ #匹配字付串的开始 $ #匹配字符串的结束 * #匹配重复零次或更多次 + #匹配重复一次或更多次 ? #匹配重复零次或一次 (n) #匹配重复n次 {n,} #匹配重复n次或更多次 {n,m} #匹配重复n到m次 *? #匹配重复任意次,但尽可能少重复 +? #匹配重复1次或更多次,但尽可能少重复?? #匹配重复0次或1次,但尽可能少重复 {n,m}? #匹配重复n到m次,但尽可能少重复 {n,}? #匹配重复n次以上,但尽可能少重复 \W #匹配任意不是字母,数字,下划线,汉字的字符 \S #匹配任意不是空白符的字符 \D #匹配任意非数字的字符 \B #匹配不是单词开头或结束的位置 [^x] #匹配除了x以外的任意字符 [^lee] #匹配除了magedu 这几个字母以外的任意字符
Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据包。 Default: — Context: server, location, if
flag 说明
redirect; #临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端 #由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302 permanent; #重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端 #由客户端重新发起请求,状态码:301 break; #重写完成后,停止对当前URL在当前location中后续的其它重写操作 #而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在location中使用 #适用于一个URL一次重写 last; #重写完成后,停止对当前URI在当前location中后续的其它重写操作, #而后对新的URL启动新一轮重写检查,不建议在location中使用 #适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户
创建目录
制作认证文件
编写配置文件
测试访问
不用输https直接跳转
判断文件是否存在
none: #请求报文首部没有referer首部, #比如用户直接在浏览器输入域名访问web网站,就没有referer信息。 blocked: #请求报文有referer首部,但无有效值,比如为空。 server_names: #referer首部中包含本主机名及即nginx 监听的server_name。 arbitrary_string: #自定义指定字符串,但可使用*作通配符。示例: *.timinglee.org www.timinglee.* regular expression: #被指定的正则表达式模式匹配到的字符串,要使用~开头,例如: ~.*\.timinglee\.com
反向代理是位于客户端和后端服务器之间的服务器。与正向代理(代表客户端向服务器发起请求)不同,反向代理接收来自客户端的请求,并将这些请求转发给后端的一个或多个服务器。然后,它将后端服务器的响应返回给客户端,就好像这个响应是直接来自反向代理服务器本身一样。
负载均衡
安全防护
缓存加速
动静分离
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协议转发至指定服务器处理
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_connect_timeout 6s; #60s为自定义nginx与后端服务器建立连接的超时时间,超时会返回客户端504响应码 proxy_read_timeout time; #配置nginx服务器向后端服务器或服务器组发起read请求后,等待的超时时间,默认60s proxy_send_timeout time; #配置nginx项后端服务器或服务器组发起write请求后,等待的超时 时间,默认60s proxy_http_version 1.0; #用于设置nginx提供代理服务的HTTP协议的版本,默认http 1.0 proxy_ignore_client_abort off; #当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求。即如果此项设置为on开启,则服务器会忽略客户端中断并一直等着代理服务执行返回,如果设置为off,则客户端中断后Nginx也会中断客户端请求并立即记录499日志,默认为off。
提高响应速度
减轻后端服务器压力
缓存存储
缓存命中与未命中
缓存过期策略
proxy_cache zone_name | off; 默认off #指明调用的缓存,或关闭缓存机制;Context:http, server, location #zone_name 表示缓存的名称.需要由proxy_cache_path事先定义 proxy_cache_key string; #缓存中用于“键”的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;proxy_cache_valid [code ...] time; #定义对特定响应码的响应内容的缓存时长,定义在http{...}中 在http配置定义缓存信息 proxy_cache_path /var/cache/nginx/proxy_cache #定义缓存保存路径,proxy_cache会自动创建levels=1:2:2 #定义缓存目录结构层次 #1:2:2可以生成 2^4x2^8x2^8=2^20=1048576个目录 keys_zone=proxycache:20m #指内存中缓存的大小,主要用于存放key和metadata (如:使用次数) #一般1M可存放8000个左右的key inactive=120s #缓存有效时间 max_size=10g; #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值 #调用缓存功能,需要定义在相应的配置段,如server{...};或者location等 proxy_cache proxycache; proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间 proxy_cache_valid any 1m; #除指定的状态码返回的数据以外的缓存多长时间,必须设置, 否则不会缓存 proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off #在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端 #示例 proxy_cache_use_stale error http_502 http_503; proxy_cache_methods GET | HEAD | POST ...; #对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
非缓存场景压测
[root@web1 ~]# ab -n1000 -c100 http://www.timingtc.org/static/index.html
主配置文件
测试
[root@web1 ~]# ab -n1000 -c100 http://www.timingtc.org/static/index.html
提高系统可用性
提升系统性能
客户端请求
Nginx 分配请求
后端服务器处理请求
Nginx 返回响应
#自定义一组服务器,配置在http块内 upstream name { server ..... ...... } #示例 upstream backend { server backend1.example.com weight=5; server 127.0.0.1:8080 max_fails=3 fail_timeout=30s; server unix:/tmp/backend3; server backup1.example.com backup; } server address [parameters]; #配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。 #server支持的parameters如下: weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等 max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制 max_fails=number #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检 测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性 检查,而非周期性的探测 fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再 次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒 backup #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器 down #标记为down状态,可以平滑下线后端服务器resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启 Nginxhash KEY [consistent]; #基于指定请求报文中首部字段或者URI等key做hash计算,使用consistent参数,将使用ketama一致性 hash算法,适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一致 性hash基于取模运算 hash $request_uri consistent; #基于用户请求的uri做hash hash $cookie_sessionid #基于cookie中的sessionid这个key进行hash调度,实现会话绑 定 ip_hash; #源地址hash调度方法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计算,以实现会话保持 least_conn; #最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC
172.25.254.129 #Nginx 代理服务器 172.25.254.128 #后端web A,Apache部署 172.25.254.10 #后端web B,Apache部署
加入算法
tcp负载均衡配置参数
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; } }
[root@web1 ~]# mysql -utc -ptc -h172.25.254.129 -e "select @@server_id"
[root@web2 ~]# mysql -utc -ptc -h172.25.254.129 -e "select @@server_id"
CGI的由来: 最早的Web服务器只能简单地响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏 览器,也就是静态html文件,但是后期随着网站功能增多网站开发也越来越复杂,以至于出现动态技术,比如像php(1995年)、java(1995)、python(1991)语言开发的网站,但是nginx/apache服务器并不能直接运行 php、java这样的文件,apache实现的方式是打补丁,但是nginx缺通过与第三方基于协议实现,即通过某种特定协议将客户端请求转发给第三方服务处理,第三方服务器会新建新的进程处理用户 的请求,处理完成后返回数据给Nginx并回收进程,最后nginx在返回给客户端,那这个约定就是通用网关接口(common gateway interface,简称CGI),CGI(协议) 是web服务器和外部应用程序之间的接口标准,是cgi程序和web服务器之间传递信息的标准化接口。
为什么会有FastCGI? CGI协议虽然解决了语言解析器和 Web Server 之间通讯的问题,但是它的效率很低,因为 Web Server每收到一个请求都会创建一个CGI进程,PHP解析器都会解析php.ini文件,初始化环境,请求结束的时候再关闭进程,对于每一个创建的CGI进程都会执行这些操作,所以效率很低,而FastCGI是用来提高CGI性 能的,FastCGI每次处理完请求之后不会关闭掉进程,而是保留这个进程,使这个进程可以处理多个请求。这样的话每个请求都不用再重新创建一个进程了,大大提升了处理效率。 什么是PHP-FPM? PHP-FPM(FastCGI Process Manager: FastCGI进程管理器)是一个实现了Fastcgi的程序,并且提供进程管理的功能。 进程包括master进程和worker进程。master进程只有一个,负责监听端口,接受来自web server的请求 worker进程一般会有多个,每个进程中会嵌入一个PHP解析器,进行PHP代码的处理。
#转发请求到后端服务器,address为后端的fastcgi server的地址,可用位置:location, if in location fastcgi_index name; #fastcgi默认的主页资源,示例:fastcgi_index index.php; fastcgi_param parameter value [if_not_empty]; #设置传递给FastCGI服务器的参数值,可以是文本,变量或组合,可用于将Nginx的内置变量赋值给自定义 key fastcgi_param REMOTE_ADDR $remote_addr; #客户端源IP fastcgi_param REMOTE_PORT $remote_port; #客户端源端口 fastcgi_param SERVER_ADDR $server_addr; #请求的服务器IP地址 fastcgi_param SERVER_PORT $server_port; #请求的服务器端口 fastcgi_param SERVER_NAME $server_name; #请求的server name Nginx默认配置示例: location ~ \.php$ { root /scripts; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #默认脚本路径 #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; #此文件默认系统已提供,存放的相对路径为 prefix/conf }
上传需要的安装包
解压缩
编译nginx
下载可能需要的依赖
开始编译php
注意编译过程中的报错
出现下面的界面表示成功
生成php主配置文件
修改时区
生成启动脚本
写入环境变量
测试一下
测试一下
[root@nginx ~]# ab -n1000 -c10 http://www.timingtc.org/index.php
上传相关的压缩包
解压缩
测试
上传需要的压缩包并解压缩
编写配置文件
[root@nginx conf.d]# vim php.conf
测试
[root@nginx conf.d]# ab -n1000 -c10 http://www.timingtc.org/index.php