关于 httpd

1.http请求过程

建立连接 ,接收请求 ,处理请求 ,访问资源 ,构建响应报文 ,发送响应报文 ,记录日志

2. http 0.9  1.0  1.1 版本区别

0.9   只有(get)下载,没有上传  (put)

1.0  没有长连接可以下载和上传  (put)

1.1  支持长连接 可以下载和上传 (put)

3.httpd三种工作模式

Prefork:开子进程 ,每个进程响应一个请求

Work:一个主进程:生成m个子进程,每个子进程负责生个n个线程,每个线程响应一个请求

event:子进程中开线程

一个主进程生成m个子进程,每个子进程负责生个n个线程,每个线程响应一个请求,并发响应请求:m*n,有专门的监控线程来管理这些keep-alive类型的线程

4.httpd(apache)的功能

提供http协议服务       web网页

多个虚拟主机:IP、Port、FQDN            用一台物理服务器搭建多个网站。

CGI:Common Gateway Interface, 通用网关接口,支持动态程序

反向代理

负载均衡

路径别名

丰富的用户认证机制:basic,digest

支持第三方模块

5. httpd(apache)的特性

高度模块化:core + modules

DSO:Dynamic Shared Object 动态加载/卸载

MPM:multi-processing module 多路处理模块(一种设计理念)

功能多且稳定,处理静态资源优秀。

6.对httpd进行调优

隐藏版本号

虚拟主机(基于ip,端口,域名在一台主机上访问不同的网页)

长连接   限制:时间限制 ,请求数量限制

alias别名

定义站点默认主页面文件

定义文档页面路径

修改工作模式

使用目录 :开放目录的权限

7 http 文件位置

/var/www/html/    主站点

/etc/httpd/        主目录

8.http资源类型

静态文件:无需服务端做出额外处理,服务器端和客户端的文件内容相同 常见文件后缀:.html, .txt, .jpg, .js, .css, .mp3, .avi

动态文件:服务端执行程序,返回执行的结果,服务器端和客户端的文件内容不相同 常见文件后缀:.php, .jsp ,.asp

9. URI 和 URL

URI: Uniform Resource Identifier 统一资源标识,分为URL 和 URN

uri是一个标识,用来区别于其他资源的标识

URN:Uniform Resource Naming,统一资源命名 示例: P2P下载使用的磁力链接是URN的一种实现

​             magnet:?xt=urn:btih:660557A6890EF888666(只是描述了资源的名字,并没有明确该资源在哪里)

URL:Uniform Resorce Locator,统一资源定位符,用于描述某服务器某特定资源位置 url就是每次我们输入网址访问某个网站时,浏览器上输入的那一行内容。比如:http://baidu.com这是一个url,每个链接地址是一个url。

两者区别:

URN如同一个人的名称,而URL代表一个人的住址。换言之,URN定义某事物的身份,而URL提供查找该事物的方法。URN仅用于命名,而不指定地URL组成

Nginx

