提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • Nginx简介
    • 背景介绍
    • 常见服务器对比
  • Nginx的优点
  • Nginx的功能特性及常用功能
    • 基本HTTP服务
    • 高级HTTP服务
    • 邮件服务
  • Nginx常用的功能模块
  • Nginx的核心组成
  • Nginx环境准备
    • Nginx版本介绍
    • 获取Nginx源码
    • 准备服务器系统
  • Nginx安装方式介绍
    • 方案一:Nginx的源码简单安装
    • 方案二:yum安装
    • 源码简单安装和yum安装的差异:
    • 方案三:Nginx的源码复杂安装
  • Nginx目录结构分析
  • Nginx服务器启停命令
    • 方式一:Nginx服务的信号控制
    • 方式二:Nginx的命令行控制
  • Nginx服务器版本升级和新增模块
    • 方案一:使用Nginx服务信号进行升级
    • 方案二:使用Nginx安装目录的make命令完成升级
  • Nginx核心配置文件结构
    • 全局块
      • user指令
      • work process指令
      • 其他指令
    • events块
      • events指令配置实例
    • http块
      • 定义MIME-Type
      • 自定义服务日志
      • 其他配置指令
    • server块和location块
  • --------------以下是Nginx的进阶篇--------------------
  • Nginx服务器基础配置实例
  • Nginx服务操作的问题
  • Nginx配置成系统服务
  • Nginx命令配置到系统环境
  • Nginx静态资源部署
    • Nginx静态资源概述
    • Nginx静态资源的配置指令
      • listen指令
      • server_name指令
      • location指令
      • 设置请求资源的目录root / alias
      • index指令
      • error_page指令
    • 静态资源优化配置语法
    • Nginx静态资源压缩实战
      • Gzip模块配置指令
      • Gzip压缩功能的实例配置
      • Gzip和sendfile共存问题
        • gzip_static指令
    • 静态资源的缓存处理
      • 什么是缓存
      • 什么是web缓存
      • web缓存的种类
      • 浏览器缓存
      • 为什么要用浏览器缓存
      • 浏览器缓存的执行流程
      • 浏览器缓存相关指令
        • expires指令
        • add_header指令
  • Nginx的跨域问题解决
    • 同源策略
    • 跨域问题
    • 跨域问题的案例演示
    • 解决方案
  • 静态资源防盗链
    • 什么是资源盗链
    • Nginx防盗链的实现原理:
    • 针对目录进行防盗链
  • Rewrite功能配置
    • "地址重写"与"地址转发"
    • Rewrite规则
      • set指令
      • Rewrite常用全局变量
      • if指令
      • break指令
      • return指令
      • rewrite指令
      • rewrite_log指令
  • Rewrite的案例
    • 域名跳转
      • 问题分析
      • 环境准备
    • 域名镜像
    • 独立域名
    • 目录自动添加"/"
    • 合并目录
    • 防盗链

Nginx简介

背景介绍

Nginx(“engine x”)一个具有高性能的【HTTP】和【反向代理】的【WEB服务器】,同时也是一个【POP3/SMTP/IMAP代理服务器】,是由伊戈尔·赛索耶夫(俄罗斯人)使用C语言编写的,Nginx的第一个版本是2004年10月4号发布的0.1.0版本。另外值得一提的是伊戈尔·赛索耶夫将Nginx的源码进行了开源,这也为Nginx的发展提供了良好的保障。

名词解释

  1. WEB服务器:

    WEB服务器也叫网页服务器,英文名叫Web Server,主要功能是为用户提供网上信息浏览服务。

  2. HTTP:

    HTTP是超文本传输协议的缩写,是用于从WEB服务器传输超文本到本地浏览器的传输协议,也是互联网上应用最为广泛的一种网络协议。HTTP是一个客户端和服务器端请求和应答的标准,客户端是终端用户,服务端是网站,通过使用Web浏览器、网络爬虫或者其他工具,客户端发起一个到服务器上指定端口的HTTP请求。

  3. POP3/SMTP/IMAP:

    POP3(Post Offic Protocol 3)邮局协议的第三个版本,SMTP(Simple Mail Transfer Protocol)简单邮件传输协议,IMAP(Internet Mail Access Protocol)交互式邮件存取协议,通过上述名词的解释,我们可以了解到Nginx也可以作为电子邮件代理服务器。

  4. 反向代理

    正向代理

常见服务器对比

在介绍这一节内容之前,我们先来认识一家公司叫Netcraft。

Netcraft公司于1994年底在英国成立,多年来一直致力于互联网市场以及在线安全方面的咨询服务,其中在国际上最具影响力的当属其针对网站服务器、SSL市场所做的客观严谨的分析研究,公司官网每月公布的调研数据(Web Server Survey)已成为当今人们了解全球网站数量以及服务器市场分额情况的主要参考依据,时常被诸如华尔街杂志,英国BBC,Slashdot等媒体报道或引用。

我们先来看一组数据,我们先打开Nginx的官方网站 http://nginx.org/,找到Netcraft公司公布的数据,对当前主流服务器产品进行介绍。


上面这张图展示了2019年全球主流Web服务器的市场情况,其中有Apache、Microsoft-IIS、google Servers、Nginx、Tomcat等,而我们在了解新事物的时候,往往习惯通过类比来帮助自己理解事物的概貌。所以下面我们把几种常见的服务器来给大家简单介绍下:

IIS

全称(Internet Information Services)即互联网信息服务,是由微软公司提供的基于windows系统的互联网基本服务。windows作为服务器在稳定性与其他一些性能上都不如类UNIX操作系统,因此在需要高性能Web服务器的场合下,IIS可能就会被"冷落".

Tomcat

Tomcat是一个运行Servlet和JSP的Web应用软件,Tomcat技术先进、性能稳定而且开放源代码,因此深受Java爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web应用服务器。但是Tomcat天生是一个重量级的Web服务器,对静态文件和高并发的处理比较弱。

Apache

Apache的发展时期很长,同时也有过一段辉煌的业绩。从上图可以看出大概在2014年以前都是市场份额第一的服务器。Apache有很多优点,如稳定、开源、跨平台等。但是它出现的时间太久了,在它兴起的年代,互联网的产业规模远远不如今天,所以它被设计成一个重量级的、不支持高并发的Web服务器。在Apache服务器上,如果有数以万计的并发HTTP请求同时访问,就会导致服务器上消耗大量能存,操作系统内核对成百上千的Apache进程做进程间切换也会消耗大量的CUP资源,并导致HTTP请求的平均响应速度降低,这些都决定了Apache不可能成为高性能的Web服务器。这也促使了Lighttpd和Nginx的出现。

Lighttpd

Lighttpd是德国的一个开源的Web服务器软件,它和Nginx一样,都是轻量级、高性能的Web服务器,欧美的业界开发者比较钟爱Lighttpd,而国内的公司更多的青睐Nginx,同时网上Nginx的资源要更丰富些。

其他的服务器

Google Servers,Weblogic, Webshpere(IBM)…经过各个服务器的对比,种种迹象都表明,Nginx将以性能为王。这也是我们为什么选择Nginx的理由。

Nginx的优点

(1)速度更快、并发更高
单次请求或者高并发请求的环境下,Nginx都会比其他Web服务器响应的速度更快。一方面在正常情况下,单次请求会得到更快的响应,另一方面,在高峰期(如有数以万计的并发请求),Nginx比其他Web服务器更快的响应请求。Nginx之所以有这么高的并发处理能力和这么好的性能原因在于Nginx采用了多进程和I/O多路复用(epoll)的底层实现。

(2)配置简单,扩展性强

Nginx的设计极具扩展性,它本身就是由很多模块组成,这些模块的使用可以通过配置文件的配置来添加。这些模块有官方提供的也有第三方提供的模块,如果需要完全可以开发服务自己业务特性的定制模块。

(3)高可靠性

Nginx采用的是多进程模式运行,其中有一个master主进程和N多个worker进程,worker进程的数量我们可以手动设置,每个worker进程之间都是相互独立提供服务,并且master主进程可以在某一个worker进程出错时,快速去"拉起"新的worker进程提供服务

(4)热部署

现在互联网项目都要求以7*24小时进行服务的提供,针对于这一要求,Nginx也提供了热部署功能,即可以在Nginx不停止的情况下,对Nginx进行文件升级、更新配置和更换日志文件等功能。

(5)成本低、BSD许可证

BSD是一个开源的许可证,世界上的开源许可证有很多,现在比较流行的有六种分别是GPL、BSD、MIT、Mozilla、Apache、LGPL。这六种的区别是什么,我们可以通过下面一张图来解释下:

Nginx本身是开源的,我们不仅可以免费的将Nginx应用在商业领域,而且还可以在项目中直接修改Nginx的源码来定制自己的特殊要求。这些点也都是Nginx为什么能吸引无数开发者继续为Nginx来贡献自己的智慧和青春。OpenRestry [Nginx+Lua] Tengine[淘宝]

Nginx的功能特性及常用功能

Nginx提供的基本功能服务从大体上归纳为"基本HTTP服务"、“高级HTTP服务”和"邮件服务"等三大类。

基本HTTP服务

Nginx可以提供基本HTTP服务,可以作为HTTP代理服务器和反向代理服务器,支持通过缓存加速访问,可以完成简单的负载均衡和容错,支持包过滤功能,支持SSL等。

  • 处理静态文件、处理索引文件以及支持自动索引;
  • 提供反向代理服务器,并可以使用缓存加上反向代理,同时完成负载均衡和容错;
  • 提供对FastCGI、memcached等服务的缓存机制,,同时完成负载均衡和容错;
  • 使用Nginx的模块化特性提供过滤器功能。Nginx基本过滤器包括gzip压缩、ranges支持、chunked响应、XSLT、SSI以及图像缩放等。其中针对包含多个SSI的页面,经由FastCGI或反向代理,SSI过滤器可以并行处理。
  • 支持HTTP下的安全套接层安全协议SSL.
  • 支持基于加权和依赖的优先权的HTTP/2

