<font style="color:rgb(55, 53, 47);">01、Nginx 的介绍</font>
<font style="color:rgb(55, 53, 47);">Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器</font>
<font style="color:rgb(55, 53, 47);">Nginx 支持热部署,几乎能做到 7*24 小时不间断运行,即使运行几个月也不需要重启,还能在不间断服务的情况下对软件进行热更新。</font>
<font style="color:rgb(55, 53, 47);">Nginx 最重要的考量是 性能 ,其占用内存少、并发能力强、能支持高达 5w 个并发连接数</font>
<font style="color:rgb(55, 53, 47);">Nginx 是免费的并可以商业化,配置使用也比较简单。</font>
<font style="color:rgb(55, 53, 47);">Nginx 的最重要的几个使用场景:</font>
- <font style="color:rgb(55, 53, 47);">静态资源服务,通过本地文件系统提供服务(就是作为静态页面的服务器);</font>
- <font style="color:rgb(55, 53, 47);">反向代理服务,延伸出包括缓存、负载均衡等;</font>
- <font style="color:rgb(55, 53, 47);">API 服务,OpenResty ;</font>
<font style="color:rgb(55, 53, 47);">02、简单和非简单请求</font>
<font style="color:rgb(55, 53, 47);">如果同时满足下面两个条件,就属于简单请求,凡是不同时满足这两个条件的,都属于非简单请求</font>
- <font style="color:rgb(55, 53, 47);">请求方法是 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">HEAD</font><font style="color:rgb(55, 53, 47);">、</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">GET</font><font style="color:rgb(55, 53, 47);">、</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">POST</font><font style="color:rgb(55, 53, 47);"> 三种之一;</font>
- <font style="color:rgb(55, 53, 47);">HTTP 头信息不超过右边这几个字段:</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Accept</font><font style="color:rgb(55, 53, 47);">、</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Accept-Language</font><font style="color:rgb(55, 53, 47);">、</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Content-Language</font><font style="color:rgb(55, 53, 47);">、</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Last-Event-ID</font><font style="color:rgb(55, 53, 47);"> 、</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Content-Type</font><font style="color:rgb(55, 53, 47);"> 只限于三个值 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">application/x-www-form-urlencoded</font><font style="color:rgb(55, 53, 47);">、</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">multipart/form-data</font><font style="color:rgb(55, 53, 47);">、</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">text/plain</font><font style="color:rgb(55, 53, 47);">;</font>
<font style="color:rgb(55, 53, 47);">浏览器处理简单请求和非简单请求的方式不一样</font>
- <font style="color:rgb(55, 53, 47);">简单请求</font>
<font style="color:rgb(55, 53, 47);">对于简单请求,浏览器会在头信息中增加 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Origin</font><font style="color:rgb(55, 53, 47);"> 字段后直接发出,</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Origin</font><font style="color:rgb(55, 53, 47);"> 字段用来说明,本次请求来自的哪个源(协议+域名+端口)。</font>
<font style="color:rgb(55, 53, 47);">如果服务器发现 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Origin</font><font style="color:rgb(55, 53, 47);"> 指定的源不在许可范围内,服务器会返回一个正常的 HTTP 回应,浏览器取到回应之后发现回应的头信息中没有包含 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Access-Control-Allow-Origin</font><font style="color:rgb(55, 53, 47);"> 字段,就抛出一个错误给 XHR 的 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">error</font><font style="color:rgb(55, 53, 47);"> 事件;</font>
<font style="color:rgb(55, 53, 47);">如果服务器发现 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Origin</font><font style="color:rgb(55, 53, 47);"> 指定的域名在许可范围内,服务器返回的响应会多出几个 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Access-Control-</font><font style="color:rgb(55, 53, 47);"> 开头的头信息字段。</font>
- <font style="color:rgb(55, 53, 47);">非简单请求</font>
<font style="color:rgb(55, 53, 47);">非简单请求是那种对服务器有特殊要求的请求,比如请求方法是 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">PUT</font><font style="color:rgb(55, 53, 47);"> 或 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">DELETE</font><font style="color:rgb(55, 53, 47);">,或 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">Content-Type</font><font style="color:rgb(55, 53, 47);"> 值为 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">application/json</font><font style="color:rgb(55, 53, 47);">。浏览器会在正式通信之前,发送一次 HTTP 预检 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">OPTIONS</font><font style="color:rgb(55, 53, 47);"> 请求,先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 请求方法和头信息字段。只有得到肯定答复,浏览器才会发出正式的 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">XHR</font><font style="color:rgb(55, 53, 47);"> 请求,否则报错。</font>
<font style="color:rgb(55, 53, 47);">03、跨域</font>
<font style="color:rgb(55, 53, 47);">在浏览器上当前访问的网站向另一个网站发送请求获取数据的过程就是</font><font style="color:rgb(55, 53, 47);">跨域请求</font><font style="color:rgb(55, 53, 47);">。</font>
<font style="color:rgb(55, 53, 47);">跨域是浏览器的</font>同源策略<font style="color:rgb(55, 53, 47);">决定的,是一个重要的浏览器安全策略,用于限制一个 </font>origin<font style="color:rgb(55, 53, 47);"> 的文档或者它加载的脚本与另一个源的资源进行交互,它能够帮助阻隔恶意文档,减少可能被攻击的媒介,可以使用 </font>CORS<font style="color:rgb(55, 53, 47);"> 配置解除这个限制。</font>
<font style="color:rgb(55, 53, 47);">关于跨域网上已经有很多解释,这里就不啰嗦,也可以直接看 MDN 的 </font><浏览器的同源策略><font style="color:rgb(55, 53, 47);"> 文档进一步了解,这里就列举几个同源和不同元的例子,相信程序员都能看得懂。</font>
plain
| 1 | # 同源的例子 |
| 2 | http://example.com/app1/index.html # 只是路径不同 |
| 3 | http://example.com/app2/index.html |
| 4 | |
| 5 | http://Example.com:80 # 只是大小写差异 |
| 6 | http://example.com |
| 7 | |
| 8 | # 不同源的例子 |
| 9 | http://example.com/app1 # 协议不同 |
| 10 | https://example.com/app2 |
| 11 | |
| 12 | http://example.com # host 不同 |
| 13 | http://www.example.com |
| 14 | http://myapp.example.com |
| 15 | |
| 16 | http://example.com # 端口不同 |
| 17 | http://example.com:8080 |
<font style="color:rgb(55, 53, 47);">04、正向代理和反向代理</font>
<font style="color:rgb(55, 53, 47);">反向代理(Reverse Proxy)对应的是正向代理(Forward Proxy),他们的区别:</font>
<font style="color:rgb(55, 53, 47);">正向代理:</font><font style="color:rgb(55, 53, 47);"> 一般的访问流程是客户端直接向目标服务器发送请求并获取内容,使用正向代理后,客户端改为向代理服务器发送请求,并指定目标服务器(原始服务器),然后由代理服务器和原始服务器通信,转交请求并获得的内容,再返回给客户端。正向代理隐藏了真实的客户端,为客户端收发请求,使真实客户端对服务器不可见;</font>
<font style="color:rgb(55, 53, 47);">举个具体的例子 </font><font style="color:rgb(55, 53, 47);">🌰</font><font style="color:rgb(55, 53, 47);">,你的浏览器无法直接访问谷哥,这时候可以通过一个代理服务器来帮助你访问谷哥,那么这个服务器就叫正向代理。</font>
<font style="color:rgb(55, 53, 47);">反向代理:</font><font style="color:rgb(55, 53, 47);"> 与一般访问流程相比,使用反向代理后,直接收到请求的服务器是代理服务器,然后将请求转发给内部网络上真正进行处理的服务器,得到的结果返回给客户端。反向代理隐藏了真实的服务器,为服务器收发请求,使真实服务器对客户端不可见。一般在处理跨域请求的时候比较常用。现在基本上所有的大型网站都设置了反向代理。</font>
<font style="color:rgb(55, 53, 47);">举个具体的例子 </font><font style="color:rgb(55, 53, 47);">🌰</font><font style="color:rgb(55, 53, 47);">,去饭店吃饭,可以点川菜、粤菜、江浙菜,饭店也分别有三个菜系的厨师 </font><font style="color:rgb(55, 53, 47);">👨🍳</font><font style="color:rgb(55, 53, 47);">,但是你作为顾客不用管哪个厨师给你做的菜,只用点菜即可,小二将你菜单中的菜分配给不同的厨师来具体处理,那么这个小二就是反向代理服务器。</font>
<font style="color:rgb(55, 53, 47);">简单的说,一般给客户端做代理的都是正向代理,给服务器做代理的就是反向代理。</font>
<font style="color:rgb(55, 53, 47);">正向代理和反向代理主要的原理区别可以参见下图:</font>
<!-- 这是一张图片,ocr 内容为: -->