Nginx-高性能的 Web服务端

        Nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学为俄罗斯rambler.ru公司开发的,开发工作最早从2002年开始,第一次公开发布时间是2004年10月4日,版本号是0.1.02019年3月11日F5 与 NGINX达成协议,F5 将收购 NGINX 的所有已发行股票,总价值约为 6.7 亿美元。6.7亿美金约合44.97亿人民币,nginx核心模块代码长度198430(包括空格、注释),所以一行代码约为2.6万人民币

        官网地址 www.nginx.org

        Nginx历经十几年的迭代更新(https://nginx.org/en/CHANGES), 目前功能已经非常完善且运行稳定,另外Nginx的版本分为开发版、稳定版和过期版,nginx以功能丰富著称,它即可以作为http服务器,也可以作为反向代理服务器或者邮件服务器,能够快速的响应静态网页的请求,支持FastCGI/SSL/Virtual Host/URL Rwrite/Gzip/HTTP Basic Auth/http或者TCP的负载均衡(1.9版本以上且开启stream模块)等功能,并且支持第三方的功能扩展。天猫 淘宝 京东 小米 163 新浪等一线互联网公司都在用Nginx或者进行二次开发

        基于Nginx的工作场景

        正向代理:  代理的客户端( 科学上网 )

        反向代理:  代理的服务端

影响用户体验的因素

#客户端 客户端硬件配置 客户端网络速率 客户端与服务端距离

#服务器 服务端网络速率 服务端硬件配置 服务端架构设计 服务端应用程序工作模式 服务端并发数量 服务端响应文件大小及数量 buffer cache 服务端I/O压力

I/O 模型

I/O在计算机中指Input/Output, IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一。IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处理的I/O请求数量为单位,I/O请求通常为读或写数据操作请求。一次完整的I/O是用户空间的进程数据与内核空间的内核数据的报文的完整交换,但是由于内核空间与用户空间是严格隔离的,所以其数据交换过程中不能由用户空间的进程直接调用内核空间的内存数据,而是需要经历一次从内核空间中的内存数据copy到用户空间的进程内存当中,所以简单说I/O就是把数据从内核空间中的内存数据复制到用户空间中进程的内存当中。

Linux 的 I/O 

磁盘I/O

        磁盘I/O是进程向内核发起系统调用,请求磁盘上的某个资源比如是html 文件或者图片,然后内核通过相应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存,如果是比较大的数据也需要等待时间

网络I/O : 一切皆文件,本质为对socket文件的读写网络通信就是网络协议栈到用户空间进程的IO就是网络IO

文字版请求过程:

1.当用户 发起 http 请求需要请求一个index.html 网页文件

2.客户端请求与服务器端 建立连接,建立连接后, 会发送请求报文

3.服务端的网卡收到请求报文,  会将该报文复制到  内核空间, 内核空间分析报文后交给对应的程序

4.nginx 分析该报文,  将报文和自己的配置文件,一一比对,按照配置文件完成请求,  分析后发现  客户需要 index.html

5.由于 nginx 程序的权限问题, 没有资格直接调用磁盘上的文件,程序会再将这个请求  再次转发给内核,内核得到后请求 去磁盘上找文件,找到文件后 复制给程序

6.程序会构建响应报文,构建好后在交给内核空间

7.内核空间  得到响应报文后,再 交给网卡 发给  客户

零拷贝技术

        传统的 Linux 系统的标准 I/O 接口(read、write)是基于数据拷贝的,也就是数据都是 copy_to_user 或者 copy_from_user,这样做的好处是,通过中间缓存的机制,减少磁盘 I/O 的操作,但是坏处也很明显,大量数据的拷贝,用户态和内核态的频繁切换,会消耗大量的 CPU 资源,严重影响数据传输的性能,统计表明,在Linux协议栈中,数据包在内核态和用户态之间的拷贝所用的时间甚至占到了数据包整个处理流程时间的57.1%

什么是零拷贝

        零拷贝就是上述问题的一个解决方案,通过尽量避免拷贝操作来缓解 CPU 的压力。零拷贝并没有真正做到“0”拷贝,它更多是一种思想,很多的零拷贝技术都是基于这个思想去做的优化

        减少 内核空间 和 用户空间之间拷贝次数。(sendfile)

MMAP ( Memory Mapping )

        mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问。

        mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。

        实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。内存映射减少数据在用户空间和内核空间之间的拷贝操作,适合大量数据传输

1. I/O 模型相关概览

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

同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态

        同步:内核处理完了 不会主动告诉nginx 你交代的任务 我做完了,需要nginx不停的询问内核有没有完成

        异步:内核处理完了 会主动告诉nginx 你交代的任务 我做完了

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

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

        比如我有 1 2 3 4 共四个请求

        nginx进程 在处理 1 请求的时候 是否可以继续处理 2 请求?

        阻塞:只能处理完 1 请求所有的任务再去接待2客户。

        非阻塞:在处理1请求的时候,内核是需要时间准备的,在内核准备时间里可以处理2请求。

2. 网络I/O模型

阻塞型、非阻塞型、复用型、信号驱动型、异步

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

        阻塞IO模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成read操作用户需要等待read将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够

优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销较大,apache 的preforck使用的是这种模式。

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

2.2 非阻塞型I/O模型(nonblocking IO)

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

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

        查看上图可知,在设置连接为非阻塞时,当应用进程系统调用 recvfrom 没有数据返回时,内核会立即返回一个 EWOULDBLOCK 错误,而不会一直阻塞到数据准备好。如上图在第四次调用时有一个数据报准备好了,所以这时数据会被复制到 应用进程缓冲区 ,于是 recvfrom 成功返回数据当一个应用进程这样循环调用 recvfrom 时,称之为轮询 polling 。这么做往往会耗费大量CPU时间,实际使用很少

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

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

        它的基本原理就是select/poll/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。当用户进程调用了select,那么整个进程会被block,而同时,kernel(内核)会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。Apache prefork是此模式的select,work是poll模式。

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

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

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

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

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

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

优点:线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此可以提高资源的利用率缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知

2.5 异步 I/O 模型(asynchronous IO)

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

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

        Nginx支持在多种不同的操作系统实现不同的事件驱动模型,但是其在不同的操作系统甚至是不同的系统版本上面的实现方式不尽相同,主要有以下实现方式:

1、select: select库是在linux和windows平台都基本支持的 事件驱动模型库,并且在接口的定义也基本相同,只是部分参数的含义略有差异,最大并发限制1024,是最早期的事件驱动模型。

2、poll: 在Linux 的基本驱动模型,windows不支持此驱动模型,是select的升级版,取消了最大的并发限制,在编译nginx的时候可以使用--with-poll_module和--without-poll_module这两个指定是否编译select库。

3、epoll: epoll是库是Nginx服务器支持的最高性能的事件驱动库之一,是公认的非常优秀的事件驱动模型,它和select和poll有很大的区别,epoll是poll的升级版,但是与poll有很大的区别.

epoll的处理方式是创建一个待处理的事件列表,然后把这个列表发给内核,返回的时候在去轮训检查这个表,以判断事件是否发生,epoll支持一个进程打开的最大事件描述符的上限是系统可以打开的文件的最大数,同时epoll库的I/O效率不随描述符数目增加而线性下降,因为它只会对内核上报的“活跃”的描述符进行操作。

4、rtsig: 不是一个常用事件驱动,最大队列1024,不是很常用 5、kqueue: 用于支持BSD系列平台的高校事件驱动模型,主要用在FreeBSD 4.1及以上版本、OpenBSD 2.0级以上版本,NetBSD级以上版本及Mac OS X 平台上,该模型也是poll库的变种,因此和epoll没有本质上的区别,都是通过避免轮训操作提供效率。

6、/dev/poll: 用于支持unix衍生平台的高效事件驱动模型,主要在Solaris 平台、HP/UX,该模型是sun公司在开发Solaris系列平台的时候提出的用于完成事件驱动机制的方案,它使用了虚拟的/dev/poll设备,开发人员将要见识的文件描述符加入这个设备,然后通过ioctl()调用来获取事件通知,因此运行在以上系列平台的时候请使用/dev/poll事件驱动机制。

7、eventport: 该方案也是sun公司在开发Solaris的时候提出的事件驱动库,只是Solaris 10以上的版本,该驱动库看防止内核崩溃等情况的发生。

8、Iocp:  Windows系统上的实现方式,对应第5种(异步I/O)模型。

三种主要的事件驱动模型

selectpoll epoll 操作方式遍历遍历回调底层实现数组链表哈希表IO效率每次调用都进行线性遍历,时间复杂度为O(n)同左事件通知方式,每当fd就绪,系统注册的回调函数就会被调用,将就绪的fd放到rdlllist里,事件复杂度O(1)最大连接数 1024(x86) 2048(x64) 无上限无上限fd拷贝每次调用select都需要把fd集合从用户拷贝到内核态。每次调用poll,都需要把fd集合从用户态拷贝到内核态调用epoll_wait不拷贝

用户态:应用程序  我们可以控制

内核态:操作系统层面,我们不容易去控制的 操作系统

Select: POSIX所规定,目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理

缺点: 单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义 FD_SETSIZE ,再重新编译内核实现,但是这样也会造成效率的降低 单个进程可监视的fd数量被限制,默认是1024,修改此值需要重新编译内核

对socket是线性扫描,即采用轮询的方法,效率较低

select 采取了内存拷贝方法来实现内核将 FD 消息通知给用户空间,这样一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大

poll: 本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态 其没有最大连接数的限制,原因是它是基于链表来存储的 大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义 poll特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd  select是边缘触发即只通知一次

epoll: 在Linux 2.6 内核中提出的 select 和 poll 的增强版本 支持水平触发 LT 和边缘触发 ET,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会 通知一次 使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知

优点: 没有最大并发连接的限制:能打开的FD的上限远大于1024(1G的内存能监听约10万个端口),具体查看/proc/sys/fs/file-max,此值和系统内存大小相关

效率提升:非轮询的方式,不会随着FD数目的增加而效率下降;只有活跃可用的FD才会调用callback函数, 即epoll最大的优点就在于它只管理“活跃”的连接,而跟连接总数无关 内存拷贝,利用mmap(Memory Mapping)加速与内核空间的消息传递;即epoll使用mmap减少复制开销

总结 select 和 epoll 之间的区别

select:会轮询遍历所有的 事件集合,其次遍历的事件个数有限制

epoll:只会遍历已准备好的事件集合,事件个数无限制

Nginx 概述

Nginx 功能介绍

静态的web资源服务器html,图片,js,css,txt等静态资源 http/https协议的反向代理 ,7层 url 结合FastCGI /uWSGI/SCGI等协议反向代理动态资源请求 tcp/udp协议的请求转发(反向代理) 4层

基础特性

模块化设计,较好的扩展性高可靠性支持热部署:不停机更新配置文件,升级版本,更换日志文件低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存event-driven,   aio,        mmap,sendfile

Web 服务相关的功能

虚拟主机(server)支持 keep-alive 和管道连接(利用一个连接做多次请求)访问日志(支持基于日志缓冲提高其性能)url rewirte  路径别名基于IP及用户的访问控制支持速率限制及并发数限制重新配置和在线升级而无须中断客户的工作进程

Nginx 架构

Nginx 进程结构

web请求处理机制

多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求。 多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程来个客户方进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。

主进程(master process)的功能:

对外接口:接收外部的操作(信号) 对内转发:根据外部的操作的不同,通过信号管理 Worker 监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程 读取Nginx 配置文件并验证其有效性和正确性 建立、绑定和关闭socket连接 按照配置生成、管理和结束工作进程 接受外界指令,比如重启、升级及退出服务器等指令 不中断服务,实现平滑升级,重启服务并应用新的配置 开启日志文件,获取文件描述符 不中断服务,实现平滑升级,升级失败进行回滚处理 编译和处理perl脚本

工作进程(worker process)的功能:

所有 Worker 进程都是平等的 实际处理:网络请求,由 Worker 进程处理 Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争CPU资源, 增加上下文切换的损耗 接受处理客户的请求 将请求依次送入各个功能模块进行处理 I/O调用,获取响应数据 与后端服务器通信,接收后端服务器的处理结果 缓存数据,访问缓存索引,查询和调用缓存数据 发送请求结果,响应客户的请求 接收主程序指令,比如重启、升级和退出等

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 版本支持动态装载和卸载

核心模块:core module 标准模块:  HTTP 模块: ngx_http_*  HTTP Core modules   #默认功能  HTTP Optional modules #需编译时指定  Mail 模块: ngx_mail_*  Stream 模块 ngx_stream_* 第三方模块

安装及使用Nginx

1.编译安装nginx

源码包内的文件:

contrib:vim 格式文件,修改nginx配置文件的格式,高亮 cp -r /opt/nginx-1.18.0/contrib/vim/* /usr/share/vim/vimfiles/ conf:配置文件 man:man帮助 man man/nginx.8 不加路径看不了 nginx.8 文件 src:源码包 点c 点h 结尾的文件

统计src 源码包中 源代码的行数 :find src -name *.c | xargs cat | wc -l

官网:https://nginx.org/en/download.html

yum -y install gcc pcre-devel openssl-devel zlib-devel openssl openssl-devel

#安装依赖包

useradd -M -s /sbin/nologin nginx

#新建nginx用户便于管理,不建立nginx程序用户会报错。

cd /opt/

wget http://nginx.org/download/nginx-1.18.0.tar.gz

#官网下载安装包

tar xf nginx-1.18.0.tar.gz

cd nginx-1.18.0/

#解压软件包

mkdir /apps/nginx -p

./configure --help

#查看帮助模块

./configure --prefix=/apps/nginx \

--user=nginx \

--group=nginx \

--with-http_ssl_module \

--with-http_v2_module \

--with-http_realip_module \

--with-http_stub_status_module \

--with-http_gzip_static_module \

--with-pcre \

--with-stream \

--with-stream_ssl_module \

--with-stream_realip_module

make

make install

chown -R nginx.nginx /apps/nginx

#修改权限(属主,属组)

######安装好后生成四个文件功能如下

1. conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能的,例如fastcgi功能使用的是fastcgi.conf和fastcgi_params两个文件,配置文件一般都有个样板配置文件,是文件名.default结尾,使用的使用将其复制为并将default去掉即可。 2. html目录中保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web文件是默认的错误页面提示页面。 3. logs:用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比如/var/logs/nginx里面。 4. sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能。

1.1 启动停止nginx

##########启动##############

/apps/nginx/sbin/nginx

#绝对路径启动

ln -s /apps/nginx/sbin/nginx /usr/bin

#设置软连接后直接 nginx启动

##########停止###############

killall nginx

没有创建nginx自启动文件,如何查看nginx是否启动

pstree -p | grep nginx

ps aux | grep nginx

1.2 创建Nginx 自启动文件

#复制同一版本的nginx的yum安装生成的service文件

vim /usr/lib/systemd/system/nginx.service

#建立文件

[Unit]

Description=nginx - high performance web server

Documentation=http://nginx.org/en/docs/

After=network-online.target remote-fs.target nss-lookup.target

Wants=network-online.target

[Service]

Type=forking

PIDFile=/apps/nginx/logs/nginx.pid

#注意文件位置,如果不对 启动不了

ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf

#注意启动文件位置

ExecReload=/bin/kill -s HUP $MAINPID

ExecStop=/bin/kill -s TERM $MAINPID

LimitNOFILE=100000

[Install]

WantedBy=multi-user.target

[root@localhost nginx]#systemctl daemon-reload

#重新加载配置

systemctl enable --now nginx

#开机自启并立即启动 如果卡住是因为logs下有 nginx.pid 文件 删除即可

chown -R nginx.nginx /apps/nginx

#修改权限

###如果需要修改pid文件可以执行以下操作#################

mkdir /apps/nginx/run/

#创建目录

vim /apps/nginx/conf/nginx.conf

#修改配置文件

pid   /apps/nginx/run/nginx.pid;

#找到 pid的位置修改

#######################################################

2. yum安装

centos7 需要安装epel源

yum install -y epel-release

#安装epel源 额外 rpeo

yum install nginx -y

yum nginx

去使用官方源按装较新的版本

http://nginx.org/en/linux_packages.html#RHEL

3.平滑升级及命令、信号使用

3.1 信号

nginx 命令支持向其发送信号,实现不同功能

nginx 当做单独命令使用有以下选项 

[root@localhost nginx]#nginx -h 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

#发送信号到主进程  stop 直接停止   reload重新加载配置文件  reopen分割日志  quit  优雅的退出

  -p prefix     : set prefix path (default: /apps/nginx/)

#指定运行目录

  -c filename   : set configuration file (default: conf/nginx.conf)

#使用指定的配置文件

  -g directives : set global directives out of configuration file

#指定配置指令

3.1.1 显示版本

[root@localhost nginx]#nginx -v nginx version: nginx/1.18.0

3.1.2 显示编译详细情况 模块等信息

[root@localhost nginx]#nginx -V nginx version: nginx/1.18.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)  built with OpenSSL 1.0.2k-fips  26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module

3.1.3 发送信号

kill -l 看信号大全

nginx -h 中可以看到的信号较少

s signal : send signal to a master process: stop, quit, reopen, reload

可以使用man手册来查看详细的信号 如果没安装,去源码包里找到man文件

man 路径/nginx.8 不加路径打不开man帮助

stop SIGTERM 直接停止

quit SIGQUIT 优雅的退出:有人在访问不会结束进程

reopen SIGUSR1 分割日志

reload SIGHUP 重新加载配置文件

SIGHUP Reload configuration, start the new worker process with a new configuration, and

gracefully shut down old worker processes.

SIGQUIT Shut down gracefully. 优雅的关闭:有人在访问不会结束进程

SIGUSR1 Reopen log files. 重新分割日志

SIGUSR2 Upgrade the nginx executable on the fly. 运行中升级

SIGWINCH Shut down worker processes gracefully. 优雅的关闭worker进程,work进程负责处理请求,还有请求不会关闭

帮助: -? -h 使用指定的配置文件: -c 指定配置指令:-g 指定运行目录:-p 测试配置文件是否有语法错误:-t -T 打印nginx的版本信息、编译信息等:-v -V 发送信号: -s 示例: nginx -s reload

实例:

nginx -s   stop   #立即关闭nginx nginx -s   quit   #优雅退出   不影响业务的状态下退出 nginx -s   reload #不关闭重新加载配置文件  

USR1分割日志

[root@localhost nginx]#cd /apps/nginx/logs/

#切换

[root@localhost logs]#ls

access.log error.log nginx.pid

access.log :记录正确日志

error.log :记录错误日志

nginx.pid :nginx的主进程pid号 cat nginx.pid

[root@localhost logs]#mv access.log access.log.bak

[root@localhost logs]#touch access.log

[root@localhost logs]#ls

access.log access.log.bak error.log nginx.pid

#把原来的日志文件改名为access.log.bak ,并建立一个空 access.log 文件

但是我们用另一台主机 curl 本机IP 后就会发现日志保存到了access.log.bak 文件中去了。

[root@localhost logs]#ll

总用量 12

-rw-r--r--. 1 root root 0 2月 20 19:10 access.log

-rw-r--r--. 1 root root 90 2月 20 19:07 access.log.bak

-rw-r--r--. 1 root root 1590 2月 20 18:56 error.log

-rw-r--r--. 1 root root 6 2月 20 18:42 nginx.pid

[root@wg ~]#curl 192.168.80.7

Welcome to nginx!

...略...

[root@localhost logs]#ll

总用量 12

-rw-r--r--. 1 root root 0 2月 20 19:10 access.log

-rw-r--r--. 1 root root 180 2月 20 19:13 access.log.bak

-rw-r--r--. 1 root root 1590 2月 20 18:56 error.log

-rw-r--r--. 1 root root 6 2月 20 18:42 nginx.pid

可以看到日志并没有保存到 access.log 文件中去。

需要给master 进程发送 USR1信号

[root@localhost logs]#pwd

/apps/nginx/logs

[root@localhost logs]#cat nginx.pid

21706

[root@localhost logs]#kill -s USR1 21706

#kill是要跟进程

或者

[root@localhost logs]#nginx -s reopen

#nginx -s 不能跟进程

[root@wg ~]#curl 192.168.80.7

[root@localhost logs]#ll

总用量 16

-rw-r--r--. 1 nginx root 90 2月 21 13:42 access.log

-rw-r--r--. 1 root root 270 2月 21 13:41 access.log.bak

-rw-r--r--. 1 nginx root 1651 2月 21 13:41 error.log

-rw-r--r--. 1 root root 6 2月 20 18:42 nginx.pid

3.1.4 指定配置 不已配置文件中的为准

nginx -g   指定配置 不已配置文件中的为准

nginx -g 'user zhangsan;'   已张三身份运行,默认是以nginx身份 nginx -g 'daemon off;'      前台运行命令

3.1.5  检查语法格式

nginx -t

3.2 升级 nginx1.18 nginx1.20

1. 将旧Nginx文件换成新Nginx文件(注意备份) 2. 向master进程发送USR2信号 3. master进程修改pid文件名,加后缀.oldbin 4. master进程用新Nginx文件启动新master进程,系统中将有新旧两个Nginx主进程共同提供Web服务 5. 向旧的Nginx服务进程发送WINCH信号,使旧的Nginx worker进程平滑停止,并删除Nginx.pid.oldbin文件 6. 向旧master进程发送QUIT信号,关闭老master 7. 如果发现升级有问题,可以回滚向老master发送HUP,向新master发送QUIT

[root@localhost ~]#wget https://nginx.org/download/nginx-1.20.2.tar.gz -P /mnt

#下载安装包到mnt目录

[root@localhost logs]#cd /mnt

[root@localhost mnt]#ls

nginx-1.20.2.tar.gz

[root@localhost mnt]#tar xf nginx-1.20.2.tar.gz

[root@localhost mnt]#cd nginx-1.20.2/

[root@localhost nginx-1.20.2]#ls

auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src

########################################################################

这时需要重新编译安装 ./configur 安装参数基本一致 这时可以使用 nginx -V 查看

########################################################################

[root@localhost nginx-1.20.2]#nginx -V

nginx version: nginx/1.18.0

built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)

built with OpenSSL 1.0.2k-fips 26 Jan 2017

TLS SNI support enabled

configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module

########################################################################

如果 有新模块在后添加即可

########################################################################

[root@localhost nginx-1.20.2]#./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module

#重新编译

[root@localhost nginx-1.20.2]#make

###########注意不要执行 make install

[root@localhost nginx-1.20.2]#ls

auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src

[root@localhost nginx-1.20.2]#cd objs/

#此文件夹中有新版本的nginx 运行程序

[root@localhost objs]#ls

autoconf.err Makefile nginx nginx.8 ngx_auto_config.h ngx_auto_headers.h ngx_modules.c ngx_modules.o src

[root@localhost objs]#./nginx -v

nginx version: nginx/1.20.2

#查看当前目录下nginx版本。

[root@localhost objs]#mv /apps/nginx/sbin/nginx /apps/nginx/sbin/nginx.bak

#将低版本的nginx主程序改名

[root@localhost objs]#cp /mnt/nginx-1.20.2/objs/nginx /apps/nginx/sbin/

#将新版本 拷入进去

[root@localhost objs]#ll /apps/nginx/sbin/

总用量 15308

-rwxr-xr-x. 1 root root 7896072 2月 21 14:09 nginx

-rwxr-xr-x. 1 nginx nginx 7774624 2月 20 18:26 nginx.bak

[root@localhost objs]#/apps/nginx/sbin/nginx -t

nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /apps/nginx/conf/nginx.conf test is successful

#检查下语法问题

[root@localhost objs]#cat /apps/nginx/logs/nginx.pid

22632

[root@localhost objs]#kill -USR2 22632

#发送 2 信号 信号在 man手册中可以看到

检验:

[root@localhost objs]#cd /apps/nginx/html/

[root@localhost html]#ls

50x.html index.html

[root@localhost html]#dd if=/dev/zero of=/apps/nginx/html/m.img bs=1G count=7

记录了7+0 的读入

记录了7+0 的写出

7516192768字节(7.5 GB)已复制,8.63538 秒,870 MB/秒

[root@localhost html]#ls

50x.html index.html m.img

#开启新机器下载

[root@wg data]#wget --limit-rate=1M http://192.168.80.7/m.img

--2024-02-21 14:20:30-- http://192.168.80.7/m.img

正在连接 192.168.80.7:80... 已连接。

已发出 HTTP 请求,正在等待回应... 200 OK

长度:7516192768 (7.0G) [application/octet-stream]

正在保存至: “m.img”

#回到网页服务器

[root@localhost html]#ss -ntap|grep 80

#查看那个进程在管理 下载

LISTEN 0 128 *:80 *:* users:(("nginx",pid=25800,fd=6),("nginx",pid=25799,fd=6),("nginx",pid=22668,fd=6),("nginx",pid=22632,fd=6))

ESTAB 0 1571240 192.168.80.7:80 192.168.80.11:60410 users:(("nginx",pid=25800,fd=3))

#会有 新老两个进程

[root@localhost html]#ls /apps/nginx/logs/

access.log access.log.bak error.log nginx.pid nginx.pid.oldbin

[root@localhost html]#cat /apps/nginx/logs/nginx.pid.oldbin

22632

#1.18老进程

[root@localhost html]#cat /apps/nginx/logs/nginx.pid

25799

#1.20新进程

[root@localhost html]#pstree -p |grep nginx

|-nginx(22632)-+-nginx(25799)---nginx(25800)

| `-nginx(22668)

[root@localhost html]#kill -WINCH 22632

#优雅关闭老进程的 worker 进程

#再开启一台服务器测试 是否是新的进程 在下载

[root@localhost ~]#wget --limit-rate=1M http://192.168.80.7/m.img

--2024-02-21 14:29:37-- http://192.168.80.7/m.img

正在连接 192.168.80.7:80... 已连接。

已发出 HTTP 请求,正在等待回应... 200 OK

长度:7516192768 (7.0G) [application/octet-stream]

正在保存至: “m.img”

#回到网页服务器可以看到 之前的在 但是又开启了一个 12

[root@localhost html]#ss -ntap|grep 80

LISTEN 0 128 *:80 *:* users:(("nginx",pid=25800,fd=6),("nginx",pid=25799,fd=6),("nginx",pid=22632,fd=6))

ESTAB 0 1422472 192.168.80.7:80 192.168.80.11:60410 users:(("nginx",pid=25800,fd=3))

ESTAB 0 682256 192.168.80.7:80 192.168.80.12:47120 users:(("nginx",pid=25800,fd=11))

测试一段时间无问题 就可以了,如果断掉第一个 下载 ,老的进程就关闭了

3.3. 回滚

把1.20版本的nginx返回到1.18版本。

[root@localhost html]#kill -HUP `cat /apps/nginx/logs/nginx.pid.oldbin`

#唤起老的进程

[root@localhost html]#kill -QUIT `cat /apps/nginx/logs/nginx.pid`

优雅的关闭新的进程:有人在访问不会结束进程

[root@localhost html]#curl -I 127.1

HTTP/1.1 200 OK

Server: nginx/1.18.0

Date: Wed, 21 Feb 2024 06:44:08 GMT

Content-Type: text/html

Content-Length: 612

Last-Modified: Tue, 20 Feb 2024 10:26:00 GMT

Connection: keep-alive

ETag: "65d47e38-264"

Accept-Ranges: bytes

4 配置详细解释

nginx 官方帮助文档:http://nginx.org/en/docs/

tengine 帮助文档:http://tengine.taobao.org/nginx_docs/cn/docs/

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

主配置文件:nginx.conf

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

配置文件由指令和指令块构成 每条指令以;分号结尾,指令与值之间以空格符号分隔 pid    /apps/run/nginx.pid 指令已{}达括号将多条指令组织在一起且可以嵌套指令块 include语句允许组合多个配置文件以提升可维护性  #号注释 $使用变量 部分支持正则 自定义变量:由用户使用set命令定义,格式: set variable_name value

1. 全局块

该部分配置主要影响Nginx全局,通常包括下面几个部分:

配置运行Nginx服务器用户(组) worker process数 Nginx进程PID存放路径 错误日志的存放路径 配置文件的引入

2. events块

该部分配置主要影响Nginx服务器与用户的网络连接,主要包括:

设置网络连接的序列化 是否允许同时接收多个网络连接 事件驱动模型的选择 最大连接数的配置

3. http块

定义MIMI-Type 自定义服务日志 允许sendfile方式传输文件 连接超时时间 单连接请求数上限

4. server块

配置网络监听 基于名称的虚拟主机配置 基于IP的虚拟主机配置

5. location块

location配置 请求根目录配置 更改location的URI 网站默认首页配置

全局配置 events{  控制事件驱动      } http  {  web网页配置有关   server  { location  }   }

main block:主配置段,即全局配置段,对http,mail都有效

#事件驱动相关的配置   同步 event {  ... }    #http/https 协议相关配置段 http {  ... }           #默认配置文件不包括下面两个块 #mail 协议相关配置段 mail {  ... }     #stream 服务器相关配置段 stream {负载均衡  ... }

4.1 全局配置

nginx 有多种模块

核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件驱动机制 、进程管理等核心功能标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置 等等可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如:Flash 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持Stream服务模块: 实现反向代理功能,包括TCP协议代理第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等

4.1.1  关闭版本或修改版本

Syntax:    server_tokens on | off | build | string;

#语法 Default:     server_tokens on;

#默认值 :开启 Context:    http, server, location

#这里的意思是 server_tokens 可以放在 http, server, location 中

例子:

[root@localhost html]#vim /apps/nginx/conf/nginx.conf

#修改配置文件 放在 http语句中

http {

server_tokens off;

[root@localhost html]#nginx -s reload

#重新加载

验证:

[root@localhost html]#curl -I 127.1

HTTP/1.1 200 OK

Server: nginx #版本被隐藏了

Date: Wed, 21 Feb 2024 07:12:02 GMT

Content-Type: text/html

Content-Length: 612

Last-Modified: Tue, 20 Feb 2024 10:26:00 GMT

Connection: keep-alive

ETag: "65d47e38-264"

Accept-Ranges: bytes

自行修改版本:

#去修改源码,在安装包里, 再重新编译 #号不要去掉

#先把服务关闭,不然编译不成功

如果你是用 systemctl start nginx 开启nginx ,在关闭时使用 systemctl stop nginx 关闭。

如果你是 运行的是 nginx 可执行文件 ,使用 nginx -s stop 关闭。

[root@localhost ~]#cd /opt

[root@localhost opt]#ls

html nginx-1.18.0 nginx-1.18.0.tar.gz

[root@localhost opt]#vim /opt/nginx-1.18.0/src/core/nginx.h

#在第13行和第14行

13 #define NGINX_VERSION "1.18.0"

14 #define NGINX_VER "nginx/" NGINX_VERSION

#更改""号内的内容即可。

13 #define NGINX_VERSION "114514"

14 #define NGINX_VER "home/" NGINX_VERSION

以上修改的是 server_tokens on; 的情况下。也就是默认情况 在不关闭版本的情况下 显示home/114514

[root@localhost opt]#vim /opt/nginx-1.18.0/src/http/ngx_http_header_filter_module.c

49 static u_char ngx_http_server_string[] = "Server: nginx" CRLF;

修改后

49 static u_char ngx_http_server_string[] = "Server: niganma" CRLF;

以上修改的是 server_tokens off; 的情况下。也就是 关闭版本 的情况下 显示 Server: niganma

重新编译安装

要关闭nginx

[root@localhost opt]#cd /opt/nginx-1.18.0/

[root@localhost nginx-1.18.0]#ls

auto CHANGES.ru configure html Makefile objs src

CHANGES conf contrib LICENSE man README

[root@localhost nginx-1.18.0]#./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module

[root@localhost nginx-1.18.0]#make -j 2 && make install

验证:

[root@localhost ~]#systemctl start nginx

[root@localhost ~]#vim /apps/nginx/conf/nginx.conf

#修改配置文件 放在 http语句中

http {

server_tokens off;

[root@localhost ~]#nginx -s reload

[root@localhost ~]#curl -I 127.1

HTTP/1.1 200 OK

Server: niganma #关闭版本情况

Date: Wed, 21 Feb 2024 07:35:55 GMT

Content-Type: text/html

Content-Length: 612

Last-Modified: Tue, 20 Feb 2024 10:26:00 GMT

Connection: keep-alive

ETag: "65d47e38-264"

Accept-Ranges: bytes

[root@localhost ~]#vim /apps/nginx/conf/nginx.conf

#修改配置文件 放在 http语句中

http {

server_tokens on;

[root@localhost ~]#nginx -s reload

[root@localhost ~]#curl -I 127.1

HTTP/1.1 200 OK

Server: home/114514 #开启版本情况

Date: Wed, 21 Feb 2024 07:44:54 GMT

Content-Type: text/html

Content-Length: 612

Last-Modified: Tue, 20 Feb 2024 10:26:00 GMT

Connection: keep-alive

ETag: "65d47e38-264"

Accept-Ranges: bytes

4.1.2 修改启动的进程数

Syntax:    worker_processes    number  |  auto

#语法

Default:     worker_processes 1;

#默认值 :1

Context:    main

#这里的意思是 worker_processes 可以放在 main 中(全局配置块)

worker_processes  1;    #允许的启动工作进程数数量,和你真实的cpu数量有关   1

worker_processes auto; #如果设置为auto  就是你真实的cpu数量 你有几个cpu就开几个进程

[root@localhost ~]#vim /apps/nginx/conf/nginx.conf

3 worker_processes auto;

#在第三行且原来默认为 1

[root@localhost ~]#nginx -s reload

[root@localhost ~]#ps axo pid,cmd,psr,ni|grep nginx

34028 nginx: master process /apps 3 0

35142 nginx: worker process 1 0

35143 nginx: worker process 2 0

35144 nginx: worker process 0 0

35145 nginx: worker process 3 0

35149 grep --color=auto nginx 0 0

pid:进程pid号

cmd:显示进程名称

psr :显示进程运行在几号cpu上 (这些进程不会运行在固定cpu上,来回切换会影响性能)

ni:显示进程的优先级

[root@localhost ~]#lscpu |grep 'CPU(s):'

CPU(s): 4

#4核cpu

[root@localhost ~]#pstree -p | grep nginx

|-nginx(34028)-+-nginx(35142)

| |-nginx(35143)

| |-nginx(35144)

| `-nginx(35145)

4.1.3 cpu与work 进程绑定

        将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占以一核心CPU,但是可以保证此进程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。

Syntax:    worker_cpu_affinity  cpumask  ...;

                worker_cpu_affinity  auto  [cpumask];

#语法

Default:    ——

#无默认值

Context:    main

#这里的意思是 worker_cpu_affinity 可以放在 main 中(全局配置块) 

CPU序号: CPU MASK:

00000001:0号CPU

00000010:1号CPU ................ 10000000:7号CPU

 worker_cpu_affinity 00000001 00000010 00000100 00001000     #第0号---第3号CPU    #序号绑定cpu    亲缘性

worker_cpu_affinity 00000101 00001010; #同一个work  可以绑定  两个cpu可以这么写 但是不建议,本来就是 不希望来回跳转,这样也是来回跳转。

实际操作:

[root@localhost ~]#vim /apps/nginx/conf/nginx.conf

worker_cpu_affinity 00000001 00000010 00000100 00001000;

#绑定到 第一、二、三、四 块cpu上

#注意 要绑一起绑

[root@localhost ~]#nginx -s reload

[root@localhost ~]#ps axo pid,cmd,psr,ni|grep -v grep |grep nginx

34028 nginx: master process /apps 3 0

36506 nginx: worker process 0 0

36507 nginx: worker process 1 0

36508 nginx: worker process 2 0

36509 nginx: worker process 3 0

验证cpu乱跑可以刷新网页即可

while true ;do ab -c 1000 -n 1000 http://192.168.91.100/;done

[root@localhost ~]#yum install httpd-tools -y

#安装压力测试的工具

4.1.4 PID 路径

pid    /apps/nginx/logs/nginx.pid;

pid  进程号文件位置可以自定义省略

4.1.5 nginx进程的优先级(work进程的优先级)

当你想将nginx的work进程的优先级调高  可以使用nice设置

nice的优先级是  -20 到 19

Syntax: worker_priority number;

#语法

Default:

worker_priority 0;

#默认值:0

#工作进程优先级,-20~20(19)     往小调,越小优先级越高。-20

Context: main

#这里的意思是 worker_priority 可以放在 main 中(全局配置块)

例子:

[root@localhost ~]#ps axo pid,cmd,psr,ni|grep nginx|sort -n

34028 nginx: master process /apps 3 0

36506 nginx: worker process 0 0

36507 nginx: worker process 1 0

36508 nginx: worker process 2 0

36509 nginx: worker process 3 0

37522 grep --color=auto nginx 0 0

#查看默认优先级,默认优先级为0

ni :显示进程的优先级

[root@localhost ~]#vim /apps/nginx/conf/nginx.conf

worker_priority -20;

#添加此项

[root@localhost ~]#nginx -s reload

[root@localhost ~]#ps axo pid,cmd,psr,ni|grep nginx|sort -n

34028 nginx: master process /apps 3 0

37659 nginx: worker process 0 -20

37660 nginx: worker process 1 -20

37661 nginx: worker process 2 -20

37662 nginx: worker process 3 -20

37673 grep --color=auto nginx 0 0

4.1.6 调试work进程打开的文件的个数

Syntax: worker_rlimit_nofile number;

#语法

Default: —

#无默认值

Context: main

#放在 main 中(全局配置块)

worker_rlimit_nofile 65536;  #所有worker进程能打开的文件数量上限,包括:Nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制.最好与ulimit -n 或者limits.conf的值保持一致,这个设置的是总打开数量

只要机器性能够多加几个也没问题

例子:

[root@localhost ~]#vim /apps/nginx/conf/nginx.conf

worker_processes 1;

worker_cpu_affinity 00000001;

worker_rlimit_nofile 65536;

#这个设置的是总打开数量

[root@localhost ~]#nginx -s reload

[root@localhost ~]#ps axo pid,cmd,psr,ni|grep nginx|sort -n

34028 nginx: master process /apps 1 0

39505 nginx: worker process 0 -20

40829 grep --color=auto nginx 2 0

#选择其中一个进程 到proc 下去查看 连接状态

[root@localhost ~]#ls /proc/39505/fd

#可以看到打开的连接数

0 1 10 11 12 2 3 4 5 6 7 9

可以在 2号机器上安装压力测试的工具写一个压力测试脚本

[root@localhost ~]#yum install httpd-tools -y

#安装压力测试的工具

[root@localhost ~]#while true ;do ab -c 1000 -n 1000 http://192.168.80.7/;done

回到1号机器

[root@localhost ~]#ls /proc/39505/fd

#在2号机压力测试后 就会产生很多 进程文件

改了后还需要 修改 系统默认项

[root@localhost ~]#ulimit -a

#单个进程能打开的文件是1024

core file size (blocks, -c) 0

data seg size (kbytes, -d) unlimited

scheduling priority (-e) 0

file size (blocks, -f) unlimited

pending signals (-i) 7168

max locked memory (kbytes, -l) 64

max memory size (kbytes, -m) unlimited

open files (-n) 1024

pipe size (512 bytes, -p) 8

POSIX message queues (bytes, -q) 819200

real-time priority (-r) 0

stack size (kbytes, -s) 8192

cpu time (seconds, -t) unlimited

max user processes (-u) 7168

virtual memory (kbytes, -v) unlimited

file locks (-x) unlimited

[root@localhost ~]#ulimit -n 60000

#只修改当前窗口

需要修改pam认证文件

[root@localhost ~]#vim /etc/security/limits.conf

#最后加入

* soft core unlimited

* hard core unlimited

* soft nproc 1000000

* hard nproc 1000000

* soft nofile 1000000

* hard nofile 1000000

* soft memlock 32000

* hard memlock 32000

* soft msgqueue 8192000

* hard msgqueue 8192000

#设置完后重启

[root@localhost ~]#ulimit -a

core file size (blocks, -c) unlimited

data seg size (kbytes, -d) unlimited

scheduling priority (-e) 0

file size (blocks, -f) unlimited

pending signals (-i) 7168

max locked memory (kbytes, -l) 32000

max memory size (kbytes, -m) unlimited

open files (-n) 1000000

pipe size (512 bytes, -p) 8

POSIX message queues (bytes, -q) 8192000

real-time priority (-r) 0

stack size (kbytes, -s) 8192

cpu time (seconds, -t) unlimited

max user processes (-u) 1000000

virtual memory (kbytes, -v) unlimited

file locks (-x) unlimited

4.1.7 服务是否以后台方式运行

一般服务都是后台运行,前台容器中会用到前台运行

Syntax: daemon on | off;

#语法

Default:

daemon on;

#默认值:on    默认后台运行

Context: main

#放在 main 中(全局配置块)

daemon off; #加入此选项 设置前台运行

4.1.8 只有 master进程没有 work进程

Syntax: master_process on | off;

#是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为on

Default:

master_process on;

Context: main

确定工作进程是否启动。这个指令适用于nginx开发人员。

实际生产中使用较少

4.2 event事件 io模型调优

events {    worker_connections  65536;  #设置单个工作进程的最大并发连接数    use epoll;    #使用epoll事件驱动,Nginx支持众多的事件驱动,比如:select、poll、epoll,只能设置在events模块中设置。

   accept_mutex on;     #on为同一时刻一个请求轮流由work进程处理,而防止被同时唤醒所有worker,避免多个睡眠进程被唤醒的设置,默认为off,新请求会唤醒所有worker进程,此过程也称为"惊群",因此nginx刚安装完以后要进行适当的优化。建议设置为on

   multi_accept on;     #ON时Nginx服务器的每个工作进程可以同时接受多个新的网络连接,此指令默认为off,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个。建议设置为on }

4.3 http设置

http  是一个大的语句块,包含若干个小的语句块(比如server语句块)

http {  ...  ...  #各server的公共配置  server {    #每个server用于定义一个虚拟主机,第一个server为默认虚拟服务器  ...  }  server {       ...  server_name   #虚拟主机名  root     #主目录  alias     #路径别名  location [OPERATOR] URL {     #指定URL的特性  ...  if CONDITION {  ...  }  }  } }

http 协议配置说明

http {

  include       mime.types; #导入支持的文件类型,是相对于/apps/nginx/conf的目录

  default_type application/octet-stream; #除mime.types中文件类型外,设置其它文件默认类型,访问其它类型时会提示下载不匹配的类型文件

#日志配置部分

   #log_format main '$remote_addr - $remote_user [$time_local] "$request" '

   #                 '$status $body_bytes_sent "$http_referer" '

   #                 '"$http_user_agent" "$http_x_forwarded_for"';

   #access_log logs/access.log main;

#自定义优化参数

  sendfile       on; #使用零拷贝技术传输文件

   #tcp_nopush     on; #在开启了sendfile的情况下,合并请求后统一发送给客户端。

   #tcp_nodelay   off; #在开启了keepalived模式下的连接是否启用TCP_NODELAY选项,当为off时,延迟0.2s发送,默认On时,不延迟发送,立即发送用户响应报文。

   #keepalive_timeout 0;

  keepalive_timeout  65 65; #设置会话保持时间,第二个值为响应首部:keepAlived:timeout=65,可以和第一个值不同

   #gzip on; #开启文件压缩

  server {

      listen       80; #设置监听地址和端口

      server_name localhost; #设置server name,可以以空格隔开写多个并支持正则表达式,如:*.kgc.com www.kgc.* ~^www\d+\.kgc\.com$ default_server

       #charset koi8-r; #设置编码格式,默认是俄语格式,建议改为utf-8

       #access_log logs/host.access.log main;

      location /fxj { # www.jntm.com/fxj /apps/nginx/html

          root   /data;

          index index.html index.htm;

      }

       #error_page 404             /404.html;

       # redirect server error pages to the static page /50x.html

       #

      error_page   500 502 503 504 /50x.html; #定义错误页面

      location = /50x.html {

          root   html;

      }

       # proxy the PHP scripts to Apache listening on 127.0.0.1:80

       #

       #location ~ \.php$ { #以http的方式转发php请求到指定web服务器

       #   proxy_pass   http://127.0.0.1;

       #}

       # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000

       #

       #location ~ \.php$ { #以fastcgi的方式转发php请求到php处理

       #   root           html;

       #   fastcgi_pass   127.0.0.1:9000;

       #   fastcgi_index index.php;

       #   fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;

       #   include       fastcgi_params;

       #}

       # deny access to .htaccess files, if Apache's document root

       # concurs with nginx's one

       #

       #location ~ /\.ht { #拒绝web形式访问指定文件,如很多的网站都是通过.htaccess文件来改变自己的重定向等功能。

       #   deny all;

       #}

      location ~ /passwd.html {

          deny all;

      }

  }

   # another virtual host using mix of IP-, name-, and port-based configuration

   #

   #server { #自定义虚拟server

3.3.1 MIME

范例: 识别php文件为text/html

   #   listen       8000;

   #   listen       somename:8080;

   #   server_name somename alias another.alias;

   #   location / {

   #       root   html;

   #       index index.html index.htm; #指定默认网页文件,此指令由ngx_http_index_module模块提供

   #   }

   #}

   # HTTPS server

   #

   #server { #https服务器配置

   #   listen       443 ssl;

   #   server_name localhost;

   #   ssl_certificate     cert.pem;

   #   ssl_certificate_key cert.key;

   #   ssl_session_cache   shared:SSL:1m;

   #   ssl_session_timeout 5m;

   #   ssl_ciphers HIGH:!aNULL:!MD5;

   #   ssl_prefer_server_ciphers on;

   #   location / {

   #       root   html;

   #       index index.html index.htm;

   #   }

   #}

4.3.1 mime

此项为支持的 文件格式,如果不支持的格式 会自动帮你下载,如果支持 就会显示在网页上

[root@localhost ~]#vim /apps/nginx/conf/mime.types

types {

text/html html htm shtml;

.....................................................................

image/png png;

image/svg+xml svg svgz;

image/tiff tif tiff;

image/vnd.wap.wbmp wbmp;

image/webp webp;

image/x-icon ico;

image/x-jng jng;

image/x-ms-bmp bmp;

4.3.2 server 下的 root

root指定了主页文件的位置

root路径格式 指定文件的路径    url   Syntax:    root path; Default:     root html; Context:    http, server, location, if in location

指明  你软件的根目录

root   指明根目录的位置 location  根据 用户访问地址的不同,指定访问的目录

4.3.3 server块构建虚拟主机

好像访问的是多台主机,实际上只有1台主机

我们构建不同虚拟主机   PC端和手机端

过程:

[root@localhost ~]#vim /apps/nginx/conf/nginx.conf

#修改配置文件 要放在 http 模块里

http {

include /apps/nginx/conf.d/*.conf;

[root@localhost ~]#mkdir -p /apps/nginx/conf.d/

#建立子配置文件

[root@localhost ~]#cd /apps/nginx/conf.d/

[root@localhost conf.d]#vim pc.conf

#分别编写配置文件

server {

listen 80;

server_name www.pc.com;

location / {

root /pc/;

}

}

[root@localhost conf.d]#vim m.conf

server {

listen 80; #监听端口

server_name www.m.com; #域名

location / {

root /m/;

}

}

[root@localhost conf.d]#mkdir /pc

[root@localhost conf.d]#mkdir /m

#构建数据文件夹

[root@localhost conf.d]#echo "hello pc" > /pc/index.html

[root@localhost conf.d]#echo "hello m" > /m/index.html

#构建数据文件

记得nginx -t检查配置是否输错。

[root@localhost conf.d]#nginx -s reload

去第二台机器修改/etc/hosts 文件

[root@wg data]#vim /etc/hosts

192.168.80.7 www.pc.com www.m.com

[root@wg data]#curl www.pc.com

hello pc

[root@wg data]#curl www.m.com

hello m

基于端口:

[root@localhost ~]#cd /apps/nginx/conf.d/

[root@localhost conf.d]#vim pc.conf

#分别编写配置文件

server {

listen 192.168.80.7:9327; #监听访问本机 ip:9327端口的请求

server_name www.pc.com;

location / {

root /pc/;

}

}

[root@localhost conf.d]#vim m.conf

server {

listen 192.168.80.7:80; #监听访问本机 ip:80端口的请求

server_name www.m.com; #域名

location / {

root /m/;

}

}

基于不同ip

ifconfig ens33:0 192.168.80.8/24

[root@localhost ~]#cd /apps/nginx/conf.d/

[root@localhost conf.d]#vim pc.conf

#分别编写配置文件

server {

listen 192.168.80.7:80;

server_name www.pc.com;

location / {

root /pc/;

}

}

[root@localhost conf.d]#vim m.conf

server {

listen 192.168.80.8:80;

server_name www.m.com;

location / {

root /m/;

}

}

4.3.4 alias 别名

别名设置

server {    listen 80;    server_name www.pc.com;    location /news {         root /pc/;         #相当于追加    将文件夹 news 追加到/pc/news

        #你访问192.168.80.7/news 就相当于访问 /pc/news目录下的index.html文件         }    location /study {         alias /mnt/nginx/sports/;         #相当于替换 你访问 /study  就是访问/mnt/nginx/sports         } }

#location 后面的根 / 是nginx网页文件的位置 (/apps/nginx/html/)

4.3.5 location

什么是url? 文件路径描述符    比如 www.m.com/

在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,按一定的优化级找出一个最佳匹配,而后应用其配置在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最高的一个uri,uri是用户请求的字符串,即域名后面的web文件路径,然后使用该location模块中的正则url和字符串,如果匹配成功就结束搜索,并使用此location处理此请求。

location 官方帮助:

Module ngx_http_core_module

语法规则:

#语法规则:

location [ = | ~ | ~* | ^~ ] uri { ... }

= #用于标准url前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求

^~ #用于标准url前,表示包含正则表达式,并且匹配以指定的正则表达式开头,对URI的最左边部分做匹配检查,不区分字符大小写

~ #用于标准url前,表示包含正则表达式,并且区分大小写

~* #用于标准url前,表示包含正则表达式,并且不区分大写

不带符号 #匹配起始于此uri的所有的uri

#\ #用于标准url前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号

#匹配优先级从高到低:

=, ^~, ~/~*, 不带符号

~ 与 ~* 优先级相同, 谁在配置前面就先匹配谁

=                  用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立即处理请求^~            用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头,对URI的最左边部分做匹配检查,不区分字符大小写~                用于标准uri前,表示包含正则表达式,并且区分大小写~*              用于标准uri前,表示包含正则表达式,并且不区分大写不带符号     匹配起始于此uri的所有的uri  \               用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号

4.3.5.1 不区分大小写案例 ~*

        ~* 用来对用户请求的 uri 做模糊匹配,uri 中无论都是大写、都是小写或者大小写混合,此模式也都会匹配,通常使用此模式匹配用户request中的静态资源并继续做下一步操作,此方式使用较多注意: 此方式中,对于Linux文件系统上的文件仍然是区分大小写的,如果磁盘文件不存在,仍会提示404 ~* 虽然 不区分大小写 但是linux系统的文件系统xfs区分大小写

#正则表达式匹配:

server {

listen 80;

server_name www.pc.com;

location ~* /A.?\.jpg {

##匹配 已A后面一个或没有字符,已.jpg结尾的图片

## .? 代表的意思是 一个或没有字符。 比如你/opt/html目录下有 A.jpg 和 A1.jpg ,你访问http://192.168.80.7的时候

##使用http://192.168.80.7/A.jpg 和 http://192.168.80.7/A1.jpg 都可以访问到/opt/html目录下的图片

root /opt/html/;

}

}

只要是图片就去 html 中找

server {

listen 80;

server_name www.pc.com;

location ~* \.(gif|jpg|jpeg)$ {

#访问格式:http://192.168.80.7/A.jpg

root /opt/html/;

}

}

#########匹配优先级#########

关于优先级的一些小问题:

#匹配优先级从高到低:

=, ^~, ~/~*, 不带符号

例子:

[root@localhost ~]#mkdir /mnt/html/

[root@localhost ~]#echo 'mnt/html' > /mnt/html/index.html

[root@localhost ~]#mkdir /opt/html/

[root@localhost ~]#echo 'opt/html' > /opt/html/index.html

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

location = / {

root /opt/html/;

}

location / {

root /mnt/html/;

}

}

#按理来说 = 优先级最高,最终匹配的是/opt/html文件下的index.html文件。但可惜并不是。

[root@localhost ~]#nginx -s reload

[root@wg ~]#curl 192.168.80.7/

mnt/html

[root@wg ~]#curl 192.168.80.7

mnt/html

#可它匹配的是没等号的。

测验优先级:

#匹配优先级:=, ^~, ~/~*,/

[root@localhost ~]#mkdir -p /opt/nginx/static{1,2,3,4}

[root@localhost ~]#echo 'static1' > /opt/nginx/static1/1.txt

[root@localhost ~]#echo 'static2' > /opt/nginx/static2/1.txt

[root@localhost ~]#echo 'static3' > /opt/nginx/static3/1.txt

[root@localhost ~]#echo 'static4' > /opt/nginx/static4/1.txt

[root@localhost ~]#tree /opt/nginx/

/opt/nginx/

├── static1

│   └── 1.txt

├── static2

│   └── 1.txt

├── static3

│   └── 1.txt

└── static4

└── 1.txt

4 directories, 4 files

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

location ~ \.(txt)$ {

root /opt/nginx/static1;

}

location ~* \.(txt)$ {

root /opt/nginx/static2/;

}

location ^~ /1.txt {

root /opt/nginx/static3/;

}

location = /1.txt {

root /opt/nginx/static4/;

}

}

[root@localhost html]#nginx -s reload

验证:

[root@wg ~]#curl 192.168.80.7/1.txt

static4

# = 最先被匹配 然后回到主机把配置文件里 = 删掉。

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

location ~ \.(t)$ {

root /opt/nginx/static1/;

}

location ~* \.(t)$ {

root /opt/nginx/static2/;

}

location ^~ /1.t {

root /opt/nginx/static3/;

}

}

[root@localhost html]#nginx -s reload

验证:

[root@wg ~]#curl 192.168.80.7/1.txt

static3

# ^~ 第二个被匹配 然后回到主机把配置文件里 ^~ 删掉。

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

location ~ \.(t)$ {

root /opt/nginx/static1/;

}

location ~* \.(t)$ {

root /opt/nginx/static2/;

}

}

[root@localhost html]#nginx -s reload

验证: 因为 ~ 与 ~* 谁在前就先匹配谁

[root@wg ~]#curl 192.168.80.7/1.txt

static1

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

location ~* \.(t)$ {

root /opt/nginx/static2/;

}

location ~ \.(t)$ {

root /opt/nginx/static1/;

}

}

[root@localhost html]#nginx -s reload

验证:

[root@wg ~]#curl 192.168.80.7/1.txt

static2

4.3.5.2生产案例

#直接匹配网站根会加速Nginx访问处理

location = /index.html {

  ......;

}

location / {

  ......;

}

#静态资源配置方法1

location ^~ /static/ {

  ......;

}

#静态资源配置方法2,应用较多

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {

  ......;

}

#多应用配置

location ~* /app1 {

    ......;

}

location ~* /app2 {

    ......;

}

实际网站使用中,至少有三个匹配规则定义:

#第一个必选规则

直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。

可以是一个静态首页,也可以直接转发给后端应用服务器

location = /index.html {

    root html;

index index.html index.htm;

}

#第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项

有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用

location ^~ /static/ {

    root /webroot/static/;

}

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {

    root /webroot/res/;

}

#第三个规则就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器

非静态文件请求就默认是动态请求

location / {

    proxy_pass http://tomcat_server;

}

4.3.6   access 模块      四层控制

Module ngx_http_access_module

[root@localhost nginx-1.18.0]#./configure --help |grep access

# 可以去源码包中 过滤 access模块 自带 不想要可以 without 去掉

--without-http_access_module disable ngx_http_access_module

--http-log-path=PATH set http access log pathname

--without-stream_access_module disable ngx_stream_access_module

自带模块,官方提供的 功能第三方模块 ,需要自己下载并在编译时加进去

例子:

配置文件修改

server {

listen 80;

server_name www.jntm.com;

allow 192.168.80.0/24; #允许192.168.80.0/24网段的用户访问

deny 192.168.80.11; #拒绝192.168.80.11用户的访问

deny all; #拒绝所有

location / {

root /data/nginx/html/;

}

}

#ip越精确,越往上写。范围越广,越往下(一般情况)

4.3.7 验证模块 需要输入用户名和密码

模块名称:ngx_http_auth_basic_module

访问控制模块基于模块ngx_http_access_module实现,可以通过匹配客户端源IP地址进行限制

注意:如果能在防火墙设备控制,最好不要在nginx上配置,可以更好的节约资源。

语法:

Syntax: auth_basic string | off;

Default:

auth_basic off;

Context: http, server, location, limit_except

 

Syntax: auth_basic_user_file file;

#语法:密码文件存放位置

Default: —

Context: http, server, location, limit_except

例子:

server {

listen 80;

server_name www.kgc.com;

location /pc {

root /opt/html/;

#追加 访问/opt 相当于访问/opt/html/pc/目录下的index.html

auth_basic "hello";

#提示信息,不是所有浏览器都有用

auth_basic_user_file /opt/passwd/.lisi;

#密码文件存放位置 ,需要通过命令生成

}

}

htpasswd

此命令来自于 httpd-tools 包,如果没有安装 一下即可

yum install -y httpd-tools

使用方法:

第一次生成文件 htpasswd -c  文件路径 姓名             交互式生成密码 htpasswd -bc 文件路径 姓名 密码           直接将密码跟在后面

-c  代表新建用户名和密码对应的文件 -b  将密码跟在用户名后

非第一次(更改生成后的密码文件) htpasswd     文件路径 姓名             交互式生成密码 htpasswd -b  文件路径 姓名 密码           直接将密码跟在后面

第一次

[root@localhost html]#mkdir -p /opt/passwd

[root@localhost passwd]#htpasswd -bc /opt/passwd/.lisi lisi 123

Adding password for user lisi

#-b 将名字密码跟在后面 -c 新建文件

[root@localhost passwd]#cat /opt/passwd/.lisi

lisi:$apr1$lT1obYH7$1lo0A4Iy6L8Zv05qPj52F0

非第一次

[root@localhost passwd]#htpasswd -b /opt/passwd/.lisi wang 123456

Adding password for user wang

[root@localhost passwd]#cat /opt/passwd/.lisi

lisi:$apr1$lT1obYH7$1lo0A4Iy6L8Zv05qPj52F0

wang:$apr1$H6YkC9ho$.xFiQ8.ofJDUJ2nSdEE0M.

#在密码文件中添加新的用户和密码

[root@localhost passwd]#htpasswd -b /opt/passwd/.lisi lisi 123456

Updating password for user lisi

[root@localhost passwd]#cat /opt/passwd/.lisi

lisi:$apr1$yIy.1dL8$YV/mU7ir4bIsIpUe3yS1P/

wang:$apr1$H6YkC9ho$.xFiQ8.ofJDUJ2nSdEE0M.

#更改lisi用户的密码

实例:

[root@localhost pc]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.jntm.com;

location /pc {

root /opt/html/;

#追加 访问/pc 相当于访问/opt/html/pc/ 目录下的 index.html

auth_basic "hello";

auth_basic_user_file /opt/passwd/.lisi;

}

}

[root@localhost pc]#nginx -s reload

 提示信息如下 火狐浏览器有,谷歌没有

​​​​​​​

4.3.8 自定义 错误页面

​​​​​​​

我们 可以改变  默认的错误页面,同时也可以用指定的响应状态码进行响应

Syntax: error_page code ... [=[response]] uri;

页面错误代码

Default: —

Context: http, server, location, if in location

 

error_page    固定写法 code          响应码 =             可以将响应码转换 uri           访问连接​​​​​​​

实际操作:

[root@localhost pc]#mkdir -p /opt/html/pc/error

[root@localhost pc]#vim /opt/html/pc/error/40x.html

你可以尝试访问http://192.168.80.7

[root@localhost pc]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.jntm.com;

charset utf-8;

root /opt/html;

error_page 404 /40x.html;

location /40x.html {

root /opt/html/pc/error/;

}

}

[root@localhost pc]#nginx -s reload

验证:

[root@localhost pc]#curl 192.168.80.7

opt/html

[root@localhost pc]#curl 192.168.80.7/651

你可以尝试访问http://192.168.80.7

自定义 错误码

[root@localhost pc]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.jntm.com;

charset utf-8;

root /opt/html;

error_page 404 =302 /40x.html;

#把错误码 404 指定成302 注意此处的 40x.html 需要真实存在建立的页面必须一致

location /40x.html {

root /opt/html/pc/error/;

}

}

[root@localhost pc]#nginx -s reload

#用处:因用户输入错误的地址 导致 出现404错误码,但是某些浏览器会把 404 跳转成他们设置的404(广告)使用此配置就不会出现该情况。

#出了错  直接跳转到显示主站点

server {

listen 80;

server_name www.jntm.com;

root /opt/html/pc;

error_page 404 =302 /index.html;

#把错误码 404 指定成302 并跳到主页面:/index.html

}

4.3.9 日志位置存放

Syntax: error_log file [level];

Default:

error_log logs/error.log error;

Context: main, http, mail, stream, server, location

 

 

Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

access_log off;

Default:

access_log logs/access.log combined;

Context: http, server, location, if in location, limit_except

定义错误日志文件:

实际操作,将两个网站的 日志分离

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

charset utf-8;

location /pc {

root /opt/html;

error_log /riz/logs/pc_error.log;

access_log /riz/logs/pc_access.log;

}

}

[root@localhost ~]#vim /apps/nginx/conf.d/m.conf

server {

listen 80;

server_name www.m.com;

charset utf-8;

location /m {

root /opt/html;

error_log /riz/logs/m_error.log;

access_log /riz/logs/m_access.log;

}

}

[root@localhost ~]#mkdir -p /riz/logs/

[root@localhost ~]#mkdir -p /opt/html/pc

[root@localhost html]#mkdir -p /opt/html/m

[root@localhost ~]#echo "欢迎访问pc" > /opt/html/pc/index.html

[root@localhost ~]#echo "欢迎访问m" > /opt/html/m/index.html

[root@localhost ~]#nginx -s reload

查看日志是否生效

4.3.10 检测文件是否存在

        try_files会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内部500错误。

        语法格式:

Syntax: try_files file ... uri;

        try_files file ... =code;

Default: —

Context: server, location

例子:

location / {

  root /opt/html/pc;

  try_files $uri  $uri.html $uri/index.html /about/default.html;

   #try_files $uri $uri/index.html $uri.html =489;

}

www.pc.com/abc

我的访问是路径下的abc文件,那按照设置,先会去找abc,没有abc会在后面加上abc.html,再没有会在路径后补上abc/index.html

最后没有会有一个兜底的

[root@centos8 ~]# echo "default page" >> /opt/html/pc/about/default.html

#重新加载nginx配置文件并测试,当访问到http://www.pc.com/about/default.html等不存在的uri会显示

default.html,如果是自定义的状态码则会显示在返回数据的状态码中

#注释default.html行,启用上面489行生效后,再观察结果

[root@centos8 ~]#curl -I http://www.pc.com/about/default.html

HTTP/1.1 489 #489就是自定义的状态返回码(失败的时候返回)

Server: nginx

Date: Fri, 23 Feb 2024 06:38:43 GMT

Content-Length: 15

Connection: keep-alive

Keep-Alive: timeout=65

例子 解释

#一定要有兜底否则也还是报错 我测试的结果 pc.html是兜底的可能版本不一

location / {

root /opt/html;

try_files $uri  $uri.html $uri/index.html /about/default.html;

#你如果 访问一个路径 /pc 如果没有这个页面 先去找pc , pc.html

#然后再去找 pc/index.html

#最后再找/about/default.html

}

实际操作:

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

charset utf-8;

location / {

root /opt/html/pc;

try_files $uri  $uri.html $uri/index.html /about/default.html;

}

}

[root@localhost ~]#mkdir /opt/html/pc/about/

[root@localhost ~]#echo "default page" > /opt/html/pc/about/default.html

[root@localhost ~]#nginx -s reload

[root@localhost ~]#tree /opt/html/

/opt/html/

├── m

│   └── index.html

└── pc

├── about

│   └── default.html

└── index.html

3 directories, 3 files

测验:

[root@wg ~]#curl 192.168.80.7/

欢迎访问pc

[root@wg ~]#curl 192.168.80.7/p

default page

设置返回响应码:

server {

listen 80;

server_name www.pc.com;

charset utf-8;

location / {

root /opt/html/pc;

try_files $uri  $uri.html $uri/index.html $uri/default.html =489;

}

}

#如果你在配置文件中写入 try_files /about/default.html =489; 是不会出现489响应码的因为它会在配匹

失败的时候出现。 这样写只会成功,不会失败也就不会出现489响应码。

自定义和重新定义页面

server{

listen 80;

server_name www.pc.com;

location / {

root opt/html/pc;

try_files $uri  $uri.html $uri/index.html =489;

}

error_page 489 /40x.html;

location = /40x.html {

root /opt/html/error/;

}

}

4.3.11 长连接

http     基于  tcp  协议    先要  三次握手然后 再传输数据

一次三次握手 下载多个资源

一次三次握手下载一个资源

Syntax: keepalive_timeout timeout [header_timeout];

Default:

keepalive_timeout 75s;

Context: http, server, location

Syntax: keepalive_requests number;

Default:

keepalive_requests 1000;

Context: http, server, location

This directive appeared in version 0.8.0.

该指令出现在0.8.0版本中。 ​​​​​​​

相关设置

keepalive_timeout timeout [header_timeout];   #设定保持连接超时时长,0表示禁止长连接,默认大概为65-75s  版本不一 各不相同,通常配置在http字段作为站点全局配置

keepalive_requests number;   #在一次长连接上所允许请求的资源的最大数量,默认为100次,建议适当调大,比如:500 可以加在全局或者 server 

例子:

keepalive_requests 3; #最大下载三个资源就会断开

keepalive_timeout 60 65;   #只能有一个空格  #开启长连接后,返回客户端的会话保持时间为60s,单次长连接累计请求达到指定次数请求或65秒就会被断开,后面的60为发送给客户端应答报文头部中显示的超时时间设置为60s:如不设置客户端将不显示超时时间。

Keep-Alive:timeout=60  #浏览器收到的服务器返回的报文 #如果设置为0表示关闭会话保持功能,将如下显示: Connection:close  #浏览器收到的服务器返回的报文

对哪种浏览器禁用长连接

Syntax: keepalive_disable none | browser ...;

#对哪种浏览器禁用长连接

Default:

keepalive_disable msie6;

Context: http, server, location

实际操作:

测试需要安装httpd-tools。

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

charset utf-8;

keepalive_requests 2;

keepalive_timeout 270 300;

location / {

root /opt/html/pc;

}

}

[root@localhost ~]#echo awfaeaef > /opt/html/pc/a.txt

[root@localhost ~]#echo efjpwpwg > /opt/html/pc/b.txt

[root@localhost ~]#echo qwiqfneo > /opt/html/pc/c.txt

[root@localhost ~]#nginx -s reload

[root@wg ~]#telnet 192.168.80.7 80

Trying 192.168.80.7...

Connected to 192.168.80.7.

Escape character is '^]'.

GET /a.txt HTTP/1.1 #获取根目录下的a.txt文件 使用HTTP版本

HOST:www.pc.com #域名

#回车

HTTP/1.1 200 OK

Server: nginx/1.18.0

Date: Fri, 23 Feb 2024 08:00:21 GMT

Content-Type: text/plain; charset=utf-8

Content-Length: 9

Last-Modified: Fri, 23 Feb 2024 07:52:49 GMT

Connection: keep-alive

Keep-Alive: timeout=300

ETag: "65d84ed1-9"

Accept-Ranges: bytes

awfaeaef

4.3.12 作为下载服务器配置

ngx_http_autoindex_module 模块处理以斜杠字符 "/" 结尾的请求,并生成目录列表,可以做为下载服务配置使用

官方文档:Module ngx_http_autoindex_module

[root@localhost nginx-1.18.0]#./configure --help |grep auto #自带   --without-http_autoindex_module    disable ngx_http_autoindex_module

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 #变量提供 限制   变量优先级高

例子实现:

server {

listen 80;

server_name www.pc.com;

charset utf-8;

location /download {

autoindex on;

#开启下载服务器

autoindex_exact_size off;

#关闭确切大小

limit_rate 1024k;

#所有人限速1024k,默认单位是字节数

set $limit_rate 2M;

#谁先生效? 变量优先级高 set 后面的先生效

alias /opt/download;

#别名 访问/download 相当于访问/opr/download

}

}

4.3.13 用户上传资料

上传需要借助开发小的程序, 并且程序 5M 和 nginx  10M 都会限制。 两者取最小

client_max_body_size 1m;

#设置允许客户端上传单个文件的最大值,默认值为1m,上传文件超过此值会出413错误

client_body_buffer_size size;

#用于接收每个客户端请求报文的body部分的缓冲区大小;默认16k;超出此大小时,其将被暂存到磁盘上的由下面client_body_temp_path指令所定义的位置

client_body_temp_path path [level1 [level2 [level3]]];

#设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量,目录名为16进制的数字,使用hash之后的值从后往前截取1位、2位、2位作为目录名

上传文件大于限制 错误代码413

4.3.14 其他设置

directio size | off; #操作完全和aio相反,aio是读取文件而directio是写文件到磁盘,启用直接I/O,默认为关闭,当文件大于等于给定大小时,例如:directio 4m;同步(直接)写磁盘,而非写缓存。

意思是:数据 是直接 写入 磁盘     还是等待一定数据量写入磁盘

open_file_cache off;  #是否缓存打开过的文件信息

open_file_cache max=N [inactive=time];

#nginx可以缓存以下三种信息:

(1) 文件元数据:文件的描述符、文件大小和最近一次的修改时间

(2) 打开的目录结构

(3) 没有找到的或者没有权限访问的文件的相关信息

max=N:#可缓存的缓存项上限数量;达到上限后会使用LRU(Least recently used,最近最少使用)算法实现管理

inactive=time:#缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于

open_file_cache_min_uses

#指令所指定的次数的缓存项即为非活动项,将被删除

open_file_cache_valid time;

#缓存项有效性的检查验证频率,默认值为60s

open_file_cache_errors on | off;

#是否缓存查找时发生错误的文件一类的信息,默认值为off

open_file_cache_min_uses number;

#open_file_cache指令的inactive参数指定的时长内,至少被命中此处指定的次数方可被归类为活动项,默认值为1

范例:

open_file_cache max=10000 inactive=60s;

#最大缓存10000个文件,非活动数据超时时长60s

open_file_cache_valid   60s;  

#每间隔60s检查一下缓存数据有效性

open_file_cache_min_uses 5;

#60秒内至少被命中访问5次才被标记为活动数据

open_file_cache_errors   on;

#缓存错误信息

limit_except method ... { ... },仅用于location

#限制客户端使用除了指定的请求方法之外的其它方法

method:GET, HEAD, POST, PUT, DELETE,MKCOL, COPY, MOVE, OPTIONS, PROPFIND,

PROPPATCH, LOCK, UNLOCK, PATCH

limit_except GET {

allow 192.168.91.101;

deny all;

}

#除了GET和HEAD 之外其它方法仅允许192.168.1.0/24网段主机使用

5 高级配置

5.1 网页的状态页

        基于nginx 模块 ngx_http_stub_status_module 实现,在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module,否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态

​​​​​​​Syntax: stub_status;

Default: —

Context: server, location

配置实例:

location /nginx_status {

  #stub_status;

  auth_basic           "auth login";

  #提示信息,不是所有浏览器都有用

  auth_basic_user_file /apps/nginx/conf/.htpasswd;

  #密码文件存放位置 ,需要通过命令生成

  allow 192.168.80.0/24; #只允许192.168.80.0/24网段的主机访问

  allow 127.0.0.1;

  deny all; #白名单 拒绝所有访问

}

while : ;do ab -c 1000 -n 10000 http://192.168.91.100/;sleep 1;done

#压力测试 模拟高链接

如何使用 curl 文字浏览器访问需要输入用户名和密码的地址?

curl http://用户名:密码@www.pc.com/nginx_status 2>/dev/null |awk '/Reading/{print $2,$4,$6}'

# 2>/dev/null 把错误信息导入到 空文件中

#awk '/Reading/{print $2,$4,$6}' 以空格为分隔符提取出 Reading 行的第 2 4 6 字符。

实际操作:

只需要添加 location

location /nginx_status {

  stub_status;

}

#状态页用于输出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)

##############为了安全考虑#####################

增加验证模块

server{

listen 80;

server_name www.pc.com;

root /data/nginx/pc;

location /admin {

stub_status;

auth_basic "admin site";

auth_basic_user_file /opt/passwd/.lisi;

}

}

5.2 Nginx 第三方模块

5.2.1 echo模块

别人写好的,非官方模块。

开源的echo模块 https://github.com/openresty/echo-nginx-module

如何在已经编译安装后添加echo模块?

下载echo模块:

[root@localhost opt]#yum install git -y

#安装git

[root@localhost opt]#git clone https://github.com/openresty/echo-nginx-module.git

[root@localhost opt]#ls

echo-nginx-module html nginx-1.18.0 nginx-1.18.0.tar.gz

切换到解压 nginx 安装包后 获得的目录 nginx-1.18.0

[root@localhost ~]#cd /opt/nginx-1.18.0

重新编译并在原来的后面加上想要的 模块

./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/opt/echo-nginx-module

make && make install

[root@localhost nginx-1.18.0]#systemctl restart nginx

[root@localhost nginx-1.18.0]#nginx -t

nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /apps/nginx/conf/nginx.conf test is successful

测试echo模块:

vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

charset utf-8;

location /hello {

default_type text/html;

echo "hello world";

}

}

第二台机器

[root@wg ~]#curl 192.168.80.7/hello

hello world

5.3 变量

http://nginx.org/en/docs/varindex.html​​​​​​​ 官方文档

5.3.1 内置变量

常用内置变量

$remote_addr;

#存放了客户端的地址,注意是客户端的公网IP

$proxy_add_x_forwarded_for

#此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔,如果请求中没有X-Forwarded-For,就使用$remote_addrthe “X-Forwarded-For” client request header field with the $remote_addr variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable.

客户机 代理1 代理2 nginx服务器

$proxy_add_x_forwarded_for: 在代理1 上存的是 客户机的ip

$proxy_add_x_forwarded_for: 在代理2 上存的是 客户机的ip,代理1的ip 用逗号隔开

$proxy_add_x_forwarded_for: nginx 上存的是 客户机的ip,代理1的ip,代理2的ip

$args;

#变量中存放了URL中的参数,例如:http://www.kgc.org/main/index.do?id=20190221&partner=search

#返回结果为: id=20190221&partner=search 存放的就是这个

select * from table where id=20190221

$document_root;

#保存了针对当前资源的请求的系统根目录,例如:/apps/nginx/html

$document_uri;

#保存了当前请求中不包含参数的URI,注意是不包含请求的指令,

比如:http://www.kgc.org/main/index.do?id=20190221&partner=search会被定义为/main/index.do

#返回结果为:/main/index.do

$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请求生成的文件绝对路径,

如:/apps/nginx/html/main/index.html

系统的真实路径

$request_uri; https:// www.baidu.com/main/index.do?id=20190221&partner=search

#包含请求参数的原始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; 443 https

#请求的服务器的端口号

$http_

#name为任意请求报文首部字段,表示记录请求报文的首部字段

arbitrary request header field; the last part of a variable name is the field

name converted to lower case with dashes replaced by underscores

#用下划线代替横线

#示例: echo $http_User_Agent;  

$http_user_agent;

#客户端浏览器的详细信息

$http_cookie;

#客户端的cookie信息

$cookie_

#name为任意请求报文首部字部cookie的key名

$http_

#name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,

如果有 横线需要替换为下划线

arbitrary request header field; the last part of a variable name is the field

name converted to lower case with dashes replaced by underscores #用下划线代替横线

#示例:

echo $http_user_agent;

echo $http_host;

$sent_http_

#name为响应报文的首部字段,name的对应的首部字段名需要为小写,

如果有横线需要替换为下划线,此变量有问题

echo $sent_http_server;

$arg_

#此变量存放了URL中的指定参数,name为请求url中指定的参数

#对比 变量 $arg 是全部, 如果 要id 如下

echo $arg_id;

实际操作:

location /main {

index index.html;

default_type text/html;

echo "hello world,main-->";

echo $remote_addr;

#存放了客户端的地址,注意是客户端的公网IP

echo $args;

#URL中的参数

echo $arg_user;

#URL中的user参数

echo $document_root;

#保存了针对当前资源的请求的系统根目录

echo $document_uri;

#当前请求中不包含参数的URI

echo $host;

#存放了请求的host名称 也就是服务器的地址

echo $http_user_agent;

##客户端浏览器的详细信息

echo $http_cookie;

#客户端的cookie信息

echo $request_filename;

#当前请求的资源文件的磁盘路径

echo $scheme;

#请求的协议,例如:http,https,ftp等

echo $scheme://$host$document_uri?$args;

}

加入此段后 去主机2上进行测试

[root@wg ~]#curl 192.168.80.7/main

hello world,main-->

192.168.80.11

/apps/nginx/html

/main

192.168.80.7

curl/7.29.0

/apps/nginx/html/main

http

http://192.168.80.7/main?

[root@wg ~]#vim /etc/hosts

192.168.80.7 www.pc.com

curl -b uid=100 'http://www.pc.com/main?user=zhou&title=cto'

#-b 加上cookie

[root@wg ~]#curl -b uid=100 'http://www.pc.com/main?user=zhou&title=cto'

hello world,main-->

192.168.80.11

user=zhou&title=cto

zhou

/apps/nginx/html

/main

www.pc.com

curl/7.29.0

uid=100

/apps/nginx/html/main

http

http://www.pc.com/main?user=zhou&title=cto

5.3.2 自定义变量

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

语法格式:

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

范例:

location /main {

set $name jnjn;

echo $name;

set $my_port $server_port;

#把内置变量的值赋予给自定义变量$my_port

echo $my_port;

echo "$server_name:$server_port";

}

#输出信息如下

[root@location ~]#curl www.pc.com/main

jnjn

80

www.pc.com:80

把$server_port(内置变量) 的值定义给 $my_port(自定义变量)

5.4 自定义访问日志

5.4.1日志的格式 可以自由指定

主配置文件中的默认日志格式配置:

#log_format main '$remote_addr - $remote_user [$time_local] "$request" '

# '$status $body_bytes_sent "$http_referer" '

# '"$http_user_agent" "$http_x_forwarded_for"';

#access_log logs/access.log main;

自定义:

[root@localhost ~]#vim /apps/nginx/conf/nginx.conf

log_format test '$remote_addr - $remote_user [$time_local] "$request" '

'$status $body_bytes_sent "$http_referer" '

'"$http_user_agent" "$http_x_forwarded_for"'

'$server_name:$server_port';

access_log logs/access.log test;

#access_log 后面的test表示调用 log_format test 定义的格式

#格式可以定义多个

[root@localhost ~]#nginx -s reload

使用另一台主机 curl 本机

[root@localhost ~]#tailf /apps/nginx/logs/access.log

192.168.80.11 - - [26/Feb/2024:15:08:27 +0800] "GET / HTTP/1.1" 200 15 "-" "curl/7.29.0" "-"www.pc.com:80

#可以看到多出来了www.pc.com:80

### 注意如果开启 include  注意定义子配置文件与 日志格式的上下关系  ,   日志格式一定要在  include 之前 否则会不生效。

如果你在子配置文件中 自定义了日志存放位置 且 主配置文件中 的日志格式配置在 include       /apps/nginx/conf.d/*.conf;之后,那么子配置文件中自定义日志存放位置的日志格式会还是默认格式。

5.4.2自定义json 格式日志

方便ELK收集日志

vim /apps/nginx/conf/nginx.conf

log_format access_json '{"@timestamp":"$time_iso8601",'

       '"host":"$server_addr",'

       '"clientip":"$remote_addr",'

       '"size":$body_bytes_sent,'

       '"responsetime":$request_time,'

       '"upstreamtime":"$upstream_response_time",'

       '"upstreamhost":"$upstream_addr",'  

       '"http_host":"$host",'

       '"uri":"$uri",'

       '"xff":"$http_x_forwarded_for",'

       '"referer":"$http_referer",'

       '"tcp_xff":"$proxy_protocol_addr",'

       '"http_user_agent":"$http_user_agent",'

       '"status":"$status"}';

access_log logs/access.log access_json;

[root@localhost ~]#nginx -s reload

主机2 去访问 curl 192.168.80.7

[root@localhost ~]#tailf /apps/nginx/logs/access.log

{"@timestamp":"2024-02-26T15:25:11+08:00",    '"host":"192.168.80.7",'    '"clientip":"192.168.80.11",'    '"size":15,'    '"responsetime":0.000,'    '"upstreamtime":"-",'    '"upstreamhost":"-",'     '"http_host":"192.168.80.7",'    '"uri":"/index.html",'    '"xff":"-",'    '"referer":"-",'    '"tcp_xff":"-",'    '"http_user_agent":"curl/7.29.0",'    '"status":"200"}'

如何使用命令提取出status状态码?

tail -n1 /apps/nginx/logs/access.log | sed -r 's/.*(status)":"(.*)"}.*/\2/'

如何统计状态码个数?

cat  /apps/nginx/logs/access.log  | sed -r 's/.*(status)":"(.*)"}.*/\2/' | sort -n | uniq -c

#统计状态码个数       6 200      26 304      28 404

如何提取服务器的IP地址:

tail -n1 /apps/nginx/logs/access.log |awk -F[:\"] '{print $13}' 192.168.80.7

 或

tail -n1 /apps/nginx/logs/access.log |awk -F: '{print $6}'|sed -r 's/"(.*)",.*/\1/'

5.5 nginx压缩功能

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

        不支持压缩图片(要想支持安装第三方模块)

        官方文档: https://nginx.org/en/docs/http/ngx_http_gzip_module.html

        配置指令如下:

        注意:curl 文字版浏览器不支持显示压缩文件

#启用或禁用gzip压缩,默认关闭

gzip on | off;

#压缩比由低到高从1到9,默认为1

gzip_comp_level level;

#禁用IE6 gzip功能

gzip_disable "MSIE [1-6]\.";

#gzip压缩的最小文件,小于设置值的文件将不会压缩

gzip_min_length 1k;

#启用压缩功能时,协议的最小版本,默认HTTP/1.1(不要低于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;

#预压缩,先压缩好,不用临时压缩,消耗cpu。比如用户想要1.txt

开启这个后就能识别1.txt.gz,把1.txt的压缩包发给用户。

#需要手动压缩

#访问页面都是下载(GET)

gzip_static on | off;

#重启nginx并进行访问测试压缩功能

[root@centos8 ~]# cp /apps/nginx/logs/access.log /data/nginx/html/pc/m.txt

[root@centos8 ~]# echo "test" > /data/nginx/html/pc/test.html #小于1k的文件测试是否会压缩

[root@centos8 ~]# vim /apps/nginx/conf/nginx.conf

gzip on;

gzip_comp_level 5;

gzip_min_length 1k;

gzip_types text/plain application/javascript application/x-javascript text/css

application/xml text/javascript application/x-httpd-php image/gif image/png;  

gzip_vary on;

#重启Nginx并访问测试:

[root@centos8 ~]# curl --head --compressed 192.168.80.7/test.html

HTTP/1.1 200 OK

Server: nginx

Date: Fri, 22 Feb 2019 01:52:23 GMT

Content-Type: text/html

Last-Modified: Thu, 21 Feb 2019 10:31:18 GMT

Connection: keep-alive

Keep-Alive: timeout=65

Vary: Accept-Encoding

ETag: W/"5c6e7df6-171109"

Content-Encoding: gzip #压缩传输

#验证不压缩访问的文件大小:

​​​​​​​实际操作:

太小的文件没必要压缩,压缩说不定变大了

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

charset utf-8;

gzip on;

gzip_comp_level 9;

#压缩等级

gzip_min_length 10k;

#小于10k不压缩

gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php;

#指明仅对哪些类型的资源执行压缩操作

gzip_vary on;

#在响应报文首部插入“Vary: Accept-Encoding”

location / {

root /opt/html;

}

}

[root@localhost zip]#ll -h /apps/nginx/logs/access.log

-rw-r--r--. 1 root root 11M 2月 26 16:19 /apps/nginx/logs/access.log

[root@localhost zip]#cp /apps/nginx/logs/access.log /opt/html/a.html

[root@localhost zip]#nginx -s reload

注意  状态码304是缓存 要 强刷

##########################  开启预压缩  ##########################

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

server_name www.pc.com;

charset utf-8;

gzip on;

gzip_comp_level 9;

#压缩等级

gzip_min_length 10k;

#小于10k不压缩

gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php;

#指明仅对哪些类型的资源执行压缩操作

gzip_vary on;

#在响应报文首部插入“Vary: Accept-Encoding”

gzip_static on;

#开启预压缩。

location / {

root /opt/html;

}

}