高级HTTP服务

  • 支持基于名字和IP的虚拟主机设置
  • 支持HTTP/1.0中的KEEP-Alive模式和管线(PipeLined)模型连接
  • 自定义访问日志格式、带缓存的日志写操作以及快速日志轮转。
  • 提供3xx~5xx错误代码重定向功能支持重写(Rewrite)模块扩展
  • 支持重新加载配置以及在线升级时无需中断正在处理的请求
  • 支持网络监控
  • 支持FLV和MP4流媒体传输

邮件服务

Nginx提供邮件代理服务也是其基本开发需求之一,主要包含以下特性:

  • 支持IMPA/POP3代理服务功能
  • 支持内部SMTP代理服务功能

Nginx常用的功能模块

这也是我们重点要掌握的内容

Nginx的核心组成

Nginx环境准备

Nginx版本介绍

Nginx的官方网站为: http://nginx.org
打开源码可以看到如下的页面内容

Nginx的官方下载网站为http://nginx.org/en/download.html,当然你也可以之间在首页选中右边的download进入版本下载网页。在下载页面我们会看到如下内容:

获取Nginx源码

http://nginx.org/download/
打开上述网站,就可以查看到Nginx的所有版本,选中自己需要的版本进行下载。下载我们可以直接在windows上下载然后上传到服务器,也可以直接从服务器上下载,这个时候就需要准备一台服务器。

准备服务器系统

环境准备

(1)确认centos的内核

准备一个内核为2.6及以上版本的操作系统,因为linux2.6及以上内核才支持epoll,而Nginx需要解决高并发压力问题是需要用到epoll,所以我们需要有这样的版本要求。
我们可以使用uname -a命令来查询linux的内核版本。


(2)确保centos能联网


(3)确认关闭防火墙

这一项的要求仅针对于那些对linux系统的防火墙设置规则不太清楚的,建议大家把防火墙都关闭掉,因为我们此次课程主要的内容是对Nginx的学习,把防火墙关闭掉,可以省掉后续Nginx学习过程中遇到的诸多问题。

关闭的方式有如下两种:

(4)确认停用selinux

selinux(security-enhanced linux),美国安全局对于强制访问控制的实现,在linux2.6内核以后的版本中,selinux已经成功内核中的一部分。可以说selinux是linux史上最杰出的新安全子系统之一。虽然有了selinux,我们的系统会更安全,但是对于我们的学习Nginx的历程中,会多很多设置,所以这块建议大家将selinux进行关闭。

sestatus查看状态

如果查看不是disabled状态,我们可以通过修改配置文件来进行设置,修改SELINUX=disabled,然后重启下系统即可生效。

Nginx安装方式介绍

Nginx的安装方式有两种分别是:

如果通过Nginx源码安装需要提前准备的内容:

GCC编译器

Nginx是使用C语言编写的程序,因此想要运行Nginx就需要安装一个编译工具。GCC就是一个开源的编译器集合,用于处理各种各样的语言,其中就包含了C语言。

使用命令yum install -y gcc来安装

安装成功后,可以通过gcc --version来查看gcc是否安装成功

PCRE

Nginx在编译过程中需要使用到PCRE库(perl Compatible RegularExpressoin 兼容正则表达式库),因为在Nginx的Rewrite模块和http核心模块都会使用到PCRE正则表达式语法。

可以使用命令yum install -y pcre pcre-devel来进行安装

安装成功后,可以通过rpm -qa pcre pcre-devel来查看是否安装成功

zlib

zlib库提供了开发人员的压缩算法,在Nginx的各个模块中需要使用gzip压缩,所以我们也需要提前安装其库及源代码zlib和zlib-devel

可以使用命令yum install -y zlib zlib-devel来进行安装

安装成功后,可以通过rpm -qa zlib zlib-devel来查看是否安装成功

OpenSSL

OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包进行安全通信,并且避免被窃听。

SSL:Secure Sockets Layer安全套接协议的缩写,可以在Internet上提供秘密性传输,其目标是保证两个应用间通信的保密性和可靠性。在Nginx中,如果服务器需要提供安全网页时就需要用到OpenSSL库,所以我们需要对OpenSSL的库文件及它的开发安装包进行一个安装。

可以使用命令yum install -y openssl openssl-devel来进行安装

安装成功后,可以通过rpm -qa openssl openssl-devel来查看是否安装成功

上述命令,一个个来的话比较麻烦,我们也可以通过一条命令来进行安装

yum install -y gcc pcre pcre-devel zlib zlib-devel opensslopenssl-devel进行全部安装。

方案一:Nginx的源码简单安装

(1)进入官网查找需要下载版本的链接地址,然后使用wget命令进行下载

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

(2)建议大家将下载的资源进行包管理

mkdir -p nginx/core
mv nginx-1.16.1.tar.gz nginx/core

(3)解压缩

tar -xzf nginx-1.16.1.tar.gz

(4)进入资源文件中,发现configure

./configure

(5)编译

make

(6)安装

make install

方案二:yum安装

使用源码进行简单安装,我们会发现安装的过程比较繁琐,需要提前准备GCC编译器、PCRE兼容正则表达式库、zlib压缩库、OpenSSL安全通信的软件库包,然后才能进行Nginx的安装。

(1)安装yum-utils

sudo yum install -y yum-utils

(2)添加yum源文件

vim /etc/yum.repos.d/nginx.repo

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/
$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$re
leasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

(3)查看是否安装成功

yum list | grep nginx


(4)使用yum进行安装

yun install -y nginx

(5)查看nginx的安装位置

whereis nginx


(6)启动测试

源码简单安装和yum安装的差异:

这里先介绍一个命令: ./nginx -V,通过该命令可以查看到所安装Nginx的版本及相关配置信息。

简单安装


yum安装

解压Nginx目录

执行tar -zxvf nginx-1.16.1.tar.gz对下载的资源进行解压缩,进入压缩后的目录,可以看到如下结构


内容解释:

  • auto:存放的是编译相关的脚本
  • CHANGES:版本变更记录
  • CHANGES.ru:俄罗斯文的版本变更记录
  • conf:nginx默认的配置文件
  • configure:nginx软件的自动脚本程序,是一个比较重要的文件,作用如下:
    (1)检测环境及根据环境检测结果生成C代码
    (2)生成编译代码需要的Makefile文件
  • contrib:存放的是几个特殊的脚本文件,其中README中对脚本有着详细的说明
  • html:存放的是Nginx自带的两个html页面,访问Nginx的首页和错误页面
  • LICENSE:许可证的相关描述文件
  • man:nginx的man手册
  • README:Nginx的阅读指南
  • src:Nginx的源代码

方案三:Nginx的源码复杂安装

这种方式和简单的安装配置不同的地方在第一步,通过./configure来对编译参数进行设置,需要我们手动来指定。那么都有哪些参数可以进行设置,接下来我们进行一个详细的说明。

  • PATH:是和路径相关的配置信息
  • with:是启动模块,默认是关闭的
  • without:是关闭模块,默认是开启的

我们先来认识一些简单的路径配置已经通过这些配置来完成一个简单的编译:

--prefix=PATH

指向Nginx的安装目录,默认值为/usr/local/nginx

--sbin-path=PATH

指向(执行)程序文件(nginx)的路径,默认值为 < prefix>/sbin/nginx

--modules-path=PATH

指向Nginx动态模块安装目录,默认值为< prefix>/modules

--conf-path=PATH

指向配置文件(nginx.conf)的路径,默认值为< prefix>/conf/nginx.conf

--error-log-path=PATH

指向错误日志文件的路径,默认值为< prefix>/logs/error.log

--http-log-path=PATH

指向访问日志文件的路径,默认值为< prefix>/logs/access.log

--pid-path=PATH

指向Nginx启动后进行ID的文件路径,默认值为< prefix>/logs/nginx.pid

--lock-path=PATH

指向Nginx锁文件的存放路径,默认值为< prefix>/logs/nginx.lock

要想使用可以通过如下命令

./configure --prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--modules-path=/usr/local/nginx/modules \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--lock-path=/usr/local/nginx/logs/nginx.lock

在使用上述命令之前,需要将之前服务器已经安装的nginx进行卸载,卸载的步骤分为三步骤:

步骤一:需要将nginx的进程关闭

./nginx -s stop

步骤二:将安装的nginx进行删除

rm -rf /usr/local/nginx

步骤三:将安装包之前编译的环境清除掉

make clean

Nginx目录结构分析

在使用Nginx之前,我们先对安装好的Nginx目录文件进行一个分析,在这块给大家介绍一个工具tree,通过tree我们可以很方面的去查看centos系统上的文件目录结构,当然,如果想使用tree工具,就得先通过yum install -y tree来进行安装,安装成功后,可以通过执行tree /usr/local/nginx(tree后面跟的是Nginx的安装目录),获取的结果如下:

  • conf:nginx所有配置文件目录
  • CGI(Common Gateway Interface)通用网关【接口】,主要解决的问题是从客户端发送一个请求和数据,服务端获取到请求和数据后可以调用调用CGI【程序】处理及相应结果给客户端的一种标准规范。
  • fastcgi.conf:fastcgi相关配置文件
  • fastcgi.conf.default:fastcgi.conf的备份文件
  • fastcgi_params:fastcgi的参数文件
  • fastcgi_params.default:fastcgi的参数备份文件
  • scgi_params:scgi的参数文件
  • scgi_params.default:scgi的参数备份文件
  • uwsgi_params:uwsgi的参数文件
  • uwsgi_params.default:uwsgi的参数备份文件
  • mime.types:记录的是HTTP协议中的Content-Type的值和文件后缀名的对应关系
  • mime.types.default:mime.types的备份文件
  • nginx.conf:这个是Nginx的核心配置文件,这个文件非常重要,也是我们即将要学习的重点
  • nginx.conf.default:nginx.conf的备份文件
  • koi-utf、koi-win、win-utf这三个文件都是与编码转换映射相关的配置文件,用来将一种编码转换成另一种编码
  • html:存放nginx自带的两个静态的html页面
  • 50x.html:访问失败后的失败页面
  • index.html:成功访问的默认首页
  • logs:记录入门的文件,当nginx服务器启动后,这里面会有 access.logerror.log 和nginx.pid三个文件出现。
  • sbin:是存放执行程序文件
  • nginxnginx是用来控制Nginx的启动和停止等相关的命令。