<font style="color:rgb(55, 53, 47);">05、负载均衡</font>
<font style="color:rgb(55, 53, 47);">一般情况下,客户端发送多个请求到服务器,服务器处理请求,其中一部分可能要操作一些资源比如数据库、静态资源等,服务器处理完毕后,再将结果返回给客户端。</font>
<font style="color:rgb(55, 53, 47);">这种模式对于早期的系统来说,功能要求不复杂,且并发请求相对较少的情况下还能胜任,成本也低。随着信息数量不断增长,访问量和数据量飞速增长,以及系统业务复杂度持续增加,这种做法已无法满足要求,并发量特别大时,服务器容易崩。</font>
<font style="color:rgb(55, 53, 47);">很明显这是由于服务器性能的瓶颈造成的问题,除了堆机器之外,最重要的做法就是负载均衡。</font>
<font style="color:rgb(55, 53, 47);">请求爆发式增长的情况下,单个机器性能再强劲也无法满足要求了,这个时候集群的概念产生了,单个服务器解决不了的问题,可以使用多个服务器,然后将请求分发到各个服务器上,将负载分发到不同的服务器,这就是</font><font style="color:rgb(55, 53, 47);">负载均衡</font><font style="color:rgb(55, 53, 47);">,核心是「分摊压力」。</font>
<font style="color:rgb(55, 53, 47);">⭐</font><font style="color:rgb(55, 53, 47);">️</font><font style="color:rgb(55, 53, 47);"> Nginx 实现负载均衡,一般来说指的是将请求转发给服务器集群。</font>
<font style="color:rgb(55, 53, 47);">🌰</font><font style="color:rgb(55, 53, 47);"> 举个具体的例子,晚高峰乘坐地铁的时候,入站口经常会有地铁工作人员大喇叭“请走 B 口,B 口人少车空....”,这个工作人员的作用就是负载均衡。</font>
<!-- 这是一张图片,ocr 内容为: -->

<font style="color:rgb(55, 53, 47);">06、动静分离</font>
<font style="color:rgb(55, 53, 47);">为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力。</font>
<!-- 这是一张图片,ocr 内容为: -->