[root@localhost zip]#cd /opt/html/

[root@localhost html]#ls

a.html m pc

[root@localhost html]#tar zcf a.html.gz a.html

[root@localhost html]#ls

a.html a.html.gz m pc

[root@localhost html]#mv a.html /xiaz/

[root@localhost html]#ls

a.html.gz m pc

[root@localhost html]#nginx -s reload

访问 192.168.80.7/文件名

5.6 https 功能

        Web网站的登录页面都是使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议,HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。

        nginx 的https 功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数--with-http_ssl_module开启

        官方文档:Module ngx_http_ssl_module

ssl on | off;  

#为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代

listen 443 ssl;

ssl_certificate /path/to/file;

#指向包含当前虚拟主机和CA的两个证书信息的文件,一般是crt文件

ssl_certificate_key /path/to/file;

#当前虚拟主机使用的私钥文件,一般是key文件

ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];

#支持ssl协议版本,早期为ssl现在是TLS,默认为后三个

ssl_session_cache off | none | [builtin[:size]] [shared:name:size];

#配置ssl缓存

off: #关闭缓存

none:  #通知客户端支持ssl session cache,但实际不支持

builtin[:size]:#使用OpenSSL内建缓存,为每worker进程私有

[shared:name:size]:#在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称

ssl_session_timeout time;