Nginx服务器启停命令

方式一:Nginx服务的信号控制


前面在提到Nginx的高性能,其实也和它的架构模式有关。Nginx默认采用的是多进程的方式来工作的,当将Nginx启动后,我们通过ps -ef |grep nginx命令可以查看到如下内容:

从上图中可以看到,Nginx后台进程中包含一个master进程和多个worker进程,master进程主要用来管理worker进程,包含接收外界的信息,并将接收到的信号发送给各个worker进程,监控worker进程的状态,当worker进程出现异常退出后,会自动重新启动新的worker进程。而worker进程则是专门用来处理用户请求的,各个worker进程之间是平等的并且相互独立,处理请求的机会也是一样的。nginx的进程模型,我们可以通过下图来说明下:

我们现在作为管理员,只需要通过给master进程发送信号就可以来控制Nginx,这个时候我们需要有两个前提条件,一个是要操作的master进程,一个是信号。
(1)要想操作Nginx的master进程,就需要获取到master进程的进程号ID。获取方式简单介绍两个,

方式一:通过ps -ef | grep nginx
方式二:在讲解nginx的./configure的配置参数的时候,有一个参数是--pid-path=PATH默认是/usr/local/nginx/logs/nginx.pid,所以可以通过查看该文件来获取nginx的master进程ID.

(2)信号


调用命令为kill -signal PID
signal:即为信号;PID即为获取到的master线程ID

  1. 发送TERM/INT信号给master进程,会将Nginx服务立即关闭。

  2. 发送QUIT信号给master进程,master进程会控制所有的work进程不再接收新的请求,等所有请求处理完后,在把进程都关闭掉。

  3. 发送HUP信号给master进程,master进程会把控制旧的work进程不再接收新的请求,等处理完请求后将旧的work进程关闭掉,然后根据nginx的配置文件重新启动新的work进程

  4. 发送USR1信号给master进程,告诉Nginx重新开启日志文件

  5. 发送USR2信号给master进程,告诉master进程要平滑升级,这个时候,会重新开启对应的master进程和work进程,整个系统中将会有两个master进程,并且新的master进程的PID会被记录在/usr/local/nginx/logs/nginx.pid而之前的旧的master进程PID会被记录在/usr/local/nginx/logs/nginx.pid.oldbin文件中,接着再次发送QUIT信号给旧的master进程,让其处理完请求后再进行关闭

  1. 发送WINCH信号给master进程,让master进程控制不让所有的work进程在接收新的请求了,请求处理完后关闭work进程。注意maste进程不会被关闭掉

方式二:Nginx的命令行控制

此方式是通过Nginx安装目录下的sbin下的可执行文件nginx来进行Nginx状态的控制,我们可以通过nginx -h来查看都有哪些参数可以用:

-?和-h:显示帮助信息
-v:打印版本号信息并退出
-V:打印版本号信息和配置信息并退出
-t:测试nginx的配置文件语法是否正确并退出
-T:测试nginx的配置文件语法是否正确并列出用到的配置文件信息然后退出
-q:在配置测试期间禁止显示非错误消息
-s:signal信号,后面可以跟 :


-p:prefix,指定Nginx的prefix路径,(默认为: /usr/local/nginx/)
-c:filename,指定Nginx的配置文件路径,(默认为: conf/nginx.conf)
-g:用来补充Nginx配置文件,向Nginx服务指定启动时应用全局的配置

Nginx服务器版本升级和新增模块

果想对Nginx的版本进行更新,或者要应用一些新的模块,最简单的做法就是停止当前的Nginx服务,然后开启新的Nginx服务。但是这样会导致在一段时间内,用户是无法访问服务器。为了解决这个问题,我们就需要用到Nginx服务器提供的平滑升级功能。这个也是Nginx的一大特点,使用这种方式,就可以使Nginx在7*24小时不间断的提供服务了。接下来我们分析下需求:

需求:Nginx的版本最开始使用的是Nginx-1.14.2,由于服务升级,需要将Nginx的版本升级到Nginx-1.16.1,要求Nginx不能中断提供服务。

为了应对上述的需求,这里我们给大家提供两种解决方案:
方案一:使用Nginx服务信号完成Nginx的升级
方案二:使用Nginx安装目录的make命令完成升级

环境准备
(1)先准备两个版本的Nginx分别是 1.14.2和1.16.1

(2)使用Nginx源码安装的方式将1.14.2版本安装成功并正确访问

(3)将Nginx1.16.1进行参数配置和编译,不需要进行安装。

方案一:使用Nginx服务信号进行升级

第一步:将1.14.2版本的sbin目录下的nginx进行备份

cd /usr/local/nginx/sbin
mv nginx nginxold

第二步:将Nginx1.16.1安装目录编译后的objs目录下的nginx文件,拷贝到原来/usr/local/nginx/sbin目录下

cd ~/nginx/core/nginx-1.16.1/objs
cp nginx /usr/local/nginx/sbin

第三步:发送信号USR2给Nginx的1.14.2版本对应的master进程
第四步:发送信号QUIT给Nginx的1.14.2版本对应的master进程

方案二:使用Nginx安装目录的make命令完成升级

第一步:将1.14.2版本的sbin目录下的nginx进行备份

cd /usr/local/nginx/sbin
mv nginx nginxold

第二步:将Nginx1.16.1安装目录编译后的objs目录下的nginx文件,拷贝到原来/usr/local/nginx/sbin目录下

cd ~/nginx/core/nginx-1.16.1/objs
cp nginx /usr/local/nginx/sbin

第三步:进入到安装目录,执行make upgrade

第四步:查看是否更新成功

./nginx -v

在整个过程中,其实Nginx是一直对外提供服务的。并且当Nginx的服务器启动成功后,我们是可以通过浏览器进行直接访问的,同时我们可以通过更改html目录下的页面来修改我们在页面上所看到的内容,那么问题来了,为什么我们要修改html目录下的文件,能不能多添加一些页面使Nginx的功能更加丰富,还有前面聊到Nginx的前端功能又是如何来实现的,这就需要我们对Nginx的核心配置文件进行一个详细的学习。

Nginx核心配置文件结构

从前面的内容学习中,我们知道Nginx的核心配置文件默认是放在/usr/local/nginx/conf/nginx.conf,这一节,我们就来学习下nginx.conf的内容和基本配置方法。

读取Nginx自带的Nginx配置文件,我们将其中的注释部分【学习一个技术点就是在Nginx的配置文件中可以使用#来注释】删除掉后,就剩下下面内容:

worker_processes 1;events {worker_connections 1024;}
http {include       mime.types;  default_type application/octet-stream; sendfile       on; keepalive_timeout 65; server {     listen       80;    server_name localhost;   location / {     root   html;     index index.html index.htm;           }     error_page   500 502 503 504 /50x.html;     location = /50x.html {        root   html;     }   }
}


简单小结下:
nginx.conf配置文件中默认有三大块:全局块、events块、http块
http块中可以配置多个server块,每个server块又可以配置多个location块。

全局块

user指令

(1)user:用于配置运行Nginx服务器的worker进程的用户和用户组。

该属性也可以在编译的时候指定,语法如下./configure --user=user–group=group,如果两个地方都进行了设置,最终生效的是配置文件中的配置。

该指令的使用步骤:
(1)设置一个用户信息"www"

user www;


测试一下配置文件:这个报错的愿意是因为当前没有user用户

(2) 创建一个用户

useradd www


修改之前 worker进程的用户时nobody

修改之后,重新加载配置文件,worker进程的用户变为www

(3)修改user属性

user www

(4)创建/root/html/index.html页面,添加如下内容

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>body {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sansserif;}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfullyinstalled andworking. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
<p><em>I am WWW</em></p>
</body>
</html>

(5)修改nginx.conf


(重新加载nginx服务)

(5)测试启动访问

页面会报403拒绝访问的错误

(6)分析原因

因为当前用户没有访问/root/html目录的权限

(7)将文件创建到 /home/www/html/index.html,修改配置


(8)再次测试启动访问

综上所述,使用user指令可以指定启动运行工作进程的用户及用户组,这样对于系统的权限访问控制的更加精细,也更加安全。

work process指令

master_process:用来指定是否开启工作进程。

如果我们想关闭nginx的worker进程,可以nginx.conf中添加如此:

重新加载配置

你会发现worker进程还存在,这是因为要想让此配置生效就必须重启nginx服务

worker_processes:用于配置Nginx生成工作进程的数量,这个是Nginx服务器实现并发处理服务的关键所在。理论上来说workder process的值越大,可以支持的并发处理量也越多,但事实上这个值的设定是需要受到来自服务器自身的限制,建议将该值和服务器CPU的内核数保存一致


如果将worker_processes设置成2,则会看到如下内容:


其他指令

daemon:设定Nginx是否以守护进程的方式启动。
守护式进程是linux后台执行的一种服务进程,特点是独立于控制终端,不会随着终端关闭而停止。

非守护进程:

同样此命令需要重启Nginx

发现依然能访问Nginx

如果我们关掉

再访问,此时Nginx已经无法访问,这就是非守护进程

守护进程:
Nginx默认就是守护进程

pid:用来配置Nginx当前master进程的进程号ID存储的文件路径。

这个文件只有Nginx是守护进程才会有

error_log:用来配置Nginx的错误日志存放路径

该属性可以通过./configure --error-log-path=PATH来指定