<font style="color:rgb(55, 53, 47);">一般来说,都需要将动态资源和静态资源分开,由于 Nginx 的高并发和静态资源缓存等特性,经常将静态资源部署在 Nginx 上。</font><font style="color:rgb(55, 53, 47);">如果请求的是静态资源,直接到静态资源目录获取资源,如果是动态资源的请求,则利用反向代理的原理</font><font style="color:rgb(55, 53, 47);">,把请求转发给对应后台应用去处理,从而实现动静分离。</font>
<font style="color:rgb(55, 53, 47);">使用前后端分离后,可以很大程度提升静态资源的访问速度,即使动态服务不可用,静态资源的访问也不会受到影响。</font>
<font style="color:rgb(55, 53, 47);">07、Nginx 的安装</font>
<font style="color:rgb(55, 53, 47);">1、到官网下载安装包:</font>http://nginx.org/<font style="color:rgb(55, 53, 47);"> nginx-1.12.2.tar.gz (centos8 安装1.12版本并不可以,可以试试更高版本,比如1.17.6)</font>
<font style="color:rgb(55, 53, 47);">2、下载所需依赖包:pcre-8.37.tar.gz</font><font style="color:rgb(55, 53, 47);"> </font><font style="color:rgb(55, 53, 47);">openssl-1.0.1t.tar.gz</font><font style="color:rgb(55, 53, 47);"> </font><font style="color:rgb(55, 53, 47);">zlib-1.2.8.tar.gz</font>
<font style="color:rgb(55, 53, 47);">3、离线安装 nginx:</font>
- <font style="color:rgb(55, 53, 47);">解压缩 pcre-xx.tar.gz 包</font>
<font style="color:rgb(55, 53, 47);">进入解压缩目录,执行 ./configure</font>
<font style="color:rgb(55, 53, 47);">注意:如果提示错误,需要提前安装 gcc++:</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">yum install -y gcc-c++</font>
<font style="color:rgb(55, 53, 47);">./configure 完成后,回到pcre目录下执行make,再执行make install</font>
- <font style="color:rgb(55, 53, 47);">解压缩 openssl-xx.tar.gz 包</font>
<font style="color:rgb(55, 53, 47);">进入解压缩目录,执行 ./config </font>
<font style="color:rgb(55, 53, 47);">make && make install</font>
- <font style="color:rgb(55, 53, 47);">解压缩 zlib-xx.tar.gz 包</font>
<font style="color:rgb(55, 53, 47);">进入解压缩目录,执行./configure</font>
<font style="color:rgb(55, 53, 47);">make && make install</font>
- <font style="color:rgb(55, 53, 47);">解压缩 nginx-xx.tar.gz 包 </font>
<font style="color:rgb(55, 53, 47);">进入解压缩目录,执行 ./configure </font>
<font style="color:rgb(55, 53, 47);">make && make install</font>
<font style="color:rgb(55, 53, 47);">4、关闭防火墙,访问nginx</font>
- <font style="color:rgb(55, 53, 47);">在windows系统中访问linux中nginx,默认不能访问的,因为防火墙问题</font>
- <font style="color:rgb(55, 53, 47);">关闭防火墙-开放访问的端口号,</font><font style="color:rgb(55, 53, 47);">80</font><font style="color:rgb(55, 53, 47);">端口</font>
- <font style="color:rgb(55, 53, 47);">查看开放的端口号</font>
<font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">firewall-cmd --list-all</font>
- <font style="color:rgb(55, 53, 47);">开启防火墙</font>
<font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">systemctl start firewalld</font>
- <font style="color:rgb(55, 53, 47);">关闭防火墙</font>
<font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">systemctl stop firewalld</font>
- <font style="color:rgb(55, 53, 47);">设置开放的服务或端口号</font>
<font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">firewall-cmd --add-service=http --permanent</font>
<font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">firewall-cmd --add-port=80/tcp --permanent</font>
- <font style="color:rgb(55, 53, 47);">重启防火墙:</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">firewall-cmd --reload</font>
<font style="color:rgb(55, 53, 47);">5、扩展:在线安装</font>
- <font style="color:rgb(55, 53, 47);">第 1.0 步 安装openssl、zlib、gcc 依赖 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel</font>
- <font style="color:rgb(55, 53, 47);">第 2.1 步 联网下载pcre </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">wget http://downloads.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz</font>
- <font style="color:rgb(55, 53, 47);">第 2.2 步 解压压缩文件 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">tar -zxvf pcre-8.37.tar.gz</font>
- <font style="color:rgb(55, 53, 47);">第 2.3 步 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">./configure</font><font style="color:rgb(55, 53, 47);"> 完成后,回到pcre目录下执行 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">make</font><font style="color:rgb(55, 53, 47);">,最后执行 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">make install</font>
- <font style="color:rgb(55, 53, 47);">第 2.4 步 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">pcre-config --version</font><font style="color:rgb(55, 53, 47);"> 检查版本</font>
- <font style="color:rgb(55, 53, 47);">第 3.0 步,安装nginx,使用命令解压 然后进入解压缩目录,执行 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">./configure</font><font style="color:rgb(55, 53, 47);"> 然后 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">make</font><font style="color:rgb(55, 53, 47);"> && </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">make install</font>
- <font style="color:rgb(55, 53, 47);">进入目录 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">/usr/local/nginx/sbin</font><font style="color:rgb(55, 53, 47);"> 执行 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">./nginx</font><font style="color:rgb(55, 53, 47);"> 启动服务</font>
- <font style="color:rgb(55, 53, 47);">第 4.0 步,关闭防火墙,访问nginx</font>
<font style="color:rgb(55, 53, 47);">08、Nginx 相关命令</font>
<font style="color:rgb(55, 53, 47);">我们需要去相关目录下执行命令,下面我们一个命令直接到了相应目录并执行 nginx 相关操作</font>
plain
| 1 | # nginx版本检查 |
| 2 | nginx -v |
| 3 | |
| 4 | # nginx编译参数 |
| 5 | nginx -V |
| 6 | |
| 7 | # 启停方式 |
| 8 | - 启动 |
| 9 | [root@zls ~]# /usr/local/nginx/sbin/nginx |
| 10 | [root@zls ~]# systemctl start nginx |
| 11 | - 停止 |
| 12 | [root@zls ~]# /usr/local/nginx/sbin/nginx -s stop |
| 13 | [root@zls ~]# systemctl stop nginx |
| 14 | - 重启 |
| 15 | [root@zls ~]# systemctl restart nginx |
| 16 | - 重载 |
| 17 | [root@zls ~]# /usr/local/nginx/sbin/nginx -s reload |
| 18 | [root@zls ~]# systemctl reload nginx |
<font style="color:rgb(55, 53, 47);">上述 --- 使用 systemctl start nginx 来启动 nginx 是需要配置的,下面我们来创建并配置 nginx.service 文件</font>
<font style="color:rgb(55, 53, 47);">Systemd服务文件以.service结尾,比如现在要建立nginx为开机启动,如果用yum install命令安装的,yum命令会自动创建nginx.service文件,可以直接使用systemctl相关命令。而用源码编译安装的,则需要手动创建nginx.service服务文件。</font>
<font style="color:rgb(55, 53, 47);">配置nginx.service文件</font>
<font style="color:rgb(55, 53, 47);">vim /usr/lib/systemd/system/nginx.service</font>
plain
| 1 | #配置文件内容 |
| 2 | [Unit] |
| 3 | Description=nginx |
| 4 | After=network.target |
| 5 | |
| 6 | [Service] |
| 7 | Type=forking |
| 8 | ExecStart=/usr/local/nginx/sbin/nginx |
| 9 | ExecReload=/usr/local/nginx/sbin/nginx -s reload |
| 10 | ExecStop=/usr/local/nginx/sbin/nginx -s quit |
| 11 | PrivateTmp=true |
| 12 | |
| 13 | [Install] |
| 14 | WantedBy=multi-user.target |
| 15 | |
| 16 | #[Unit]:服务的说明 |
| 17 | #Description:描述服务 |
| 18 | #After:描述服务类别 |
| 19 | #[Service]服务运行参数的设置 |
| 20 | #Type=forking是后台运行的形式 |
| 21 | #ExecStart为服务的具体运行命令 |
| 22 | #ExecReload为重启命令 |
| 23 | #ExecStop为停止命令 |
| 24 | #PrivateTmp=True表示给服务分配独立的临时空间 |
| 25 | #注意:[Service]的启动、重启、停止命令全部要求使用绝对路径 |
| 26 | #[Install]运行级别下服务安装的相关设置,可设置为多用户,即系统运行级别为3 |
plain
| 1 | #查看nginx服务状态 |
| 2 | systemctl status nginx.service |
| 3 | #启动nginx服务 |
| 4 | systemctl start nginx.service |
| 5 | #停止nginx服务 |
| 6 | systemctl stop nginx.service |
| 7 | #重启nginx服务 |
| 8 | systemctl restart nginx.service |
| 9 | #重新读取nginx配置(这个最常用, 不用停止nginx服务就能使修改的配置生效) |
| 10 | systemctl reload nginx.service |
<font style="color:rgb(55, 53, 47);">09、Nginx 配置语法</font>
<font style="color:rgb(55, 53, 47);">Nginx 的主配置文件是 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">/usr/local/nginx/conf/nginx.conf</font><font style="color:rgb(55, 53, 47);">,可以使用 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">vim /usr/local/nginx/conf/nginx.conf</font><font style="color:rgb(55, 53, 47);"> 来查看配置。</font>
<font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">nginx.conf</font><font style="color:rgb(55, 53, 47);"> 结构图可以这样概括:</font>
plain
| 1 | main # 全局配置,对全局生效 |
| 2 | ├── events # 配置影响 Nginx 服务器或与用户的网络连接 |
| 3 | ├── http # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置 |
| 4 | │ ├── upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分 |
| 5 | │ ├── server # 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块 |
| 6 | │ ├── server |
| 7 | │ │ ├── location # server 块可以包含多个 location 块,location 指令用于匹配 uri |
| 8 | │ │ ├── location |
| 9 | │ │ └── ... |
| 10 | │ └── ... |
| 11 | └── ... |
<font style="color:rgb(55, 53, 47);">一个 Nginx 配置文件的结构就像 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">nginx.conf</font><font style="color:rgb(55, 53, 47);"> 显示的那样,配置文件的语法规则:</font>
- <font style="color:rgb(55, 53, 47);">配置文件由指令与指令块构成;</font>
- <font style="color:rgb(55, 53, 47);">每条指令以 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">;</font><font style="color:rgb(55, 53, 47);"> 分号结尾,指令与参数间以空格符号分隔;</font>
- <font style="color:rgb(55, 53, 47);">指令块以 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">{}</font><font style="color:rgb(55, 53, 47);"> 大括号将多条指令组织在一起;</font>
- <font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">include</font><font style="color:rgb(55, 53, 47);"> 语句允许组合多个配置文件以提升可维护性;</font>
- <font style="color:rgb(55, 53, 47);">使用 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">#</font><font style="color:rgb(55, 53, 47);"> 符号添加注释,提高可读性;</font>
- <font style="color:rgb(55, 53, 47);">使用 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">$</font><font style="color:rgb(55, 53, 47);"> 符号使用变量;</font>
- <font style="color:rgb(55, 53, 47);">部分指令的参数支持正则表达式;</font>
- <font style="color:rgb(55, 53, 47);">全局块</font>
<font style="color:rgb(55, 53, 47);">从配置文件开始到 events 块之间的内容,主要会设置一些影响nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等。</font>
<font style="color:rgb(55, 53, 47);">worker_processes 1; 这是 Nginx 服务器并发处理服务的关键配置,worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约。</font>
- <font style="color:rgb(55, 53, 47);">events 块</font>
<font style="color:rgb(55, 53, 47);">events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process 下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 work process 可以同时支持的最大连接数等</font>
<font style="color:rgb(55, 53, 47);">上述例子就表示每个 work process 支持的最大连接数为 1024.</font>
<font style="color:rgb(55, 53, 47);">这部分的配置</font><font style="color:rgb(55, 53, 47);">对 Nginx 的性能影响较大</font><font style="color:rgb(55, 53, 47);">,在实际中应该灵活配置。</font>
- <font style="color:rgb(55, 53, 47);">http 块</font>
<font style="color:rgb(55, 53, 47);">这算是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。</font>
<font style="color:rgb(55, 53, 47);">需要注意的是:http 块也可以包括 </font><font style="color:rgb(55, 53, 47);">http全局块</font><font style="color:rgb(55, 53, 47);">、</font><font style="color:rgb(55, 53, 47);">server 块</font><font style="color:rgb(55, 53, 47);">。</font>
<font style="color:rgb(55, 53, 47);">①、http 全局块</font>
<font style="color:rgb(55, 53, 47);">http全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。</font>
<font style="color:rgb(55, 53, 47);"> </font><font style="color:rgb(55, 53, 47);"> 最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或IP配置。</font>
<font style="color:rgb(55, 53, 47);">②、server 块</font>
<font style="color:rgb(55, 53, 47);">这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。</font>
<font style="color:rgb(55, 53, 47);">⭐</font><font style="color:rgb(55, 53, 47);">️</font><font style="color:rgb(55, 53, 47);"> 每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。</font>
<font style="color:rgb(55, 53, 47);">⭐</font><font style="color:rgb(55, 53, 47);">️</font><font style="color:rgb(55, 53, 47);"> 每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块。</font>
<font style="color:rgb(55, 53, 47);">③、location 块</font>
<font style="color:rgb(55, 53, 47);">一个 server 块可以配置多个 location 块。</font>
<font style="color:rgb(55, 53, 47);">这块的主要作用是基于 Nginx 服务器接收到的请求字符串</font>
<font style="color:rgb(55, 53, 47);">🌰</font><font style="color:rgb(55, 53, 47);"> 例如 server_name/uri-string ,对虚拟主机名称(也可以是IP别名)之外的字符串</font>
<font style="color:rgb(55, 53, 47);">🌰</font><font style="color:rgb(55, 53, 47);"> 例如 前面的 /uri-string 进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的 </font><font style="color:rgb(55, 53, 47);"> </font><font style="color:rgb(55, 53, 47);"> 配置也在这里进行。</font>
<font style="color:rgb(55, 53, 47);">location 指令用于匹配 uri,语法:</font>
plain
| 1 | location [ = | ~ | ~* | ^~] uri { |
| 2 | ... |
| 3 | } |
<font style="color:rgb(55, 53, 47);">指令后面:</font>
- <font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">=</font><font style="color:rgb(55, 53, 47);"> 精确匹配路径,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找;</font>
- <font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">^~</font><font style="color:rgb(55, 53, 47);"> 用于不含正则表达式的 uri; 前,表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找;</font>
- <font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">~</font><font style="color:rgb(55, 53, 47);"> 表示用该符号后面的正则去匹配路径,区分大小写;</font>
- <font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">
*</font><font style="color:rgb(55, 53, 47);"> 表示用该符号后面的正则去匹配路径,不区分大小写。跟 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);"></font><font style="color:rgb(55, 53, 47);"> 优先级都比较低,如有多个location的正则能匹配的话,则使用正则表达式最长的那个;</font>
<font style="color:rgb(55, 53, 47);">如果 uri 包含正则表达式,则必须要有 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);"></font><font style="color:rgb(55, 53, 47);"> 或 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">*</font><font style="color:rgb(55, 53, 47);"> 标志。</font>
<font style="color:rgb(55, 53, 47);">10、典型配置</font>
plain
| 1 | #user nobody; # 运行用户,默认即是nginx,可以不进行设置 |
| 2 | worker_processes 1; # Nginx 进程数,一般设置为和 CPU 核数一样 |
| 3 | |
| 4 | #error_log logs/error.log; # Nginx 的错误日志存放目录 |
| 5 | #error_log logs/error.log notice; |
| 6 | #error_log logs/error.log info; |
| 7 | |
| 8 | #pid logs/nginx.pid; # Nginx 服务启动时的 pid 存放位置 |
| 9 | |
| 10 | |
| 11 | events { |
| 12 | use epoll; # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的) |
| 13 | worker_connections 1024; # 每个进程允许最大并发数 |
| 14 | } |
| 15 | |
| 16 | # 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置 |
| 17 | http { |
| 18 | include mime.types; # 文件扩展名与类型映射表 |
| 19 | default_type application/octet-stream; # 默认文件类型 |
| 20 | |
| 21 | # 设置日志模式 |
| 22 | #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' |
| 23 | # '$status $body_bytes_sent "$http_referer" ' |
| 24 | # '"$http_user_agent" "$http_x_forwarded_for"'; |
| 25 | |
| 26 | #access_log logs/access.log main; # Nginx访问日志存放位置 |
| 27 | |
| 28 | sendfile on; # 开启高效传输模式 |
| 29 | #tcp_nopush on; # 减少网络报文段的数量 |
| 30 | |
| 31 | #keepalive_timeout 0; |
| 32 | keepalive_timeout 65; # 保持连接的时间,也叫超时时间,单位秒 |
| 33 | |
| 34 | #gzip on; |
| 35 | |
| 36 | # 这是负载均衡的配置,让两个服务器进行轮循,可以设置轮询的具体效果 |
| 37 | upstream myserver { |
| 38 | server 192.168.96.66:8080; |
| 39 | server 192.168.96.66:8081; |
| 40 | } |
| 41 | |
| 42 | server { |
| 43 | listen 80; |
| 44 | server_name 192.168.96.66; |
| 45 | |
| 46 | #charset koi8-r; |
| 47 | |
| 48 | #access_log logs/host.access.log main; |
| 49 | |
| 50 | location / { |
| 51 | root html; |
| 52 | #proxy_pass http://192.168.96.66:8080; |
| 53 | proxy_pass http://myserver; |
| 54 | index index.html index.htm; |
| 55 | } |
| 56 | |
| 57 | #error_page 404 /404.html; |
| 58 | |
| 59 | # redirect server error pages to the static page /50x.html |
| 60 | # |
| 61 | error_page 500 502 503 504 /50x.html; |
| 62 | location = /50x.html { |
| 63 | root html; |
| 64 | } |
| 65 | |
| 66 | # proxy the PHP scripts to Apache listening on 127.0.0.1:80 |
| 67 | # |
| 68 | #location ~ \.php$ { |
| 69 | # proxy_pass http://127.0.0.1; |
| 70 | #} |
| 71 | |
| 72 | # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 |
| 73 | # |
| 74 | #location ~ \.php$ { |
| 75 | # root html; |
| 76 | # fastcgi_pass 127.0.0.1:9000; |
| 77 | # fastcgi_index index.php; |
| 78 | # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; |
| 79 | # include fastcgi_params; |
| 80 | #} |
| 81 | |
| 82 | # deny access to .htaccess files, if Apache's document root |
| 83 | # concurs with nginx's one |
| 84 | # |
| 85 | #location ~ /\.ht { |
| 86 | # deny all; |
| 87 | #} |
| 88 | } |
| 89 | |
| 90 | # another virtual host using mix of IP-, name-, and port-based configuration |
| 91 | # |
| 92 | #server { |
| 93 | # listen 8000; |
| 94 | # listen somename:8080; |
| 95 | # server_name somename alias another.alias; |
| 96 | |
| 97 | # location / { |
| 98 | # root html; |
| 99 | # index index.html index.htm; |
| 100 | # } |
| 101 | #} |
| 102 | |
| 103 | |
| 104 | # HTTPS server |
| 105 | # |
| 106 | #server { |
| 107 | # listen 443 ssl; |
| 108 | # server_name localhost; |
| 109 | |
| 110 | # ssl_certificate cert.pem; |
| 111 | # ssl_certificate_key cert.key; |
| 112 | |
| 113 | # ssl_session_cache shared:SSL:1m; |
| 114 | # ssl_session_timeout 5m; |
| 115 | |
| 116 | # ssl_ciphers HIGH:!aNULL:!MD5; |
| 117 | # ssl_prefer_server_ciphers on; |
| 118 | |
| 119 | # location / { |
| 120 | # root html; |
| 121 | # index index.html index.htm; |
| 122 | # } |
| 123 | #} |
| 124 | } |
<font style="color:rgb(55, 53, 47);">11、反向代理</font>
<font style="color:rgb(55, 53, 47);">实例一:实现效果,使用nginx反向代理,根据访问的路径跳转到不同端口的服务中</font>
<font style="color:rgb(55, 53, 47);">nginx监听端口为9000,</font>
<font style="color:rgb(55, 53, 47);">访问 </font>http://127.0.0.1:9000/edu/<font style="color:rgb(55, 53, 47);"> 直接跳转到127.0.0.1:8080</font>
<font style="color:rgb(55, 53, 47);">访问 </font>http://127.0.0.1:9000/vod/<font style="color:rgb(55, 53, 47);"> 直接跳转到127.0.0.1:8081</font>
<!-- 这是一张图片,ocr 内容为: -->