#客户端连接可以复用ssl session cache中缓存的有效时长,默认5m

自签名证书

#所有的证书需要放在一起不能移开

[root@localhost opt]#bash certificate.sh

#运行自签名证书脚本

[root@localhost opt]#cat pc.com.crt ca.crt > www.pc.com.crt

# ca.crt (颁发者) pc.com.crt(购买者)

[root@localhost opt]#mv pc.com.key www.pc.com.key

#(验证钥匙)

[root@localhost opt]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

listen 443 ssl;

server_name www.pc.com;

ssl_certificate /opt/www.pc.com.crt;

ssl_certificate_key /opt/www.pc.com.key;

ssl_session_cache shared:sslcache:20m;

ssl_session_timeout 10m;

location / {

root /opt/html;

if ( $scheme = http) {

rewrite ^/(.*)$ https://192.168.80.7/$1 redirect;

#只要你的请求协议是http 就重写成https

}

}

}

5.7 自定义图标

        favicon.ico 文件是浏览器收藏网址时显示的图标,当客户端使用浏览器问页面时,浏览器会自己主动发起请求获取页面的favicon.ico文件,但是当浏览器请求的favicon.ico文件不存在时,服务器会记录404日志,而且浏览器也会显示404报错

#方法一:服务器不记录访问日志:

location = /favicon.ico {

  log_not_found off;

  access_log off;

}

#方法二:将图标保存到指定目录访问:

#location ~ ^/favicon\.ico$ {

location = /favicon.ico {

    root   /data/nginx/html/pc/images;

    expires 365d;  #设置文件过期时间(指定缓存时间 365天)

}

【定制小图标】

wget www.baidu.com/favicon.ico

放到主目录就可以了

不生效可以重新打开浏览器

6  重写功能  rewrite

        重新帮用户重写地址      192.168.80.7  rewrite   www.baidu.com

        Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之

        一,用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为自动访问,另外还可以在一定程度上提高网站的安全性。

6.1 ngx_http_rewrite_module模块指令

官方文档: https://nginx.org/en/docs/http/ngx_http_rewrite_module.html

6.1.1 if指令

官方文档: https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if

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

if (条件匹配) {  action }

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

= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false

!=  #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false

~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假

!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假

~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假

!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真

-f 和 !-f #判断请求的文件是否存在和是否不存在

-d 和 !-d #判断请求的目录是否存在和是否不存在

-x 和 !-x #判断文件是否可执行和是否不可执行

-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)

#注意:

#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。

#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false

#示例:

http://www.baidu.com

3字打头重定向

301 永久重定向 读取过一次 就会将缓存记录在浏览器中 即使 nginx 服务器宕机 在缓存期间内 还是可以跳转