其中日志级别的值有:
debug|info|notice|warn|error|crit|alert|emerg,翻译过来为试|信息|通知|警告|错误|临界|警报|紧急,这块建议大家设置的时候不要设置成info以下的等级,因为会带来大量的磁盘I/O消耗,影响Nginx的性能。

(5)include:用来引入其他配置文件,使Nginx的配置更加灵活


新建一个main.conf

把nginx.conf这部分内容移动到main.conf


在nginx.conf中引入main.conf

events块

(1)accept_mutex:用来设置Nginx网络连接序列化

这个配置主要可以用来解决常说的"惊群"问题。大致意思是在某一个时刻,客户端发来一个请求连接,Nginx后台是以多进程的工作模式,也就是说有多个worker进程会被同时唤醒,但是最终只会有一个进程可以获取到连接,如果每次唤醒的进程数目太多,就会影响Nginx的整体性能。如果将上述值设置为on(开启状态),将会对多个Nginx进程接收连接进行序列号,一个个来唤醒接收,就防止了多个进程对连接的争抢。

具体on的效率高还是off的效率高,还要看具体的生产环境

(2)multi_accept:用来设置是否允许同时接收多个网络连接

如果multi_accept被禁止了,nginx一个工作进程只能同时接受一个新的连接。否则,一个工作进程可以同时接受所有的新连接

(3)worker_connections:用来配置单个worker进程最大的连接数

这里的连接数不仅仅包括和前端用户建立的连接数,而是包括所有可能的连接数。另外,number值不能大于操作系统支持打开的最大文件句柄数量。

(4)use:用来设置Nginx服务器选择哪种事件驱动来处理网络消息。

注意:此处所选择事件处理模型是Nginx优化部分的一个重要内容,method的可选值有select/poll/epoll/kqueue等,之前在准备centos环境的时候,我们强调过要使用linux内核在2.6以上,就是为了能使用epoll函数来优化Nginx。

另外这些值的选择,我们也可以在编译的时候使用

–with-select_module、–without-select_module、–with-poll_module、–without-poll_module来设置是否需要将对应的事件驱动模块编译到Nginx的内核。

events指令配置实例

events {accept_mutex on; # 解决惊群,将会对多个Nginx进程接收连接进行序列号,一个个来唤醒接收,就防止了多个进程对连接的争抢multi_accept on; # 一个工作进程可以同时接受所有的新连接worker_connections 1024;  # 单个worker进程最大的连接数use epoll; # 使用IO多路复用
}

启动测试

http块

定义MIME-Type

我们都知道浏览器中可以显示的内容有HTML、XML、GIF等种类繁多的文件、媒体等资源,浏览器为了区分这些资源,就需要使用MIMEType。所以说MIME Type是网络资源的媒体类型。Nginx作为web服务器,也需要能够识别前端请求的资源类型。

在Nginx的配置文件中,默认有两行配置


(1)default_type:用来配置Nginx响应前端请求默认的MIME类型。

在default_type之前还有一句include mime.types,include之前我们已经介绍过,相当于把mime.types文件中MIMT类型与相关类型文件的文件后缀名的对应关系加入到当前的配置文件中。

举例来说明:

有些时候请求某些接口的时候需要返回指定的文本字符串或者json字符串,如果逻辑非常简单或者干脆是固定的字符串,那么可以使用nginx快速实现,这样就不用编写程序响应请求了,可以减少服务器资源占用并且响应性能非常快。

如何实现

     location  /get_text {return 200 " <h1>This Is Nginx Text</h1>";}


因为配置文件中以二进制流的方式来处理,所以浏览器请求时会以附件形式操作

我们为该请求配置Nginx响应前端请求默认的MIME类型

  location  /get_text {default_type  text/plain;return 200 "<h1>This Is Nginx Text</h1>";}

再测试

text/palin 不会解析标签,只是文本处理

 location  /get_text {default_type  text/html;return 200 "<h1>This Is Nginx Text</h1>";}

text/html 可以解析标签

如果你想展示Json

  location  /get_json {default_type application/json;return 200 "{'username':'TOM' , 'age':18}";}


这个报错,可能是我浏览器json插件有问题,或者我json格式写的不对,总之,如果想要浏览器响应json,需要 default_type application/json;指定

自定义服务日志

Nginx中日志的类型分access.log、error.log。

access.log:用来记录用户所有的访问请求。

这里面再打开之前,我把执行的请求日志删除了

现在请求一次Nginx服务,就拿之前http://192.168.200.130/get_text测试
重启再打开日文件,可以发现里面已经记录了一条请求记录

具体内容:192.168.200.1 - - [11/Jun/2022:18:53:31 +0800] "GET /get_text HTTP/1.1" 200 27 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36"

那么如何定制这个日志呢?请看下面

error.log:记录nginx本身运行时的错误信息,不会记录用户的访问请求。

Nginx服务器支持对服务日志的格式、大小、输出等进行设置,需要使用到两个指令,分别是access_log和log_format指令。

(1)access_log:用来设置用户访问日志的相关属性。

  • 更换日志文件的输出的位置

在nginx.conf中修改

如果在请求http://192.168.200.130/get_tex logs文件夹下就会有my.log日志文件,里面就是我们本次请求的日志


具体内容:192.168.200.1 - - [11/Jun/2022:19:07:11 +0800] "GET /get_text HTTP/1.1" 200 27 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36"

而原来的access.log还是之前的一次请求

这样我们就修改了日志的输出文件

(2)log_format:用来指定日志的输出格式。

  • 修改日志内容

同样在nginx.conf中修改


可以发现日志,已经被修改

192.168.200.1 - - [11/Jun/2022:18:53:31 +0800] "GET /get_text HTTP/1.1" 200 27 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36"这种样式的日志文件,我们在后面说

其中"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36"和浏览器的User-Agent是一致的