plain
| 1 | # 在 nginx.conf 中配置如下信息 |
| 2 | server { |
| 3 | listen 9000; |
| 4 | server_name 192.168.96.66; |
| 5 | location ~ /edu/ { |
| 6 | proxy_pass http://192.168.96.66:8080; |
| 7 | } |
| 8 | location ~ /vod/ { |
| 9 | proxy_pass http://192.168.96.66:8081; |
| 10 | } |
| 11 | } |
<font style="color:rgb(55, 53, 47);">12、负载均衡</font>
<font style="color:rgb(55, 53, 47);">实现效果:浏览器地址栏输入地址 </font>http://192.168.137.129/edu/a.html<font style="color:rgb(55, 53, 47);">,负载均衡效果,将请求平均分配到8080和8081两台服务器上。</font>
- <font style="color:rgb(55, 53, 47);">准备两台tomcat服务器,一台8080,一台8081</font>
- <font style="color:rgb(55, 53, 47);">在两台tomcat里面webapps目录中,创建名称是edu文件夹,在edu文件夹中创建页面a.html(让a.html内容不一样,查看效果),用于测试</font>
<font style="color:rgb(55, 53, 47);">在配置文件中进行负载均衡配置:</font>
<font style="color:rgb(55, 53, 47);">upstream称为上游服务器,即真实处理请求的业务服务器。</font>
plain
| 1 | # 这是负载均衡的配置,让两个服务器进行轮循 |
| 2 | upstream myserver { |
| 3 | server 192.168.96.66:8080; |
| 4 | server 192.168.96.66:8081; |
| 5 | # server 192.168.96.66:8081 weight=10; # weight 方式,不写默认为 1 ,1 表示一个服务器一次依次循环 |
| 6 | } |
plain
| 1 | server { |
| 2 | listen 80; |
| 3 | server_name 192.168.96.66; |
| 4 | |
| 5 | location / { |
| 6 | root html; |
| 7 | # proxy_pass http://192.168.96.66:8080; |
| 8 | # 使用上游服务器进行分配,给真正的业务服务器 |
| 9 | proxy_pass http://myserver; |
| 10 | index index.html index.htm; |
| 11 | } |
<font style="color:rgb(55, 53, 47);">Nginx 提供了好几种分配方式,默认为</font><font style="color:rgb(55, 53, 47);">轮询</font><font style="color:rgb(55, 53, 47);">,就是轮流来。有以下几种分配方式:</font>
- <font style="color:rgb(55, 53, 47);">轮询</font><font style="color:rgb(55, 53, 47);">,默认方式,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务挂了,能自动剔除;</font>
- <font style="color:rgb(55, 53, 47);">weight</font><font style="color:rgb(55, 53, 47);">,权重分配,指定轮询几率,权重越高,在被访问的概率越大,用于后端服务器性能不均的情况;</font>
plain
| 1 | # weight代表权,重默认为1,权重越高被分配的客户端越多 |
| 2 | |
| 3 | # 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 例如: |
| 4 | |
| 5 | upstream server_pool{ |
| 6 | |
| 7 | server 192.168.5.21 weight=1; |
| 8 | |
| 9 | server 192.168.5.22 weight=2; |
| 10 | |
| 11 | server 192.168.5.23 weight=3; |
| 12 | |
| 13 | } |

- <font style="color:rgb(55, 53, 47);">ip_hash</font><font style="color:rgb(55, 53, 47);">,每个请求按访问 IP 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决动态网页 session 共享问题。负载均衡每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的;</font>
plain
| 1 | # 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 例如: |
| 2 | |
| 3 | upstream server_pool{ |
| 4 | |
| 5 | ip_hash; |
| 6 | |
| 7 | server 192.168.5.21:80; |
| 8 | |
| 9 | server 192.168.5.22:80; |
| 10 | |
| 11 | } |

- <font style="color:rgb(55, 53, 47);">fair</font><font style="color:rgb(55, 53, 47);">(第三方),按后端服务器的响应时间分配,响应时间短的优先分配,依赖第三方插件 nginx-upstream-fair,需要先安装;</font>
<font style="color:rgb(55, 53, 47);">13、Nginx 动静分离</font>
<font style="color:rgb(55, 53, 47);">动静分离在之前也介绍过了,就是把动态和静态的请求分开。方式主要有两种,一种 是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案。另外一种方法就是动态跟静态文件混合在一起发布, 通过 Nginx 配置来分开。</font>
<font style="color:rgb(55, 53, 47);">通过 location 指定不同的后缀名实现不同的请求转发。通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。具体 expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用 expires 来缓存),我这里设置 3d,表示在这 3 天之内访问这个URL,发送一个请求,比对服务器该文件最后更新时间没有变化。则不会从服务器抓取,返回状态码 304,如果有修改,则直接从服务器重新下载,返回状态码 200。</font>
<font style="color:rgb(55, 53, 47);">项目静态资源准备:在任意一个tomcat的webapps中,新建data/www/a.html 与</font><font style="color:rgb(55, 53, 47);"> </font><font style="color:rgb(55, 53, 47);">data/img/2.jpg</font>
<font style="color:rgb(55, 53, 47);">nginx.conf 配置</font>
plain
| 1 | location /img/ { |
| 2 | root /data/; |
| 3 | autoindex on; |
| 4 | } |
| 5 | |
| 6 | location /www/ { |
| 7 | root /data/; |
| 8 | autoindex on; |
| 9 | index index.html index.htm; |
| 10 | } |
<font style="color:rgb(55, 53, 47);">14、Nginx 原理与优化参数配置</font>
<!-- 这是一张图片,ocr 内容为: -->