302 临时重定向 没有缓存 每次都要重定向(每次都要过问服务器)

304 无需再次传输请求的内容,也就是说可以使用缓存的内容。

案例:

location /main {

    index index.html;

    default_type text/html;

    if ( $scheme = http ){

      echo "if-----> $scheme";

    }

    if ( $scheme = https ){

     echo "if ----> $scheme";

  }

   

    #if (-f $request_filename) {

    #   echo "$request_filename is exist";

    #}

    if (!-e $request_filename) {

#如果访问页面不存在输出以下内容。

       echo "$request_filename is not exist";

       #return ;

  }

}

#$request_filename 当前请求的资源文件的磁盘路径

【 用户访问的文件不存在 直接返回主页 】

server {

listen 80;

server_name www.pc.com;

default_type text/html;

root /opt/html/;

location /test {

return 301 http://www.baidu.com;

}

location /main {

if ( $scheme = http ){

return 666 "if ----> $scheme"; #注意这里的if语句执行后会 停止匹配

}

if (!-e $request_filename){

return 302 /index.html; #如果文件或目录不存在直接跳转到主页面

}

}

}

192.168.80.7/main/xxxxx

#注意访问的main下的不存在 目录

【想控制所有网站可以 放到前面】

server {

listen 80;

server_name www.pc.com;

default_type text/html;

root /opt/html/;

if (!-e $request_filename){

return 302 /index.html; #如果文件或目录不存在直接跳转到主页面

}

location / {

root /opt/html/;

}

location /test {

default_type text/plain;

return 301 http://www.baidu.com;

}

location /main {

index index.html;

default_type text/html;

if ( $scheme = http ){

return 666 "if-----> $scheme";

}

}

}