如果你也想在自定义的日志文件中加上`User-Agent,需要如下修改nginx.conf

其他配置指令

(1)sendfile:用来设置Nginx服务器是否使用sendfile()传输文件,该属性可以大大提高Nginx处理静态资源的性能

它原理是零拷贝技术

(2)keepalive_timeout:用来设置长连接的超时时间。
》为什么要使用keepalive

我们都知道HTTP是一种无状态协议,客户端向服务端发送一个TCP请求,服务端响应完毕后断开连接。
如果客户端向服务端发送多个请求,每个请求都需要重新创建一次连接,效率相对来说比较多,使用keepalive模式,可以告诉服务器端在处理完一个请求后保持这个TCP连接的打开状态,若接收到来自这个客户端的其他请求,服务端就会利用这个未被关闭的连接,而不需要重新创建一个新连接,提升效率,但是这个连接也不能一直保持,这样的话,连接如果过多,也会是服务端的性能下降,这个时候就需要我们进行设置其的超时时间。


(3)keepalive_requests:用来设置一个keep-alive连接使用的次数。

server块和location块

server块和location块都是我们要重点讲解和学习的内容,因为我们后面会对Nginx的功能进行详细讲解,所以这块内容就放到静态资源部署的地方给大家详细说明。

本节我们主要来认识下Nginx默认给的nginx.conf中的相关内容,以及server块与location块在使用的时候需要注意的一些内容。

配置遵循就近原则

--------------以下是Nginx的进阶篇--------------------

Nginx服务器基础配置实例

前面我们已经对Nginx服务器默认配置文件的结构和涉及的基本指令做了详细的阐述。通过这些指令的合理配置,我们就可以让一台Nginx服务器正常工作,并且提供基本的web服务器功能。

接下来我们将通过一个比较完整和最简单的基础配置实例,来巩固下前面所学习的指令及其配置。

需求如下:

准备相关文件,目录如下:

首先把我们前面配置的nginx配置文件恢复成原始的样子,只保留关键的

worker_processes  1;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;server {listen       80;server_name  localhost;location / {root   html;index  index.html index.htm;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}}

准备环节:

可以直接把这个文件的内容cp 过去后再清理

配置的内容如下:

#指定工作进程所对应的用户以及用户组
user www;
#nginx在启动的时候生成工作进程的个数
worker_processes  2;
#错误日志的路径
error_log logs/error.log;
#指定master进程对应的pid的路径
pid logs/nginx.pid;
#设置为守护线程,默认就是守护线程,这里可以注掉
# daemon on;events {# 解决惊群现象accept_mutex on;# 允许worker进程可以同时接受多个请求multi_accept on;#worker进程最大所能接受的连接数worker_connections  1024;#指定nginx使用的事件模型,原理是IO多路复用技术use epoll;
}http {# 解决mime类型的配置,如果mime.types文件中没有对应的类型,那就使用default_type 默认的二进制流,浏览器会响应下载include       mime.types;default_type  application/octet-stream;# 主要用于提升nginx处理静态资源的效率,底层是零拷贝技术sendfile        on;#设置长连接的超时时间,请求处理完后,不立即断开TCP链接,防止反复建立三次握手和四次挥手带来的性能影响keepalive_timeout  65;#各服务的日志格式(这里设置一个间的格式,后面会详细讲解怎么设置一个适合自己业务的日志格式)log_format server1 '=====>server1 access log format';log_format server2 '=====>server1 access log format';# 引入外部的配置文件include /home/www/conf.d/*.conf;server {listen       80;server_name  localhost;location / {root   html;index  index.html index.htm;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}}

server1.conf

server{#配置监听端口和主机名称listen 8081;server_name localhost;#处理请求日志存放路径access_log  /home/www/myweb/server1/logs/access.log  server1;#处理配置 /server1/location1请求的locationlocation /server1/location1{root /home/www/myweb;index index_sr1_location1.html;  }#处理配置 /server1/location2请求的locationlocation /server1/location2{root /home/www/myweb;index index_sr1_location2.html;  }#配置错误页面,对404.html 做了定向配置error_page 404 /404.html;#配置错误页面转向location = /404.html {root  home/www/myweb;index 404.html;}
}

server2.conf

server{listen 8082;server_name localhost;access_log  /home/www/myweb/server2/logs/access.log  server2;location /server2/location1{root /home/www/myweb;index index_sr2_location1.html;  }location /server2/location2{root /home/www/myweb;index index_sr2_location2.html;  }error_page 404 /404.html;location = /404.html {root  home/www/myweb;index 404.html;}
}





Nginx服务操作的问题

经过前面的操作,我们会发现,如果想要启动、关闭或重新加载nginx配置文件,都需要先进入到nginx的安装目录的sbin目录,然后使用nginx的二级制可执行文件来操作,相对来说操作比较繁琐,这块该如何优化?另外如果我们想把Nginx设置成随着服务器启动就自动完成启动操作,又该如何来实现?这就需要用到接下来我们要讲解的两个知识点:

Nginx配置成系统服务
Nginx命令配置到系统环境

Nginx配置成系统服务

把Nginx应用服务设置成为系统服务,方便对Nginx服务的启动和停止等相关操作,具体实现步骤:
(1) 在/usr/lib/systemd/system目录下添加nginx.service,内容如下:

(2)添加完成后如果权限有问题需要进行权限设置

chmod 755 /usr/lib/systemd/system/nginx.service

(3)使用系统命令来操作Nginx服务

启动: systemctl start nginx
停止: systemctl stop nginx
重启: systemctl restart nginx
重新加载配置文件: systemctl reload nginx
查看nginx状态: systemctl status nginx
开机启动: systemctl enable nginx




Nginx命令配置到系统环境

前面我们介绍过Nginx安装目录下的二级制可执行文件nginx的很多命令,要想使用这些命令前提是需要进入sbin目录下才能使用,很不方便,如何去优化,我们可以将该二进制可执行文件加入到系统的环境变量,这样的话在任何目录都可以使用nginx对应的相关命令。具体实现步骤如下:

之前演示:

优化:
(1)修改/etc/profile文件


(2)使之立即生效

source /etc/profile

(3)执行nginx命令

Nginx静态资源部署

Nginx静态资源概述

上网去搜索访问资源对于我们来说并不陌生,通过浏览器发送一个HTTP请求实现从客户端发送请求到服务器端获取所需要内容后并把内容回显展示在页面的一个过程。这个时候,我们所请 求的内容就分为两种类型,一类是静态资源、一类是动态资源。
静态资源即指在服务器端真实存在并且能直接拿来展示的一些文件,比如常见的html页面、css文件、js文件、图 片、视频等资源;
动态资源即指在服务器端真实存在但是要想获取需要经过一定的业务逻辑处理,根据不同的条件展示在页面不同这 一部分内容,比如说报表数据展示、根据当前登录用户展示相关具体数据等资源;

Nginx处理静态资源的内容,我们需要考虑下面这几个问题:

Nginx静态资源的配置指令

listen指令

listen:用来配置监听端口。

listen的设置比较灵活,我们通过几个例子来把常用的设置方式熟悉下:

default_server属性是标识符,用来将此虚拟主机设置成默认主机。所谓的默认主机指的是如果没有匹配到对应的address:port,则会默认执行的。如果不指定默认使用的是第一个server。

  • 我们把配置文件中的sever修改一下

  • 重新加载配置文件

  • 测试

  • 你会发现http://192.168.200.130:8080/也能访问到Nginx服务,为什么呢?因为,Nginx会先按照192.168.200.130:8080去访问,发现没有找到,就会按照127.0.0.1:8080去访问(没有找到就按照默认服务去访问,不指定的化,默认就是第一个server),所以访问了http://127.0.0.1:8080/

  • 验证:

  • default_server指定

server_name指令

server_name:用来设置虚拟主机服务名称。

127.0.0.1 、 localhost 、域名[www.baidu.com | www.jd.com]


关于server_name的配置方式有三种,分别是:


补充小知识点:

hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交DNS域名解析服务器进行IP地址的解析。

windows:C:\Windows\System32\drivers\etc

centos:/etc/hosts

因为域名是要收取一定的费用,所以我们可以使用修改hosts文件来制作一些虚拟域名来使用。需要修改 /etc/hosts文件来添加


配置方式二:使用通配符配置:

server_name中支持通配符"*",但需要注意的是通配符不能出现在域名的中间,只能出现在首段或尾段,如:


配置三:使用正则表达式配置
server_name中可以使用正则表达式,并且使用~作为正则表达式字符串的开始标记。

常见的正则表达式

配置如下:

匹配执行顺序
由于server_name指令支持通配符和正则表达式,因此在包含多个虚拟主机的配置文件中,可能会出现一个名称被多个虚拟主机的server_name匹配成功,当遇到这种情况,当前的请求交给谁来处理呢?



location指令


location:用来设置请求的URI

uri变量是待匹配的请求字符串,可以不包含正则表达式,也可以包含正则表达式,那么nginx服务器在搜索匹配location的时候,是先使用不包含正则表达式进行匹配,找到一个匹配度最高的一个,然后在通过包含正则表达式的进行匹配,如果能匹配到直接访问,匹配不到,就使用刚才匹配度最高的那个location来处理请求。

属性介绍:

不带符号,要求必须以指定模式开始


= : 用于不包含正则表达式的uri前,必须与指定的模式精确匹配


~ : 用于表示当前uri中包含了正则表达式,并且区分大小写
~*: 用于表示当前uri中包含了正则表达式,并且不区分大小写

换句话说,如果uri包含了正则表达式,需要用上述两个符合来标识

^~: 用于不包含正则表达式的uri前,功能和不加符号的一致,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了。

设置请求资源的目录root / alias

root:设置请求的根目录


path为Nginx服务器接收到请求以后查找资源的根目录路径。
alias:用来更改location的URI


path为修改后的根路径。
以上两个指令都可以来指定访问资源的路径,那么这两者之间的区别是什么?
举例说明:
(1)在/usr/local/nginx/html目录下创建一个 images目录,并在目录下放入一张图片mv.png图片

访问图片的路径为:

(2)如果把root改为alias

再次访问上述地址,页面会出现404的错误,查看错误日志会发现是因为地址不对,所以验证了:

root的处理结果是: root路径+location路径
/usr/local/nginx/html/images/mv.png
alias的处理结果是:使用alias路径替换location路径
/usr/local/nginx/html/images

需要在alias后面路径改为

(3)如果location路径是以/结尾,则alias也必须是以/结尾,root没有要求
将上述配置修改为

访问就会出问题,查看错误日志还是路径不对,所以需要把alias后面加上 /
小结:

root的处理结果是: root路径+location路径
alias的处理结果是:使用alias路径替换location路径
alias是一个目录别名的定义,root则是最上层目录的含义。
如果location路径是以/结尾,则alias也必须是以/结尾,root没有要求

index指令

index:设置网站的默认首页

index后面可以跟多个设置,如果访问的时候没有指定具体访问的资源,则会依次进行查找,找到第一个为止。

举例说明:

error_page指令

error_page:设置网站的错误页面

当出现对应的响应code后,如何来处理。
举例说明:
(1)可以指定具体跳转的地址

(2)可以指定重定向地址

(3)使用location的@符合完成错误信息展示

可选项=[response]的作用是用来将相应代码更改为另外一个

静态资源优化配置语法

Nginx对静态资源如何进行优化配置。这里从三个属性配置进行优化:

(1)sendfile,用来开启高效的文件传输模式。

请求静态资源的过程:客户端通过网络接口向服务端发送请求,操作系统将这些客户端的请求传递给服务器端应用程序,服务器端应用程序会处理这些请求,请求处理完成以后,操作系统还需要将处理得到的结果通过网络适配器传递回去。
如:


sendFile就是我们说的零拷贝技术
如果不开启,那么数据从磁盘到网卡需要经过:2次系统调用(就是4次进程状态切换)+2次CPU拷贝+2次DMA拷贝
如果开启,只需1次系统调用+2次DMA拷贝(仅对LINUX2.4以及以上的版本,否则需要一次额外的CPU拷贝)
如果想详细了解零拷贝技术,请看我这篇博客零拷贝

(2)tcp_nopush:该指令必须在sendfile打开的状态下才会生效,主要是用来提升网络包的传输’效率’

(3)tcp_nodelay:该指令必须在keep-alive连接开启的情况下才生效,来提高网络包传输的’实时性’


经过刚才的分析,“tcp_nopush"和”tcp_nodelay“看起来是"互斥的”,那么为什么要将这两个值都打开,这个大家需要知道的是在linux2.5.9以后的版本中两者是可以兼容的,三个指令都开启的好处是,sendfile可以开启高效的文件传输模式,tcp_nopush开启可以确保在发送到客户端之前数据包已经充分“填满”, 这大大减少了网络开销,并加快了文件发送的速度。 然后,当它到达最后一个可能因为没有“填满”而暂停的数据包时,Nginx会忽略tcp_nopush参数, 然后,tcp_nodelay强制套接字发送数据。由此可知,TCP_NOPUSH可以与TCP_NODELAY一起设置,它比单独配置TCP_NODELAY具有更强的性能。所以我们可以使用如下配置来优化Nginx静态资源的处理

Nginx静态资源压缩实战

经过上述内容的优化,我们再次思考一个问题,假如在满足上述优化的前提下,我们传送一个1M的数据和一个10M的数据那个效率高?,答案显而易见,传输内容小,速度就会快。那么问题又来了,同样的内容,如果把大小降下来,我们脑袋里面要蹦出一个词就是"压缩",接下来,我们来学习Nginx的静态资源压缩模块。

在Nginx的配置文件中可以通过配置gzip来对静态资源进行压缩,相关的指令可以配置在http块、server块和location块中,Nginx可以通过


对这些指令进行解析和处理。
接下来我们从以下内容进行学习

Gzip模块配置指令

接下来所学习的指令都来自ngx_http_gzip_module模块,该模块会在nginx安装的时候内置到nginx的安装环境中,也就是说我们可以直接使用这些指令。

1、 gzip指令:该指令用于开启或者关闭gzip功能


注意只有该指令为打开状态,下面的指令才有效果

2、 gzip_types指令:该指令可以根据响应页的MIME类型选择性地开启Gzip压缩功能


所选择的值可以从mime.types文件中进行查找,也可以使用"*"代表所有。

实例:

配置文件

html中有一个jquery.js文件

未压缩前访问

配置压缩

再访问发现资源大小没变

这是因为请求的资源类型是application/javascript,

我们需要通过gzip_types指定压缩资源的媒体类型为application/javascript


再次访问,发现资源已经被压缩

gzip_types 后面也可以跟多个资源类型

3、 gzip_comp_level指令:该指令用于设置Gzip压缩程度,级别从1-9,1表示要是程度最低,要是效率最高,9刚好相反,压缩程度最高,但是效率最低最费时间。

不同压缩级别下的对比:



这个压缩级别不是越高越好,越高越消耗CPU资源,压缩效果却不见得显著提升,建议设置成中间值

4、 gzip_vary指令:该指令用于设置使用Gzip进行压缩发送是否携带“Vary:Accept-Encoding”头域的响应头部。主要是告诉接收方,所发送的数据经过了Gzip压缩处理


5、gzip_buffers指令:该指令用于处理请求压缩的缓冲区数量和大小。

其中number:指定Nginx服务器向系统申请缓存空间个数,size指的是每个缓存空间的大小。主要实现的是申请number个每个大小为size的内存空间。这个值的设定一般会和服务器的操作系统有关,所以建议此项不设置,使用默认值即可。

6、 gzip_disable指令:针对不同种类客户端发起的请求,可以选择性地开启和关闭Gzip功能。

regex:根据客户端的浏览器标志(user-agent)来设置,支持使用正则表达式。指定的浏览器标志不使用Gzip.该指令一般是用来排除一些明显不支持Gzip的浏览器。

一般针对低版本的浏览器,可以配置关闭gzip压缩,个别浏览器不支持gzip压缩

7、gzip_http_version指令:针对不同的HTTP协议版本,可以选择性地开启和关闭Gzip功能。

目前绝大多数的请求都是http1.1版本的,所以这个指令不建议配置

8、gzip_min_length指令:该指令针对传输数据的大小,可以选择性地开启和关闭Gzip功能


Gzip压缩功能对大数据的压缩效果明显,但是如果要压缩的数据比较小的化,可能出现越压缩数据量越大的情况,因此我们需要根据响应内容的大小来决定是否使用Gzip功能,响应页面的大小可以通过头信息中的Content-Length来获取。但是如何使用了Chunk编码动态压缩,该指令将被忽略。建议设置为1K或以上。



9、gzip_proxied指令:该指令设置是否对服务端返回的结果进行Gzip压缩。

Gzip压缩功能的实例配置


这些配置在很多地方可能都会用到,所以我们可以将这些内容抽取到一个配置文件中,然后通过include指令把配置文件再次加载到nginx.conf配置文件中,方法使用。
nginx_gzip.conf

Gzip和sendfile共存问题

前面在讲解sendfile的时候,提到过,开启sendfile以后,在读取磁盘上的静态资源文件的时候,可以减少拷贝的次数,可以不经过用户进程将静态文件通过网络设备发送出去,但是Gzip要想对资源压缩,是需要经过用户进程进行操作的。所以如何解决两个设置的共存问题。

可以使用ngx_http_gzip_static_module模块的gzip_static指令来解决。

gzip_static指令

gzip_static: 检查与访问资源同名的.gz文件时,response中以gzip相关的header返回.gz文件的内容。

添加上述命令后,会报一个错误,unknown directive"gzip_static"主要的原因是Nginx默认是没有添加ngx_http_gzip_static_module模块。如何来添加?

添加模块到Nginx的实现步骤

(1)查询当前Nginx的配置参数

nginx -V

(2)将nginx安装目录下sbin目录中的nginx二进制文件进行更名

cd /usr/local/nginx/sbin
mv nginx nginxold

(3) 进入Nginx的安装目录

cd /root/nginx/core/nginx-1.16.1

(4)执行make clean清空之前编译的内容

make clean

(5)使用configure来配置参数

./configure --with-http_gzip_static_module

(6)使用make命令进行编译

make

(7) 将objs目录下的nginx二进制执行文件移动到nginx安装目录下的sbin目录中

mv objs/nginx /usr/local/nginx/sbin

(8)执行更新命令

make upgrade

gzip_static测试使用

(1)直接访问http://192.168.200.130/jquery.js


(2)使用gzip命令进行压缩

cd /usr/local/nginx/html
gzip jquery.js

(3)再次访问http://192.168.200.130/jquery.js

静态资源的缓存处理

什么是缓存

缓存(cache),原始意义是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。

什么是web缓存

Web缓存是指一个Web资源(如html页面,图片,js,数据等)存在于Web服务器和客户端(浏览器)之间的副本。缓存会根据进来的请求保存输出内容的副本;当下一个请求来到的时候,如果是相同的URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求。比较常见的就是浏览器会缓存访问过网站的网页,当再次访问这个URL地址的时候,如果网页没有更新,就不会再次下载网页,而是直接使用本地缓存的网页。只有当网站明确标识资源已经更新,浏览器才会再次下载网页

web缓存的种类

客户端缓存
浏览器缓存
服务端缓存
Nginx / Redis / Memcached等

浏览器缓存

是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览.

为什么要用浏览器缓存

成本最低的一种缓存实现
减少网络带宽消耗
降低服务器压力
减少网络延迟,加快页面打开速度

浏览器缓存的执行流程

HTTP协议中和页面缓存相关的字段,我们先来认识下:


(1)用户首次通过浏览器发送请求到服务端获取数据,客户端是没有对应的缓存,所以需要发送request请求来获取数据;
(2)服务端接收到请求后,获取服务端的数据及服务端缓存的允许后,返回200的成功状态码并且在响应头上附上对应资源以及缓存信息;
(3)当用户再次访问相同资源的时候,客户端会在浏览器的缓存目录中查找是否存在响应的缓存文件
(4)如果没有找到对应的缓存文件,则走(2)步
(5)如果有缓存文件,接下来对缓存文件是否过期进行判断,过期的判断标准是(Expires),
(6)如果没有过期,则直接从本地缓存中返回数据进行展示
(7)如果Expires过期,接下来需要判断缓存文件是否发生过变化
(8)判断的标准有两个,一个是ETag(Entity Tag),一个是Last-Modified(9)判断结果是未发生变化,则服务端返回304,直接从缓存文件中获取数据
(10)如果判断是发生了变化,重新从服务端获取数据,并根据缓存协商(服务端所设置的是否需要进行缓存数据的设置)来进行数据缓存。

弱缓存和强缓存的演示

弱缓存

  • 首次通过浏览器发送请求到服务端获取数据

  • 再次发送请求


强缓存

  • 打开一个新的页面再次访问,如下,说明是强缓存

浏览器缓存相关指令

Nginx需要进行缓存相关设置,就需要用到如下的指令

expires指令

expires:该指令用来控制页面缓存的作用。可以通过该指令控制HTTP应答中的“Expires"和”Cache-Control"

time:可以整数也可以是负数,指定过期时间,如果是负数,Cache-Control则为no-cache,如果为整数或0,则Cache-Control的值为max-age=time;

no-cache:不管缓存有没有过期都需要发送请求到服务器判断请求的资源是否发生变化,也就是说走的是弱缓存
max-age和Expires的作用是一样的:Expires是http1.0所出现的配置,但是Expires的值返回的是和服务器相关的一些时间,如果本地客户端的时间和服务器的时间不一致的话,就可能导致达不到需要的需求;在http1.1的时候,就使用了Cache-Control中的max-age来替换Expires的作用,如果这两个都有,它会先以max-age指定的时间来计算缓存是否过期,如果一些浏览器不支持max-age,它就会使用Expires的值来进行判断。

epoch: 指定Expires的值为’1 January,1970,00:00:01 GMT’(1970-01-0100:00:00),Cache-Control的值no-cache

max:指定Expires的值为’31 December2037 23:59:59GMT’ (2037-12-31 23:59:59) ,Cache-Control的值为10年

off:默认不缓存。

演示:
为了方便对比,先看一下之前响应的头信息看一下:

修改配置:

右边是配置后再次请求的响应头信息

如果改成负数

弱缓存

add_header指令

add_header指令是用来添加指定的响应头和响应值。

Cache-Control作为响应头信息,可以设置如下值:
缓存响应指令:


max-age=[秒]

Nginx的跨域问题解决

这块内容,我们主要从以下方面进行解决:

同源策略

浏览器的同源策略:是一种约定,是浏览器最核心也是最基本的安全功能,如果浏览器少了同源策略,则浏览器的正常功能可能都会受到影响。

同源: 协议、域名(IP)、端口相同即为同源

跨域问题

简单描述下:

有两台服务器分别为A,B,如果从服务器A的页面发送异步请求到服务器B获取数据,如果服务器A和服务器B不满足同源策略,则就会出现跨域问题。

跨域问题的案例演示

出现跨域问题会有什么效果?,接下来通过一个需求来给大家演示下:

(1)nginx的html目录下新建一个a.html

<html><head><meta charset="utf-8"><title>跨域问题演示</title><script src="jquery.js"> </script>
<script>$(function(){$("#btn").click(function(){$.get('http://192.168.200.130:8080/getUser',function(data){alert(JSON.stringify(data));});});});</script></head><body><input type="button" value="获取数据" id="btn"/></body>
</html>

(2)在nginx.conf配置如下内容

server {listen       80;server_name  localhost;location / {root   html;index  index.html index.htm;}}server {listen       8080;server_name  localhost;location /getUser {default_type  application/json;return 200 '{"id":1,"name":"TOM","age":18}';}}

(3)通过浏览器访问测试

解决方案

使用add_header指令,该指令可以用来添加一些头信息

此处用来解决跨域问题,需要添加两个头信息,一个是Access-Control-Allow-Origin,Access-Control-Allow-Methods

ccess-Control-Allow-Origin: 直译过来是允许跨域访问的源地址信息,可以配置多个(多个用逗号分隔),也可以使用*代表所有源

Access-Control-Allow-Methods:直译过来是允许跨域访问的请求方式,值可以为 GET POST PUT DELETE…,可以全部设置,也可以根据需要设置,多个用逗号分隔

具体配置方式

静态资源防盗链

什么是资源盗链

资源盗链指的是此内容不在自己服务器上,而是通过技术手段,绕过别人的限制将别人的内容放到自己页面上最终展示给用户。以此来盗取大网站的空间和流量。简而言之就是用别人的东西成就自己的网站。

效果演示
东:https://img14.360buyimg.com/n7/jfs/t1/101062/37/2153/254169/5dcbd410E6d10ba22/4ddbd212be225fcd.jpg

度:https://pics7.baidu.com/feed/cf1b9d16fdfaaf516f7e2011a7cda1e8f11f7a1a.jpeg?token=551979a23a0995e5e5279b8fa1a48b34&s=BD385394D2E963072FD48543030030BB


我们自己准备一个页面,在页面上引入这两个图片查看效果

<html><head><meta charset="utf-8"><title>跨域问题演示</title><script src="jquery.js"> </script>
<script>$(function(){$("#btn").click(function(){$.get('http://192.168.200.130:8080/getUser',function(data){alert(JSON.stringify(data));});});});</script></head><body><input type="button" value="获取数据" id="btn"/><img src="https://img14.360buyimg.com/n7/jfs/t1/101062/37/2153/254169/5dcbd410E6d10ba22/4ddbd212be225fcd.jpg"/><br/><img src="https://pics7.baidu.com/feed/cf1b9d16fdfaaf516f7e2011a7cda1e8f11f7a1a.jpeg?token=551979a23a0995e5e5279b8fa1a48b34&s=BD385394D2E963072FD48543030030BB"/></body>
</html>


从上面的效果,可以看出来,下面的图片地址添加了防止盗链的功能,京东这边我们可以直接使用其图片。

Nginx防盗链的实现原理:

了解防盗链的原理之前,我们得先学习一个HTTP的头信息Referer,当浏览器向web服务器发送请求的时候,一般都会带上Referer,来告诉浏览器该网页是从哪个页面链接过来的。


后台服务器可以根据获取到的这个Referer信息来判断是否为自己信任的网站地址,如果是则放行继续访问,如果不是则可以返回403(服务端拒绝访问)的状态信息。

在本地模拟上述的服务器效果:

Nginx防盗链的具体实现:
valid_referers:nginx会通就过查看referer自动和valid_referers后面的内容进行匹配,如果匹配到了就将$invalid_referer变量置0,如果没有匹配到,则将$invalid_referer变量置为1,匹配的过程中不区分大小写。


none: 如果Header中的Referer为空,允许访问
blocked:在Header中的Referer不为空,但是该值被防火墙或代理进行伪装过,如不带"http://" 、"https://"等协议头的资源允许访问。
server_names:指定具体的域名或者IP
string: 可以支持正则表达式和*的字符串。如果是正则表达式,需要以~开头表示,例如

遇到的问题:图片有很多,该如何批量进行防盗链?

针对目录进行防盗链

配置如下:

这样我们可以对一个目录下的所有资源进行翻到了操作。

遇到的问题:Referer的限制比较粗,比如随意加一个Referer,上面的方式是无法进行限制的。那么这个问题改如何解决?

此处我们需要用到Nginx的第三方模块ngx_http_accesskey_module,第三方模块如何实现盗链,如果在Nginx中使用第三方模块的功能,这些我们在后面的Nginx的模块篇再进行详细的讲解。

Rewrite功能配置

Rewrite是Nginx服务器提供的一个重要基本功能,是Web服务器产品中几乎必备的功能。主要的作用是用来实现URL的重写。

注意:Nginx服务器的Rewrite功能的实现依赖于PCRE的支持,因此在编译安装Nginx服务器之前,需要安装PCRE库。Nginx使用的是ngx_http_rewrite_module模块来解析和处理Rewrite功能的相关配置。

“地址重写"与"地址转发”

重写和转发的区别:

Rewrite规则

set指令

该指令用来设置一个新的变量。

variable:变量的名称,该变量名称要用"$"作为变量的第一个字符,且不能与Nginx服务器预设的全局变量同名。

value:变量的值,可以是字符串、其他变量或者变量的组合等。

Rewrite常用全局变量




上述参数还可以在日志文件中使用,这个就要用到前面我们介绍的log_format指令

上述参数还可以在日志文件中使用,这个就要用到前面我们介绍的log_format指令:

logformat main '$remoteaddr - $request - $status-$request_uri $httpuseragent';
access_log logs/access.log main;


if指令

该指令用来支持条件判断,并根据条件判断结果选择不同的Nginx配置。

condition为判定条件,可以支持以下写法:
1、变量名。如果变量名对应的值为空或者是0,if都判断为false,其他条件为true。

2、使用"=“和”!="比较变量和字符串是否相等,满足条件为true,不满足为false

注意:此处和Java不太一样的地方是字符串不需要添加引号。


注意:正则表达式字符串一般不需要加引号,但是如果字符串中包含"}“或者是”;"等字符时,就需要把引号加上。



break指令

该指令用于中断当前相同作用域中的其他Nginx配置。与该指令处于同一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指令配置无效。并且break还有另外一个功能就是终止当前的匹配并把当前的URI在本location进行重定向访问处理。

location /testbreak{
default_type text/plain;set $username TOM; if ($args){ set $username JERRY;break;set $username ROSE;} add_header username $username;return 200 $username;
}

return指令

该指令用于完成对请求的处理,直接向客户端返回响应状态代码。在return后的所有Nginx配置都是无效的。

code:为返回给客户端的HTTP状态代理。可以返回的状态代码为0~999的任意HTTP状态代理

text:为返回给客户端的响应体内容,支持变量的使用

URL:为返回给客户端的URL地址

location /testreturn {
return 200 success;
}
location /testreturn {
return https://www.baidu.com; // 302重定向到百度
}
location /testreturn {return 302 https://www.baidu.com;}
location /testreturn {return 302 www.baidu.com;//不允许这么写}

301永久重定向
302临时重定向

rewrite指令

该指令通过正则表达式的使用来改变URI。可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理。

regex:用来匹配URI的正则表达式

replacement:匹配成功后,用于替换URI中被截取内容的字符串。如果该字符串是以"http://"或者"https://"开头的,则不会继续向下对URI进行其他处理,而是直接返回重写后的URI给客户端。

flag:用来设置rewrite对URI的处理行为,可选值有如下:

  • last:终止继续在本location块中处理接收到的URI,并将此处重写的URI作为一个新的URI,使用各location块进行处理。该标志将重写后的URI重写在server块中执行,为重写后的URI提供了转入到其他location块的机会
location rewrite {rewrite ^/rewrite/(test)\w*$ /$1 last; rewrite ^/rewrite/(demo)\w*$ /$1 last;} location /test{ default_type text/plain;return 200 test_success;}location /demo{default_type text/plain;return 200 demo_success;
}

访问 http://192.168.200.133:8081/rewrite/testabc,能正确访问

  • break:将此处重写的URI作为一个新的URI,在本块中继续进行处理。该标志将重写后的地址在当前的location块中执行,不会将新的URI转向其他的location块。
location rewrite {
#/test /usr/local/nginx/html/test/index.html rewrite ^/rewrite/(test)\w*$ /$1 break; rewrite ^/rewrite/(demo)\w*$ /$1 break;
}
location /test{
default_type text/plain;
return 200 test_success;
}
location /demo{
default_type text/plain;
return 200 demo_success;
}

访问 http://192.168.200.133:8081/rewrite/demoabc,页面报404错误

  • redirect:将重写后的URI返回给客户端,状态码为302,指明是临时重定向URI,主要用在replacement变量不是以"http://"或者"https://"开头的情况。
location rewrite {
rewrite ^/rewrite/(test)\w*$ /$1 redirect;
rewrite ^/rewrite/(demo)\w*$ /$1 redirect;
}
location /test{
default_type text/plain;
return 200 test_success;
}
location /demo{
default_type text/plain;
return 200 demo_success;
}

访问http://192.168.200.133:8081/rewrite/testabc请求会被临时重定向,浏览器地址也会发生改变

  • permanent:将重写后的URI返回给客户端,状态码为301,指明是永久重定向URI,主要用在replacement变量不是以"http://"或者"https://"开头的情况。
location rewrite {
rewrite ^/rewrite/(test)\w*$ /$1 permanent;
rewrite ^/rewrite/(demo)\w*$ /$1 permanent;
}
location /test{
default_type text/plain;
return 200 test_success;
}
location /demo{
default_type text/plain;
return 200 demo_success;
}

访问http://192.168.200.133:8081/rewrite/testabc请求会被永久重定向,浏览器地址也会发生改变

rewrite_log指令

该指令配置是否开启URL重写日志的输出功能。

开启后,URL重写的相关日志将以notice级别输出到error_log指令配置的日志文件汇总。

rewrite_log on;
error_log logs/error.log notice;

Rewrite的案例

域名跳转

问题分析

先来看一个效果,如果我们想访问京东网站,大家都知道我们可以输入www.jd.com,但是同样的我们也可以输入www.360buy.com同样也都能访问到京东网站。这个其实是因为京东刚开始的时候域名就是www.360buy.com,后面由于各种原因把自己的域名换成了www.jd.com, 虽然说域名变量,但是对于以前只记住了www.360buy.com的用户来说,我们如何把这部分用户也迁移到我们新域名的访问上来,针对于这个问题,我们就可以使用Nginx中Rewrite的域名跳转来解决。

环境准备

  • 准备三个域名:
vim /etc/hosts
127.0.0.1 www.itcast.cn127.0.0.1 www.itheima.cn 127.0.0.1 www.itheima.com
  • 通过Nginx实现访问www.itcast.cn
server {listen 80;server_name www.itcast.cn;location /{ default_type text/html; return 200 '<h1>welcome to itcast</h1>'; } }

通过Rewrite完成将www.ithema.com和www.itheima.cn的请求跳转到www.itcast.com

server {listen 80;server_name www.itheima.com www.itheima.cn; rewrite ^/ http://www.itcast.cn; }

问题描述:如何在域名跳转的过程中携带请求的URI?

修改配置信息

server {
listen 80;server_name www.itheima.com www.itheima.cn; rewrite ^(.*) http://www.itcast.cn$1;}

域名镜像

镜像网站指定是将一个完全相同的网站分别放置到几台服务器上,并分别使用独立的URL进行访问。其中一台服务器上的网站叫主站,其他的为镜像网站。镜像网站和主站没有太大的区别,可以把镜像网站理解为主站的一个备份节点。可以通过镜像网站提供网站在不同地区的响应速度。镜像网站可以平衡网站的流量负载、可以解决网络宽带限制、封锁等。

而我们所说的域名镜像和网站镜像比较类似,上述案例中,将www.itheima.com和 www.itheima.cn都能跳转到www.itcast.cn,那么www.itcast.cn我们就可以把它起名叫主域名,其他两个就是我们所说的镜像域名,当然如果我们不想把整个网站做镜像,只想为其中某一个子目录下的资源做镜像,我们可以在location块中配置rewrite功能,比如:

server {listen 80;servername www.itheima.cn www.itheima.com; location /user { rewrite ^/user(.*)$  http://www.itcast.cn$1; } location /emp{defaulttype text/html; return 200 'emp_success';}}

独立域名

一个完整的项目包含多个模块,比如购物网站有商品商品搜索模块、商品详情模块已经购物车模块等,那么我们如何为每一个模块设置独立的域名。

需求:


目录自动添加"/"

问题描述

通过一个例子来演示下问题:


要想访问上述资源,很简单,只需要通过http://192.168.200.133直接就能访问,地址后面不需要加/,但是如果将上述的配置修改为如下内容:


这个时候,要想访问上述资源,按照上述的访问方式,我们可以通过http://192.168.200.133/hm/来访问,但是如果地址后面不加斜杠,页面就会出问题。如果不加斜杠,Nginx服务器内部会自动做一个301的重定向,重定向的地址会有一个指令叫server_name_in_redirect on|off;来决定重定向的地址:


所以就拿刚才的地址来说,http://192.168.200.133/hm如果不加斜杠,那么按照上述规则,如果指令server_name_in_redirect为on,则301重定向地址变为 http://localhost/hm/,如果为off,则301重定向地址变为http://192.168.200.133/ht/。后面这个是正常的,前面地址就有问题。

注意server_name_in_redirect指令在Nginx的0.8.48版本之前默认都是on,之后改成了off,所以现在我们这个版本不需要考虑这个问题,但是如果是0.8.48以前的版本并且server_name_in_redirect设置为on,我们如何通过rewrite来解决这个问题?

解决方案

我们可以使用rewrite功能为末尾没有斜杠的URL自动添加一个斜杠

合并目录

搜索引擎优化(SEO)是一种利用搜索引擎的搜索规则来提供目的网站的有关搜索引擎内排名的方式。我们在创建自己的站点时,可以通过很多中方式来有效的提供搜索引擎优化的程度。其中有一项就包含URL的目录层级一般不要超过三层,否则的话不利于搜索引擎的搜索也给客户端的输入带来了负担,但是将所有的文件放在一个目录下又会导致文件资源管理混乱并且访问文件的速度也会随着文件增多而慢下来,这两个问题是相互矛盾的,那么使用rewrite如何解决上述问题?

举例,网站中有一个资源文件的访问路径时 /server/11/22/33/44/20.html,也就是说20.html存在于第5级目录下,如果想要访问该资源文件,客户端的URL地址就要写成 http://192.168.200.133/server/11/22/33/44/20.html,

但是这个是非常不利于SEO搜索引擎优化的,同时客户端也不好记.使用rewrite我们可以进行如下配置:

这样的话,客户端只需要输入http://www.web.name/server-11-22-33-44-20.html就可以访问到20.html页面了。这里也充分利用了rewrite指令支持正则表达式的特性。

防盗链

防盗链之前我们已经介绍过了相关的知识,在rewrite中的防盗链和之前将的原理其实都是一样的,只不过通过rewrite可以将防盗链的功能进行完善下,当出现防盗链的情况,我们可以使用rewrite将请求转发到自定义的一张图片和页面,给用户比较好的提示信息。下面我们就通过根据

Nginx学习笔记——上篇相关推荐

  1. nginx 学习笔记(2) nginx新手入门

    这篇手册简单介绍了nginx,并提供了一些可以操作的简单的工作.前提是nginx已经被安装到你的服务器上.如果没有安装,请阅读上篇:nginx 学习笔记(1) nginx安装.这篇手册主要内容:1. ...

  2. Nginx学习笔记09——URLRewrite伪静态

    URLRewrite 伪静态配置 因为jsp获取url参数很方便,所以需要将tomcat服务器上的index.html转为jsp格式的,方式是在html文件开头加上<%@ page conten ...

  3. nginx学习笔记-01nginx入门,环境搭建,常见命令

    nginx学习笔记-01nginx入门,环境搭建,常见命令 文章目录 nginx学习笔记-01nginx入门,环境搭建,常见命令 1.nginx的基本概念 2.nginx的安装,常用命令和配置文件 3 ...

  4. Nginx学习笔记3:Shell脚本检测Nginx服务状态

    前言 nginx 服务启动后,我们需要对其服务状态进行监控,今天学习过程中了解到一段非常有用的小脚本,不仅可以监控Nginx,也可以用来监控其他服务 脚本 A=`ps -C nginx –no-hea ...

  5. 【005】Nginx学习笔记-Nginx真实IP

    [005]Nginx学习笔记-Nginx真实IP 真实IP 客户端真实IP 深入理解真实IP 实验一 实验二: 多个代理服务器的情况 实验三:利用realip模块获取客户端真实IP 实验四:伪装请求头 ...

  6. 全是精髓!也许是最完美的“Nginx学习笔记”了,阿里云高工“365”天手写!

    前言 "Nginx",一个高性能的HTTP和反向代理web服务器,Nginx因为内存少.并发能力强的特性,深受虚拟机主机提供商的欢迎,可以支持高达50000个并发连接数的响应.Ng ...

  7. Nginx 学习笔记

    Nginx 学习笔记 文章目录 Nginx 学习笔记 1.Nginx 的简介 1.1正向代理 1.2反向代理 1.3负载均衡 1.4动静分离 1.5Nginx的安装 1.6Nginx的常用命令 1.7 ...

  8. 本科操作系统学习笔记(上篇)

    更新内容 由于这边四万字了太难维护(每次打开都挺卡的),所以决定分上下篇更新,这篇就是上篇了,下篇下周前发出来--2021.11.16 文章目录 更新内容 前言 计组和操作系统杂谈 概览 指令执行的过 ...

  9. Nginx学习笔记(三) Nginx基本数据结构

    话说学习一种编程语言,例如C语言,我们首先学的也是数据结构,这是以后开发程序的关键.为了更好更方便的开发Nginx,Nginx自己实现了很多适合nginx的数据结构. Nginx中的数组 ngx_ar ...