plain
| 1 | # master-workers的机制的好处 |
| 2 | |
| 3 | 首先,对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。 |
| 4 | |
| 5 | 其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快启动新的worker进程。 |
| 6 | |
| 7 | 当然,worker进程的异常退出,肯定是程序有bug了,异常退出,会导致当前worker上的所有请求失败,不过不会影响到所有请求,所以降低了风险。 |
plain
| 1 | # 需要设置多少个worker |
| 2 | Nginx 同redis类似都采用了io多路复用机制,每个worker都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求, 即使是千上万个请求也不在话下。每个worker的线程可以把一个cpu的性能发挥到极致。 |
| 3 | 所以worker数和服务器的cpu数相等是最为适宜的。设少了会浪费cpu,设多了会造成cpu频繁切换上下文带来的损耗。 |
| 4 | |
| 5 | #设置worker数量 |
| 6 | worker_processes 4 |
| 7 | |
| 8 | #work绑定cpu(4 work绑定4cpu)。 |
| 9 | worker_cpu_affinity 0001 0010 0100 1000 |
| 10 | |
| 11 | #work绑定cpu (4 work绑定8cpu中的4个) 。 |
| 12 | worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000 |
plain
| 1 | #连接数 |
| 2 | worker_connections 1024 |
| 3 | |
| 4 | 这个值是表示每个worker进程所能建立连接的最大值,所以,一个nginx能建立的最大连接数,应该是worker_connections * worker_processes。当然,这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes,如果是支持http1.1的浏览器每次访问要占两个连接,所以普通的静态访问最大并发数是: worker_connections * worker_processes /2,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/4。 |
| 5 | 因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。 |
plain
| 1 | #面试题: |
| 2 | 第一个:发送请求,占用了woker的几个连接数? |
| 3 | 第二个:nginx有一个master,有四个woker,每个woker支持最大的连接数1024,支持的最大并发数是多少? |
<font style="color:rgb(55, 53, 47);">14.1 nginx.conf 配置详解</font>
plain
| 1 | #安全问题,建议用nobody,不要用root. |
| 2 | #user nobody; |
| 3 | |
| 4 | #worker数和服务器的cpu数相等是最为适宜 |
| 5 | worker_processes 2; |
| 6 | |
| 7 | #work绑定cpu(4 work绑定4cpu) |
| 8 | worker_cpu_affinity 0001 0010 0100 1000 |
| 9 | |
| 10 | #work绑定cpu (4 work绑定8cpu中的4个) 。 |
| 11 | worker_cpu_affinity 0000001 00000010 00000100 00001000 |
| 12 | |
| 13 | #error_log path(存放路径) level(日志等级) path表示日志路径,level表示日志等级, |
| 14 | #具体如下:[ debug | info | notice | warn | error | crit ] |
| 15 | #从左至右,日志详细程度逐级递减,即debug最详细,crit最少,默认为crit。 |
| 16 | |
| 17 | #error_log logs/error.log; |
| 18 | #error_log logs/error.log notice; |
| 19 | #error_log logs/error.log info; |
| 20 | #pid logs/nginx.pid; |
| 21 | |
| 22 | events { |
| 23 | #这个值是表示每个worker进程所能建立连接的最大值,所以,一个nginx能建立的最大连接数,应该是worker_connections * worker_processes。 |
| 24 | #当然,这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes, |
| 25 | #如果是支持http1.1的浏览器每次访问要占两个连接, |
| 26 | #所以普通的静态访问最大并发数是: worker_connections * worker_processes /2, |
| 27 | #而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/4。 |
| 28 | #因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。 |
| 29 | |
| 30 | worker_connections 1024; |
| 31 | |
| 32 | #这个值是表示nginx要支持哪种多路io复用。 |
| 33 | #一般的Linux选择epoll, 如果是(*BSD)系列的Linux使用kquene。 |
| 34 | #windows版本的nginx不支持多路IO复用,这个值不用配。 |
| 35 | use epoll; |
| 36 | |
| 37 | # 当一个worker抢占到一个链接时,是否尽可能的让其获得更多的连接,默认是off 。 |
| 38 | multi_accept on; //并发量大时缓解客户端等待时间。 |
| 39 | # 默认是on ,开启nginx的抢占锁机制。 |
| 40 | accept_mutex on; //master指派worker抢占锁 |
| 41 | } |
| 42 | http { |
| 43 | #当web服务器收到静态的资源文件请求时,依据请求文件的后缀名在服务器的MIME配置文件中找到对应的MIME Type,再根据MIME Type设置HTTP Response的Content-Type,然后浏览器根据Content-Type的值处理文件。 |
| 44 | |
| 45 | include mime.types; #/usr/local/nginx/conf/mime.types |
| 46 | |
| 47 | #如果 不能从mime.types找到映射的话,用以下作为默认值-二进制 |
| 48 | default_type application/octet-stream; |
| 49 | |
| 50 | #日志位置 |
| 51 | access_log logs/host.access.log main; |
| 52 | |
| 53 | #一条典型的accesslog: |
| 54 | #101.226.166.254 - - [21/Oct/2013:20:34:28 +0800] "GET /movie_cat.php?year=2013 HTTP/1.1" 200 5209 "http://www.baidu.com" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MDDR; .NET4.0C; .NET4.0E; .NET CLR 1.1.4322; Tablet PC 2.0); 360Spider" |
| 55 | |
| 56 | #1)101.226.166.254:(用户IP) |
| 57 | #2)[21/Oct/2013:20:34:28 +0800]:(访问时间) |
| 58 | #3)GET:http请求方式,有GET和POST两种 |
| 59 | #4)/movie_cat.php?year=2013:当前访问的网页是动态网页,movie_cat.php即请求的后台接口,year=2013为具体接口的参数 |
| 60 | #5)200:服务状态,200表示正常,常见的还有,301永久重定向、4XX表示请求出错、5XX服务器内部错误 |
| 61 | #6)5209:传送字节数为5209,单位为byte |
| 62 | #7)"http://www.baidu.com":refer:即当前页面的上一个网页 |
| 63 | #8)"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; #.NET CLR 3.0.30729; Media Center PC 6.0; MDDR; .NET4.0C; .NET4.0E; .NET CLR 1.1.4322; Tablet PC 2.0); 360Spider": agent字段:通常用来记录操作系统、浏览器版本、浏览器内核等信息 |
| 64 | |
| 65 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' |
| 66 | '$status $body_bytes_sent "$http_referer" ' |
| 67 | '"$http_user_agent" "$http_x_forwarded_for"'; |
| 68 | |
| 69 | #开启从磁盘直接到网络的文件传输,适用于有大文件上传下载的情况,提高IO效率。 |
| 70 | sendfile on; //大文件传递优化,提高效率 |
| 71 | |
| 72 | #一个请求完成之后还要保持连接多久, 默认为0,表示完成请求后直接关闭连接。 |
| 73 | #keepalive_timeout 0; |
| 74 | keepalive_timeout 65; |
| 75 | |
| 76 | #开启或者关闭gzip模块 |
| 77 | #gzip on ; //文件压缩,再传输,提高效率 |
| 78 | |
| 79 | #设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。 |
| 80 | #gzip_min_lenth 1k;//超过该大小开始压缩,否则不用压缩 |
| 81 | |
| 82 | # gzip压缩比,1 压缩比最小处理速度最快,9 压缩比最大但处理最慢(传输快但比较消耗cpu) |
| 83 | #gzip_comp_level 4; |
| 84 | |
| 85 | #匹配MIME类型进行压缩,(无论是否指定)"text/html"类型总是会被压缩的。 |
| 86 | #gzip_types types text/plain text/css application/json application/x-javascript text/xml |
| 87 | |
| 88 | #动静分离 |
| 89 | #服务器端静态资源缓存,最大缓存到内存中的文件,不活跃期限 |
| 90 | open_file_cache max=655350 inactive=20s; |
| 91 | |
| 92 | #活跃期限内最少使用的次数,否则视为不活跃。 |
| 93 | open_file_cache_min_uses 2; |
| 94 | |
| 95 | #验证缓存是否活跃的时间间隔 |
| 96 | open_file_cache_valid 30s; |
| 97 | |
| 98 | upstream myserver{ |
| 99 | # 1、轮询(默认) |
| 100 | # 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 |
| 101 | # 2、指定权重 |
| 102 | # 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 |
| 103 | #3、IP绑定 ip_hash |
| 104 | # 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 |
| 105 | #4、备机方式 backup |
| 106 | # 正常情况不访问设定为backup的备机,只有当所有非备机全都宕机的情况下,服务才会进备机。当非备机启动后,自动切换到非备机 |
| 107 | # ip_hash; |
| 108 | server 192.168.161.132:8080 weight=1; |
| 109 | server 192.168.161.132:8081 weight=1 backup; |
| 110 | #5、fair(第三方)公平,需要安装插件才能用 |
| 111 | #按后端服务器的响应时间来分配请求,响应时间短的优先分配。 |
| 112 | #6、url_hash(第三方) |
| 113 | #按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 |
| 114 | |
| 115 | # ip_hash; |
| 116 | server 192.168.161.132:8080 weight=1; |
| 117 | server 192.168.161.132:8081 weight=1; |
| 118 | |
| 119 | #fair |
| 120 | |
| 121 | #hash $request_uri |
| 122 | #hash_method crc32 |
| 123 | |
| 124 | } |
| 125 | |
| 126 | server { |
| 127 | #监听端口号 |
| 128 | listen 80; |
| 129 | |
| 130 | #服务名 |
| 131 | server_name 192.168.161.130; |
| 132 | |
| 133 | #字符集 |
| 134 | #charset utf-8; |
| 135 | |
| 136 | #location [=|~|~*|^~] /uri/ { … } |
| 137 | # = 精确匹配 |
| 138 | # ~ 正则匹配,区分大小写 |
| 139 | # ~* 正则匹配,不区分大小写 |
| 140 | # ^~ 关闭正则匹配 |
| 141 | |
| 142 | #匹配原则: |
| 143 | |
| 144 | # 1、所有匹配分两个阶段,第一个叫普通匹配,第二个叫正则匹配。 |
| 145 | # 2、普通匹配,首先通过“=”来匹配完全精确的location |
| 146 | # 2.1、 如果没有精确匹配到, 那么按照最大前缀匹配的原则,来匹配location |
| 147 | # 2.2、 如果匹配到的location有^~,则以此location为匹配最终结果,如果没有那么会把匹配的结果暂存,继续进行正则匹配。 |
| 148 | # 3、正则匹配,依次从上到下匹配前缀是~或~*的location, 一旦匹配成功一次,则立刻以此location为准,不再向下继续进行正则匹配。 |
| 149 | # 4、如果正则匹配都不成功,则继续使用之前暂存的普通匹配成功的location. |
| 150 | #不是以波浪线开头的都是普通匹配。 |
| 151 | location / { # 匹配任何查询,因为所有请求都以 / 开头。但是正则表达式规则和长的块规则将被优先和查询匹配。 |
| 152 | |
| 153 | #定义服务器的默认网站根目录位置 |
| 154 | root html;//相对路径,省略了./ /user/local/nginx/html 路径 |
| 155 | |
| 156 | #默认访问首页索引文件的名称 |
| 157 | index index.html index.htm; |
| 158 | |
| 159 | #反向代理路径 |
| 160 | proxy_pass http://myserver; |
| 161 | |
| 162 | #反向代理的超时时间 |
| 163 | proxy_connect_timeout 10; |
| 164 | |
| 165 | proxy_redirect default; |
| 166 | } |
| 167 | #普通匹配 |
| 168 | location /images/ { |
| 169 | root images ; |
| 170 | } |
| 171 | # 反正则匹配 |
| 172 | location ^~ /images/jpg/ { # 匹配任何以 /images/jpg/ 开头的任何查询并且停止搜索。任何正则表达式将不会被测试。 |
| 173 | root images/jpg/ ; |
| 174 | } |
| 175 | #正则匹配 |
| 176 | location ~*.(gif|jpg|jpeg)$ { |
| 177 | #所有静态文件直接读取硬盘 |
| 178 | root pic ; |
| 179 | |
| 180 | #expires定义用户浏览器缓存的时间为3天,如果静态页面不常更新,可以设置更长,这样可以节省带宽和缓解服务器的压力 |
| 181 | expires 3d; #缓存3天 |
| 182 | } |
| 183 | |
| 184 | #error_page 404 /404.html; |
| 185 | |
| 186 | # redirect server error pages to the static page /50x.html |
| 187 | # |
| 188 | error_page 500 502 503 504 /50x.html; |
| 189 | location = /50x.html { |
| 190 | root html; |
| 191 | } |
| 192 | } |
| 193 | } |
在 Nginx 中,
proxy_pass 指令的行为在路径后面是否加 / 会有不同。具体区别如下:14.2 proxy_pass 后面没有加 /
当
proxy_pass 后面没有加 / 时,Nginx 会将匹配到的 location 路径的一部分附加到目标 URL 上。示例 1
配置:
plain
| 1 | location /data-deal-admin-operate { |
| 2 | proxy_pass http://192.168.110.62:9299; |
| 3 | } |
请求:
http://market.core.zzbdex.com.cn/data-deal-admin-operate/common/downloadFileMinio
Nginx 将此请求转发为:
http://192.168.110.62:9299/data-deal-admin-operate/common/downloadFileMinio
在这个例子中,
/data-deal-admin-operate 部分保留并附加到目标 URL 上。14.3 proxy_pass 后面加 /
当
proxy_pass 后面加 / 时,Nginx 会将匹配到的 location 路径完全替换为目标 URL 上。示例 2
配置:
plain
| 1 | location /data-deal-admin-operate { |
| 2 | proxy_pass http://192.168.110.62:9299/; |
| 3 | } |
请求:
http://market.core.zzbdex.com.cn/data-deal-admin-operate/common/downloadFileMinio
Nginx 将此请求转发为:
http://192.168.110.62:9299/common/downloadFileMinio
在这个例子中,
/data-deal-admin-operate 部分被完全替换为目标 URL 上。<font style="color:rgb(55, 53, 47);">15、常用技巧</font>
<font style="color:rgb(55, 53, 47);">1、静态服务</font>
plain
| 1 | server { |
| 2 | listen 80; |
| 3 | server_name static.sherlocked93.club; |
| 4 | charset utf-8; # 防止中文文件名乱码 |
| 5 | |
| 6 | location /download { |
| 7 | alias /usr/share/nginx/html/static; # 静态资源目录 |
| 8 | |
| 9 | autoindex on; # 开启静态资源列目录 |
| 10 | autoindex_exact_size off; # on(默认)显示文件的确切大小,单位是byte;off显示文件大概大小,单位KB、MB、GB |
| 11 | autoindex_localtime off; # off(默认)时显示的文件时间为GMT时间;on显示的文件时间为服务器时间 |
| 12 | } |
| 13 | } |
<font style="color:rgb(55, 53, 47);">2、图片防盗链</font>
<font style="color:rgb(55, 53, 47);">最好将百度和 google 设置为白名单,利于 SEO</font>
plain
| 1 | server { |
| 2 | listen 80; |
| 3 | server_name *.sherlocked93.club; |
| 4 | |
| 5 | # 图片防盗链 |
| 6 | location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ { |
| 7 | valid_referers none blocked server_names ~\.google\. ~\.baidu\. *.qq.com; # 只允许本机 IP 外链引用,将百度和谷歌也加入白名单 |
| 8 | if ($invalid_referer){ |
| 9 | return 403; |
| 10 | } |
| 11 | } |
| 12 | } |
<font style="color:rgb(55, 53, 47);">3、请求过滤</font>
plain
| 1 | # 非指定请求全返回 403 |
| 2 | if ( $request_method !~ ^(GET|POST|HEAD)$ ) { |
| 3 | return 403; |
| 4 | } |
| 5 | |
| 6 | location / { |
| 7 | # IP访问限制(只允许IP是 192.168.0.2 机器访问) |
| 8 | allow 192.168.0.2; |
| 9 | deny all; |
| 10 | |
| 11 | root html; |
| 12 | index index.html index.htm; |
| 13 | } |
<font style="color:rgb(55, 53, 47);">4、配置图片字体等静态资源缓存</font>
plain
| 1 | 由于图片、字体、音频、视频等静态文件在打包的时候通常会增加了 hash,所以缓存可以设置的长一点,先设置强制缓存,再设置协商缓存;如果存在没有 hash 值的静态文件,建议不设置强制缓存,仅通过协商缓存判断是否需要使用缓存。 |
| 2 | # 图片缓存时间设置 |
| 3 | location ~ .*\.(css|js|jpg|png|gif|swf|woff|woff2|eot|svg|ttf|otf|mp3|m4a|aac|txt)$ { |
| 4 | expires 10d; |
| 5 | } |
| 6 | |
| 7 | # 如果不希望缓存 |
| 8 | expires -1; |
<font style="color:rgb(55, 53, 47);">5、HTTP 请求转发到 HTTPS</font>
<font style="color:rgb(55, 53, 47);">配置完 HTTPS 后,浏览器还是可以访问 HTTP 的地址 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">http://sherlocked93.club/</font><font style="color:rgb(55, 53, 47);"> 的,可以做一个 301 跳转,把对应域名的 HTTP 请求重定向到 HTTPS 上</font>
plain
| 1 | server { |
| 2 | listen 80; |
| 3 | server_name www.sherlocked93.club; |
| 4 | |
| 5 | # 单域名重定向 |
| 6 | if ($host = 'www.sherlocked93.club'){ |
| 7 | return 301 https://www.sherlocked93.club$request_uri; |
| 8 | } |
| 9 | # 全局非 https 协议时重定向 |
| 10 | if ($scheme != 'https') { |
| 11 | return 301 https://$server_name$request_uri; |
| 12 | } |
| 13 | |
| 14 | # 或者全部重定向 |
| 15 | return 301 https://$server_name$request_uri; |
| 16 | |
| 17 | # 以上配置选择自己需要的即可,不用全部加 |
| 18 | } |
6、由于上传图片位置不同,ContextPath不同,两端图片无法显示配置
plain
<font style="color:rgb(55, 53, 47);">16、总结</font>
- <font style="color:rgb(55, 53, 47);">为了使 Nginx 配置更易于维护,建议为每个服务创建一个单独的配置文件,存储在 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">/etc/nginx/conf.d</font><font style="color:rgb(55, 53, 47);"> 目录,根据需求可以创建任意多个独立的配置文件。</font>
- <font style="color:rgb(55, 53, 47);">独立的配置文件,建议遵循以下命名约定 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);"><服务>.conf</font><font style="color:rgb(55, 53, 47);">,比如域名是 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">sherlocked93.club</font><font style="color:rgb(55, 53, 47);">,那么你的配置文件的应该是这样的 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">/etc/nginx/conf.d/sherlocked93.club.conf</font><font style="color:rgb(55, 53, 47);">,如果部署多个服务,也可以在文件名中加上 Nginx 转发的端口号,比如 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">sherlocked93.club.8080.conf</font><font style="color:rgb(55, 53, 47);">,如果是二级域名,建议也都加上 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">fe.sherlocked93.club.conf</font><font style="color:rgb(55, 53, 47);">。</font>
- <font style="color:rgb(55, 53, 47);">常用的、复用频率比较高的配置可以放到 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">/etc/nginx/snippets</font><font style="color:rgb(55, 53, 47);"> 文件夹,在 Nginx 的配置文件中需要用到的位置 include 进去,以功能来命名,并在每个 snippet 配置文件的开头注释标明主要功能和引入位置,方便管理。比如之前的 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">gzip</font><font style="color:rgb(55, 53, 47);">、</font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">cors</font><font style="color:rgb(55, 53, 47);"> 等常用配置,我都设置了 snippet。</font>
- <font style="color:rgb(55, 53, 47);">Nginx 日志相关目录,内以 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">域名.type.log</font><font style="color:rgb(55, 53, 47);"> 命名(比如 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">be.sherlocked93.club.access.log</font><font style="color:rgb(55, 53, 47);"> 和 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">be.sherlocked93.club.error.log</font><font style="color:rgb(55, 53, 47);"> )位于 </font><font style="color:rgb(236, 87, 87);background-color:rgb(247, 246, 243);">/var/log/nginx/</font><font style="color:rgb(55, 53, 47);"> 目录中,为每个独立的服务配置不同的访问权限和错误日志文件,这样查找错误时,会更加方便快捷。</font>