6.1.2 return

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

        语法格式:

​​​​​​​

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

范例:

location / {

  root /opt/html;

  default_type text/html;

  index index.html;

     if ( $scheme = http ){

       #return 666;

       #return 666 "not allow http";

       #return 301 http://www.baidu.com;

      return 500 "service error";

       echo "if-----> $scheme"; #return后面的将不再执行

    }

    if ( $scheme = https ){

     echo "if ----> $scheme";

  }

}

例一:

server {

listen 80;

server_name www.pc.com;

root /opt/html/;

location / {

root /opt/html/;

}

location /test { #访问test 直接返回403

return 403; #可以改成666

}

}

例二:

location /test { #访问test 直接返回666

return 666 "hello"; #可以改成666自定义,hello是描述 文字可以 图形浏览器不可以

}

location /test {

default_type text/plain; #定义文本格式后图形浏览器可以看见

return 666 "hello";

}

例三:

location /test {

default_type text/plain;

return 302 http://www.baidu.com;

}

location /test {

default_type text/plain;

return 301 /index.html;

}

301 缓存在磁盘上,服务器断开后的一段时间依旧可以继续访问

302 没有缓存 , 服务器断开无法重定向 jd 是302

永久重定向

6.1.3 set 指令

        指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key,另外set定义格式为set $key value,value可以是text, variables和两者的组合。

location /main {

  root /data/nginx/html/pc;

  index index.html;

  default_type text/html;

   set $name nnjj; #定义变量name为 nnjj

   echo $name;

   set $my_port $server_port #(nginx 自带的变量 服务端口 一般80);

   echo $my_port;

}

6.1.4 break 指令

        用于中断当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行,Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在server块和locationif块中使用

        注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行

        使用语法如下:

​​​​​​​

if ($slow) {

  limit_rate 10k;

  break;

}

location /main {

  root /data/nginx/html/pc;

  index index.html;

  default_type text/html;

   set $name kgc;

   echo $name;

  break;  #location块中break后面指令还会执行

   set $my_port $server_port;

   echo $my_port;

}

6.2 rewrite 指令

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

        官方文档:https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite

%   s/旧的/新的/

        rewrite只能放在server{},location{},if{}中,并且默认只能对域名后边的除去传递的参数外的字符串起作用,         例如 http://www.kgc.com/abc/bbs/index.php?a=1&b=2 只对/abc/bbs/index.php重写。

​​​​​​​rewrite 执行顺序如下: (1) 执行 server 块里面的 rewrite 指令。 (2) 执行 location 匹配。 (3) 执行选定的 location 中的 rewrite 指令。

语法格式 :

rewrite可以配置在 server、location、if

语法格式 :

rewrite regex replacement(www.baidu.com) [flag];

正则匹配原始访问url 替代你想让客户访问的 标志 ()premanent301 redirect302 break last

last :本条规则匹配完成后,不终止重写后的url匹配,一般用在 server 和 if 中。多次匹配break :本条规则匹配完成即终止,终止重写后的url匹配,一般使用在 location 中。单次匹配redirect :返回302临时重定向,浏览器地址会显示跳转后的URL地址。permanent :返回301永久重定向,浏览器地址栏会显示跳转后的URL地址。

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

注意:如果在同一级配置块中存在多个rewrite规则,那么会自上而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码(超时),[flag]所表示的标志位用于控制此循环机制如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向 301

正则表达式格式

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

rewrite flag 使用介绍

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

跳转型指由客户端浏览器重新对新地址进行请求代理型是在WEB服务器内部实现跳转

rewrite 格式

Syntax: rewrite regex replacement [flag];

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

flag 说明

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

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

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

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

例子:

#访问 bj 跳转到 beijing

location /bj {

root /data/nginx/pc;

rewrite ^/bj/(.*) /beijing/$1 permanent;

}

此处的$1代表后项引用

域名不在范围内(www)

server {

listen 80;

default_type text/plain;

server_name www.pc.com;

location / {

  root /opt/html;

  rewrite / http://www.m.com permanent;

   #rewrite / http://www.m.com redirect;

}

#重启Nginx并访问域名 http://www.pc.com (虚拟主机) 进行测试

curl -L 跳到最后 curl www.pc.com -L

【rewrite】 rewrite regex replacement [flag]; 指令     正则   替换         标志

【访问bj 等于 访问beijing】

location /bj {

rewrite ^/bj/(.*) /beijing/$1 permanent;

}

mkdir /beijing

echo beijing > /beijing/index.html

整个网页跳转 老域名跳转到新域名

location / {

root /data/nginx/pc/;

rewrite / http://www.accp.com permanent;

}

server {

listen 80;

server_name www.accp.com;

root /opt/html/accp/;

}

cd /opt/html/

mkdir accp

echo accp > /opt/html/accp/index.html

【break】

server {

listen 80;

server_name www.pc.com;

location /bj {

rewrite ^/bj/(.*) /beijing/$1 break;

}

}

[root@localhost ~]#mkdir /opt/html/bj/

[root@localhost ~]#mkdir /opt/html/beijing/

[root@localhost ~]#echo bj > /opt/html/bj/index.html

[root@localhost ~]#echo beijing > /opt/html/beijing/index.html

301 302 请求后 告诉你重定向的域名, 让你重新发起请求

break 服务器缓存好网页直接让你访问,直接给你结果

案例:

server {

listen 80;

server_name www.pc.com;

location /break/ {

rewrite ^/break/(.*) /test/$1 break;

return 402;

}

location /last/ {

rewrite ^/last/(.*) /test/$1 last;

return 403;

}

location /test/ {

return 666;

}

}

请求:curl 192.168.80.7/break/

返回:404

#注:break与last都停止处理后续rewrite指令集,不同之处在与last会重新发起新的请求,而break不会。

当请求break时,如匹配内容存在的话,可以直接请求成功,返回200;而如果请求内容不存在,则返回404。

请求:curl 192.168.80.7/last/

返回:666

当请求为last的时候,会对重写的新uri重新发起请求,如上例则返回666。

实战案例  http 转https

server {

listen 443 ssl;

listen 80;

ssl_certificate /opt/www.pc.com.crt;

ssl_certificate_key /opt/www.pc.com.key;

ssl_session_cache shared:sslcache:20m;

ssl_session_timeout 10m;

server_name www.pc.com;

location / {    #针对全站跳转

  root /opt/html/pc;

   if ( $scheme = http ){  #如果没有加条件判断,会导致死循环

  rewrite / https://$host redirect;

  }   http://www.kgc.com https://www.kgc.com

}

location /login {     #针对特定的URL进行跳转https

if ( $scheme = http ){  #如果没有加条件判断,会导致死循环

  rewrite / https://$host/login redirect;

  }

 }

}

其他例子:

案例1 :更换目录访问方式,目录转换为对象存储形式

要求:

/20200106/static ->/static?id=20200106

/20200123/image ->/image?id=20200123

rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;

案例2:多目录转换访问方式

要求:

www.lucky.com/images/20200106/1.jpg => www.lucky.com/index.do?name=images&dir=20200106=&file=1.jpg

规则配置:

if ($host ~* (.*)\.magedu\.com) {

rewrite ^/(.*)/(\d+)/(.*)$ /index.do?name=$1&dir=$2&file=$3 last;

}

6.3 防盗链

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

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

referer 是什么?

你直接访问 www.jd.com  referer就是空

你访问www.baidu.com   搜索 jd  点击了页面跳转到了www.jd.com  referer 为 www.baidu.com

为什么要加防盗链?

别人在他的页面上展示一些并不在自己服务器上的一些内容, 获取别人的资源地址,绕过别人的资源展示页面,直接在自己的页面上向最终用户提供此内容。不仅点击量不算我的而且 也会对我服务器造成负担。

比如我直接在自己的网站上 服务器 网络 运维 Nginx  第1张 这样就可以直接展示百度的图片,但是实际上是无法展示的 (如下图),之所以无法展示是因为百度的图片做过防盗链处理 防盗链的工作原理 通过Refer或者签名,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以追踪到显示他的网页地址 一旦检测到来源不是本站,即进行阻止或者返回指定的页面

一般被盗链的都是图片、 音乐、视频、软件等资源。 通过盗链的手段可以减轻自己服务器的负担

我们先实现没有防盗链的效果:

第一台机器:

[root@localhost html]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

default_type text/plain;

server_name www.pc.com;

root /opt/html/;

}

[root@localhost html]#ls /opt/html/

a.jpg index.html

#a.jpg 为任意图片

第二台机器:盗取第一台机器的图片

systemctl stop firewalld

setenforce 0

yum install epel-release.noarch -y

yum install nginx -y

cd /usr/share/nginx/html

vim index.html

this is yunjisuan

服务器 网络 运维 Nginx  第2张

vim /etc/nginx/nginx.conf

41 server_name www.accp.com;

修改41行如上

systemctl start nginx

真机上 添加dns 解析

C:\Windows\System32\drivers\etc

打开 hosts 文件 添加:

192.168.80.7 www.pc.com

192.168.80.12 www.lucky.com

真机上测试

www.lucky.com 是否可以打开图片

​​​​​​​ ​​​​​​​

实现盗链:

第一台服务器:

server {

listen 80;

default_type text/plain;

server_name www.pc.com;

root /opt/html/;

location ~* \.(jpg|gif|swf|jpeg|bmp)$ {

root /opt/html;

valid_referers none blocked *.pc.com pc.com;

if ( $invalid_referer ) {

return 403;

}

}

}

cd /opt/html/

可以尝试拖入 error.png 123.jpeg 图片

第二台机器尝试再次盗取看看是否可以打开图片。

各段含义解释:

~* \.(jpg|gif|swf)$:这段正则表达式表示匹配不区分大小写,以.jpg 或.gif 或.swf 结尾的文件

Valid_referers:设置信任的网站,可以正常使用图片。

None :浏览器中 referer 为空的情况,就是直接在浏览器访问图片。

Blocked :referer 不为空的情况 ,但是值被代理或防火墙删除了,这些值不以 http://或https://开头。

后面的网址或者域名:referer 中包含相关字符串的网址。

If 语句:如果链接的来源域名不在 valid_referers 所列出的列表中,$invalid_referer 为1,

则执行后面的操作,即进行重写或返回 403 页面。

7 反向代理

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

7.1 实现 http 反向代理

官方文档: https://nginx.org/en/docs/http/ngx_http_proxy_module.html

7.1.1 http 协议反向代理

7.1.1.1 反向代理配置参数

官方文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

proxy_pass;

#用来设置将客户端请求转发给的后端服务器的主机,可以是主机名(将转发至后端服务做为主机头首部)、IP

地址:端口的方式

#也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持

#示例:

10.0.0.8/web

location /web {

  index index.html;

  proxy_pass http://10.0.0.18:8080; #8080后面无uri,即无 / 符号,

需要将location后面url 附加到proxy_pass指定的url后面,此行为类似于root

#proxy_pass指定的uri不带斜线将访问的/web,等于访问后端服务器

http://10.0.0.18:8080/web/index.html,即后端服务器配置的站点根目录要有web目录才可以被访问

   # http://nginx/web/index.html ==> http://10.0.0.18:8080/web/index.html

   

proxy_pass http://10.0.0.18:8080/;   #8080后面有uri,即有 / 符号,相当于置换,

即访问/web时实际返回proxy_pass后面uri内容.此行为类似于alias

   #proxy_pass指定的uri带斜线,等于访问后端服务器的http://10.0.0.18:8080/index.html 内容返回给客户端

}  # http://nginx/web/index.html ==> http://10.0.0.18:8080

#重启Nginx测试访问效果:

#curl -L http://www.kgc.org/web

#如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),

则proxy_pass之后必须不能使用uri; 即不能有/ ,用户请求时传递的uri将直接附加至后端服务器之后

server {

...

server_name HOSTNAME;

location ~|~* /uri/ {

proxy_pass http://host:port; #proxy_pass后面的url 不能加/

}

...

}

http://HOSTNAME/uri/ --> http://host/uri/

proxy_hide_header field;

#用于nginx作为反向代理的时候,在返回给客户端http响应时,隐藏后端服务器相应头部的信息,可以设置

在http,server或location块

#示例: 隐藏后端服务器ETag首部字段

location /web {

  index index.html;

  proxy_pass http://10.0.0.18:8080/;

  proxy_hide_header ETag;

}

proxy_pass_header field;

#默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数,如果

要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端

#field 首部字段大小不敏感

#示例:透传后端服务器的Server和Date首部给客户端,同时不再响应报中显示前端服务器的Server字段