最新文章

  1. 排序算法-------堆排序
  2. centos7 mysql安装配置_mysql 5.7.17 安装配置方法图文教程(CentOS7)
  3. anaconda 安装tensorfollow 镜像_手把手教新手安装Anaconda配置开发环境
  4. Value 'EN' violates facet information 'maxlength=1'
  5. 微软100题第20题
  6. 数据库管理之数据表管理(1)
  7. mysql数据库和表的关系_MySQL数据库学习【第六篇】表与表之间的关系
  8. 解决fabric编译失败(make: *** [release/linux-amd64/bin/configtxgen] Error 1)
  9. solr获取同义词 java_如何在使用缩写及其全名搜索时使solr同义词获取相同的结果(相同的数字和顺序)...
  10. 罗技鼠标键盘没法使用,可以尝试安装此驱动
  11. 【天光学术】休闲体育论文:中小学学生羽毛球运动员心理训练方法研究
  12. 词干提取(stemming)和词形还原(lemmatization)
  13. matlab插图放大模糊,PPT中怎样简单处理放大后失真的图片
  14. java报错establishing_[Microsoft][SQLServer 2000 Driver for JDBC]Error establishing socket错误解决方法总结...
  15. 依图科技从科创板“退赛”:三年半累计亏损72亿,研发费用高企
  16. JavaScript 和读取服务器cookie
  17. 如何将excel三列数据合为一列日期数据
  18. 计算机打开页面恢复默认大小,win10怎样恢复Windows窗口默认的大小?
  19. 2021年安全员-B证(江西省)新版试题及安全员-B证(江西省)考试技巧
  20. shader学习之路——更复杂的光照之Base Pass 和 Additional Pass和光照的衰减

热门文章

  1. Games101:作业6解析(含提高部分SAH)
  2. Java库和框架之间到底有什么区别?
  3. 2----Android手机小白知识全集!! 刚入手
  4. Word在试图打开文件时遇到错误请尝试下列方法 *检查文档或驱动器的文件权限*确保有足够的内存和磁盘空间,...
  5. Java基础练习(十二)集合与数组工具类使用,BigDecimal使用,实现二分查找,快速排序
  6. 《STL》— UVa10815 Andy's First Dictionary
  7. 响应式久草编程基础教程:久草Spring Boot 与 Lettuce 在线整合
  8. NBA历史上最长的连胜和连败纪录!
  9. 开发者自己搭建IM服务器所要面临的问题
  10. python中的汉字编码(转载,已经注明转载地址)