proxy_pass_header Server;

proxy_pass_header Date;

proxy_pass_request_body on | off;

#是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启

proxy_pass_request_headers on | off;

#是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启

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

实现单台反向代理

1-1 代理服务器

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

default_type text/plain;

server_name www.pc.com;

root /opt/html/;

location / {

proxy_pass http://192.168.80.11;

}

}

[root@localhost ~]#nginx -s reload

1-2 真实服务器

yum install httpd -y

echo "real server 80.11" > /var/www/html/index.html

systemctl stop nginx

systemctl start httpd

1-3 客户机

[root@localhost ~]#curl 192.168.80.7

real server 80.11

如何修改端口号?

我要监听8080端口的访问,真实服务器和代理服务器都要监听8080端口。

真实服务器:

[root@wg html]#vim /etc/httpd/conf/httpd.conf

Listen 80

Listen 8080

[root@wg html]#systemctl reload httpd

代理服务器:

server {

listen 80;

listen 8080;

default_type text/plain;

server_name www.pc.com;

root /opt/html/;

location / {

proxy_pass http://192.168.80.11:8080;

}

}

[root@localhost ~]#nginx -s reload

客户端:

[root@localhost ~]#curl 192.168.80.7:8080

real server 80.11

如果代理服务器没有监听8080端口:

[root@localhost ~]#curl 192.168.80.7:8080

curl: (7) Failed connect to 192.168.80.7:8080; 拒绝连接

如果真实服务器没有监听8080端口:

[root@localhost ~]#curl 192.168.80.7:8080

502 Bad Gateway

502 Bad Gateway


nginx/1.18.0

关于504 与 502 状态码

在真实服务器上 做防火墙规则

iptables -A INPUT -s 192.168.91.100 -j DROP

客户端再次访问 会出现504网关超时(有可能只是处理时间久,服务器不一定挂了),时间较长1分钟,没有定义代理超时时间

iptables -A INPUT -s 192.168.91.100 -j REJECT

客户端再次访问 会出现502,一般出现502 代表后端真实服务器挂了

针对某个uri  进行访问

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

1-1 代理服务器

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

default_type text/plain;

server_name www.pc.com;

root /opt/html/;

location ~* /api {

proxy_pass http://192.168.80.11;

#http://192.168.80.11 最后的 / 可加或不加

#在不是 ~*的情况下 最后不加/ 是追加 将location上的url 追加到 192.168.80.11 后面

#在不是 ~*的情况下 最后加/ 是替换 将location上的url 替换成 192.168.80.11

#在是 ~*的情况下 如果加/ 语法出错

}

}

[root@localhost ~]#nginx -s reload

1-2 真实服务器

[root@wg ~]#cd /var/www/html/

[root@wg html]#mkdir api/

[root@wg html]#echo "html/api/index" > api/index.html

1-3 客户端

[root@localhost ~]#curl 192.168.80.7/api/

html/api/index

如果在代理服务器http://192.168.80.11 最后加上/会如何?

[root@localhost ~]#nginx -s reload

nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /apps/nginx/conf.d/pc.conf:7

#这么写会报错

如果后端服务器无法连接((比如:iptables -AINPUT -s nginx_ip -j REJECT或者systemctl stop httpd)), 会出现下面提示

一般出现502 代表后端真实服务器挂了

默认在1分钟内后端服务器无法响应(比如:iptables -AINPUT -s nginx_ip -j DROP),会显示下面的504超时提示

7.1.1.3 实战案例:指定location 实现反向代理 动静分离

只是模拟动静分离,需要借助其它软件。

需要服务器进行二次处理的是动态,不是则是静态

1-1 代理服务器

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

default_type text/plain;

server_name www.pc.com;

root /opt/html/;

location ~* /api {

#proxy_pass http://192.168.80.11/; #注意有后面的/, 表示替换

proxy_pass http://192.168.80.11; #后面没有 / , 表示追加

}

#模拟是动态资源

location ~* \.(jpg|jpeg|png|gif|bmp)$ {

proxy_pass http://192.168.80.12; #如果加/ 语法出错

}

#静态资源

}

[root@localhost ~]#nginx -s reload

1-2 真实服务器(动态资源)httpd

systemctl stop firewalld

setenforce 0

[root@wg api]#pwd

/var/www/html/api

[root@wg api]#ls

index.html

1-3 真实服务器(静态资源)

systemctl stop firewalld

setenforce 0

[root@localhost html]#pwd

/var/www/html

[root@localhost html]#ls

a.jpg b.png c.jpeg r.jpg

7.1.1.4反向代理示例:缓存功能

关闭后端服务器后,图片无法访问

缓存功能默认关闭,需要开启

​​​​​​​

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{...}中

示例:

proxy_cache_valid 200 302 10m;

proxy_cache_valid 404 1m;

proxy_cache_path;

#定义可用于proxy功能的缓存;Context:http 必须放在http语句中

proxy_cache_path path [levels=levels] [use_temp_path=on|off]

keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number]

[manager_sleep=time] [manager_threshold=time] [loader_files=number]

[loader_sleep=time] [loader_threshold=time] [purger=on|off]

[purger_files=number] [purger_sleep=time] [purger_threshold=time];

#示例:在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方法总是被缓存

扩展知识:如何清理缓存

方法1: rm -rf 缓存目录 方法2: 第三方扩展模块ngx_cache_purge

例子:

proxy_cache_path /data/nginx/proyxcache levels=1:2:2 keys_zone=proxycache:20m inactive=120s max_size=1g;

#定义可用于proxy功能的缓存;Context: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; #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值

1:1:1 16个二进制 2^16/2^16/2^16

基本配置:

server {

listen 80;

proxy_cache proxycache;

#定义缓存的名称为proxycache

proxy_cache_key $request_uri;

#对指定的数据进行MD5的运算做为缓存的key

#proxy_cache_key $host$uri$is_args$args;

proxy_cache_valid 200 302 301 10m;

#指定的状态码返回的数据缓存多长时间

proxy_cache_valid any 5m;

#除指定的状态码返回的数据以外的缓存多长时间,必须设置,否则不会缓存

server_name www.pc.com;

root /data/nginx/pc;

location / {

root /data/nginx/pc;

}

}

实现缓存实际操作

去代理服务器1-1上 添加操作

先在主配置文件 的 http模块 中加入下方配置

http {

include mime.types;

default_type application/octet-stream;

proxy_cache_path /data/nginx/proyxcache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;

#注意一定要在定义在子配置文件include的前面

include /apps/nginx/conf.d/*.conf;

[root@localhost ~]#mkdir -p /data/nginx/ #proyxcache会自动创建

[root@localhost ~]#nginx -s reload

然后去 子配置文件中添加

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

default_type text/plain;

server_name www.pc.com;

root /opt/html/;

proxy_cache proxycache;

proxy_cache_key $request_uri;

proxy_cache_valid 200 302 301 10m;

proxy_cache_valid any 5m;

location ~* \.(jpg|jpeg|png|gif|bmp)$ {

proxy_pass http://192.168.80.12;

}

}

[root@localhost ~]#nginx -s reload

[root@localhost nginx]#tree /data/nginx/proyxcache/ /data/nginx/proyxcache/ └── 5     └── f         └── 1             └── 866bac79050fa10045b53aa7f80731f5

3 directories, 1 file

7.1.1.5 实现反向代理客户端 IP 透传

一级代理

多级代理  ip地址透传

官方文档:Module ngx_http_proxy_module

实际操作:

代理服务器80.7 配置(编译安装的nginx)

[root@localhost ~]# vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

default_type text/plain;

server_name www.pc.com;

root /opt/html/;

location / {

proxy_pass http://192.168.80.12;

#proxy_set_header X-Real-IP $remote_addr;

#只添加客户端IP到请求报文头部,转发至后端服务器

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

#添加客户端IP和反向代理服务器IP到请求报文头部

}

}

代理服务器80.12 配置(yum安装的nginx)

[root@localhost nginx]#systemctl stop httpd

[root@localhost nginx]#vim /etc/nginx/nginx.conf

http {

server {

listen 80;

server_name www.lucky.com;

root /usr/share/nginx/html;

location / {

proxy_pass http://192.168.80.11;

#这里就不用加proxy_set_header了。

}

}

[root@localhost nginx]#systemctl restart nginx

真实服务器Apache配置:(yum安装)

[root@wg ~]#vim /etc/httpd/conf/httpd.conf

——————到第 196 行修改————————

LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

#重启apache访问web界面并验证apache日志

[root@wg ~]#echo "real server 80.11" > /var/www/html/index.html

[root@wg ~]#systemctl restart httpd

使用客户机验证:

[root@localhost install]#curl 192.168.80.7

real server 80.11

[root@wg ~]#tail -n3 /var/log/httpd/access_log

192.168.80.13 192.168.80.12 - - [28/Feb/2024:14:06:55 +0800] "GET / HTTP/1.0" 200 19 "-" "curl/7.29.0"

#客户机的源IP地址为192.168.80.13 ,代理服务器地址192.168.80.12

#如果想要查看所有代理服务器及客户机的IP可以在所有代理服务器上做 80.7 的配置

真实服务器nginx配置:(yum安装)

[root@wg ~]# cat /apps/nginx/conf/nginx.conf

"$http_x_forwarded_for"' #默认日志格式就有此配置

#重启nginx访问web界面并验证日志格式:

192.168.80.12 - - [28/Feb/2024:14:26:11 +0800] "GET / HTTP/1.0" 200 4833 "-" "curl/7.29.0" "192.168.80.13"

7.1.1.6 http反向代理负载均衡

        在上一个节中Nginx可以将客户端的请求转发至单台后端服务器但是无法转发至特定的一组的服务器,而且不能对后端服务器提供相应的服务器状态监测,Nginx 可以基于ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能

官方文档: https://nginx.org/en/docs/http/ngx_http_up

#自定义一组服务器,配置在http块内 upstream   web {   server 192.168.80.11;    后面可以添加调度算法  server 192.168.80.12; }

location  / { proxy_pass  http://web/; }

#示例 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  #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器 sorry server   自己不能转自己

down    #标记为down状态

resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx

注意!hash算法 的值受权重影响 

hash KEY [consistent];

#基于指定请求报文中首部字段或者URI等key做hash计算,使consistent参数,将使用ketama一致性

调度算法

1.轮询 一人一个

轮询,在nginx配置文件中是这样定义的,如下所示:

upstream web {

server 192.168.80.11:80;

server 192.168.80.12:80;

}

假如现在有用户请求我们的WEB服务器,大家想一想,这个请求该给谁呢?

因为我们用的是轮询算法,所以现在当请求进入时,首先会把请求给 192.168.80.11:80,

当第二个请求进入时会把请求给 192.168.80.12:80,第三个请求给101,这就是轮询。

总的来说:每个请求会按顺序逐一分配到不同的后端服务器。顺序为:ABABABAB.....

2.加权轮询 应用于一台服务器强,另一台服务器弱

加权轮询,在nginx配置文件中是这样定义的,如下所示:

upstream web {

server 192.168.80.11:80 weight=1;

server 192.168.80.12:80 weight=2;

}

看到上面的配置,发现和轮询算法有些不一样,多了一个weight的配置,这个weight就是设置权重值的,

Nginx负载均衡器会根据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。

那么我们上面的配置,当用户访问进来负载均衡器是如何分发请求的呢?11=A、12=B,那么顺序为:ABBABBABBABBABB......

注意:值越大分配的请求越多。

3.ip hash

ip_hash ,在nginx配置文件中是这样定义的,如下所示:

upstream web {

#hash $remote_addr;

server 192.168.80.11:80;

server 192.168.80.12:80;

ip_hash;

}

什么是ip_hash呢?其实也是很好理解的,假如你现在有两台服务器11和12,

11和12服务器是我们的电商网站,如果当用户正在浏览购买商品时,加入到了购物车内,现在要去付款。

那么肯定要跳转到另一个界面,这时客户一定会再发起请求。那么这时候如果请求给到了12服务器,

那么可想而知,购物车空空如也。那么ip_hash就出现了,可以很好的帮我们解决这种局面。

每个请求按访问IP的hash分配,这样来自同一IP固定访问一个后台服务器。

总结:nginx负载均衡器会让相同的客户端ip请求相同的服务器

4.uri hash

hash $request_uri consistent; #基于用户请求的uri做hash

url_hash按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。

url_hash其实就是当用户发起访问请求时,如果请求的资源文件是a1.index

那么这个请求会落到80.11这台服务器上,同理,如果请求的资源文件是a2.index

那么这个请求会落到80.12这台服务器上。

5.cookie hash

hash $cookie_sessionid  #基于cookie中的sessionid这个key进行hash调度,实现会话绑定

6.最少连接数

least_hash ,在nginx配置文件中是这样定义的,如下所示:

upstream web {

least_conn;

server 192.168.80.11:80;

server 192.168.80.12:80;

}

假如有两台服务器,11服务器目前有30个用户请求,12服务器目前有26个用户请求,

那么新来的访问请求,负载均衡器会给12服务器。

least_hash就是最少链接数,哪个机器连接数少就发分发给哪个机器。

7.根据响应时间

fair,在nginx配置文件中是这样定义的,如下所示:

upstream web {

fair;

server 192.168.80.11:80;

server 192.168.80.12:80;

}

fair是比上面几种更加智能的负载均衡算法。

此种算法可以根据页面大小和加载时间长短智能地进行负载均衡,

也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。

Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。

实际操作:

轮询:

代理服务器配置:

192.168.80.7

[root@localhost ~]# vim /apps/nginx/conf/nginx.conf

http {

include mime.types;

default_type application/octet-stream;

upstream web {

server 192.168.80.11:80;

server 192.168.80.12:80;

}

include /apps/nginx/conf.d/*.conf;

[root@localhost ~]# vim /apps/nginx/conf.d/pc.conf

server {

listen 80;

default_type text/plain;

server_name www.pc.com;

root /opt/html/;

location / {

proxy_pass http://web;

}

}

[root@localhost ~]#nginx -s reload

两台真实主机配置:

192.168.80.11

[root@wg ~]#systemctl start httpd

[root@wg ~]#vim /var/www/html/index.html

11 11

192.168.80.12

[root@localhost ~]#systemctl start httpd

[root@localhost ~]#vim /var/www/html/index.html

12 12 12

验证:

[root@localhost install]#curl 192.168.80.7

11 11

[root@localhost install]#curl 192.168.80.7

12 12 12

[root@localhost install]#curl 192.168.80.7

11 11

[root@localhost install]#curl 192.168.80.7

12 12 12

加权轮询:

[root@localhost ~]# vim /apps/nginx/conf/nginx.conf

http {

include mime.types;

default_type application/octet-stream;

upstream web {

server 192.168.80.11:80 weight=1;

server 192.168.80.12:80 weight=2;

}

include /apps/nginx/conf.d/*.conf;

[root@localhost ~]#nginx -s reload

验证:

[root@localhost install]#curl 192.168.80.7

11 11

[root@localhost install]#curl 192.168.80.7

12 12 12

[root@localhost install]#curl 192.168.80.7

12 12 12

[root@localhost install]#curl 192.168.80.7

11 11

[root@localhost install]#curl 192.168.80.7

12 12 12

[root@localhost install]#curl 192.168.80.7

12 12 12

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: