陶辉Nginx核心100讲笔记


csdn的图片显示有问题,为了更好的阅读体验,请移步nginx-blog

一、初始Nginx

1.1 nginx应用场景

![image.png](https://img-blog.csdnimg.cn/img_convert/5a930a077c0e7f4a8d17fe69e4350e9c.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=586&id=LL1zE&margin=[object Object]&name=image.png&originHeight=1172&originWidth=2112&originalType=binary&ratio=1&rotation=0&showTitle=false&size=928999&status=done&style=none&taskId=uddb9f030-3d60-4932-8c4c-cced0a440f1&title=&width=1056)

1.2 Nginx优点

![A82E994B-DDE1-4C48-A3B1-4CC72150E101.png](https://img-blog.csdnimg.cn/img_convert/8fcb61262648556243573ef2cebdcfcc.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=511&id=u59c349bd&margin=[object Object]&name=A82E994B-DDE1-4C48-A3B1-4CC72150E101.png&originHeight=1022&originWidth=1938&originalType=binary&ratio=1&rotation=0&showTitle=false&size=973178&status=done&style=none&taskId=udfc4d868-cc8d-4074-9e67-588b458f05f&title=&width=969)

1.3 Nginx组成

![image.png](https://img-blog.csdnimg.cn/img_convert/988d8f4f89b21b29a6f917d1ec6385b2.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=413&id=u4baf27df&margin=[object Object]&name=image.png&originHeight=826&originWidth=1516&originalType=binary&ratio=1&rotation=0&showTitle=false&size=690551&status=done&style=none&taskId=u093b0ccd-1ef0-476e-8b8f-a703c56616d&title=&width=758)

1.4 Nginx配置语法

![image.png](https://img-blog.csdnimg.cn/img_convert/9ecab8688370426e90478d09afdef67e.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=415&id=u546695db&margin=[object Object]&name=image.png&originHeight=830&originWidth=1480&originalType=binary&ratio=1&rotation=0&showTitle=false&size=815741&status=done&style=none&taskId=u2c247769-0483-4af3-a4c5-377f3d3f97e&title=&width=740)

![image.png](https://img-blog.csdnimg.cn/img_convert/2d721ec44ea250782afc3890899d74a8.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=438&id=ueaec73dd&margin=[object Object]&name=image.png&originHeight=876&originWidth=1380&originalType=binary&ratio=1&rotation=0&showTitle=false&size=328505&status=done&style=none&taskId=u790be97a-4b0b-4db9-a113-d50a1b57b6c&title=&width=690)![image.png](https://img-blog.csdnimg.cn/img_convert/ba61ca6096aa5c88c817e024645b4705.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=434&id=uc3b7e24a&margin=[object Object]&name=image.png&originHeight=868&originWidth=1548&originalType=binary&ratio=1&rotation=0&showTitle=false&size=473105&status=done&style=none&taskId=u7ab99a62-6fc6-40aa-bcf5-ac954f839af&title=&width=774)

![image.png](https://img-blog.csdnimg.cn/img_convert/09875d39f3d851c309b29b91eb6b05c3.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=426&id=ufad33ad3&margin=[object Object]&name=image.png&originHeight=852&originWidth=1460&originalType=binary&ratio=1&rotation=0&showTitle=false&size=423949&status=done&style=none&taskId=ue31bfd4f-7edb-48e8-bee3-31d0eadd078&title=&width=730)

1.5 Nginx 命令行

![image.png](https://img-blog.csdnimg.cn/img_convert/09e3250a79debfec4cd89096ae285712.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=432&id=ufa43ac01&margin=[object Object]&name=image.png&originHeight=864&originWidth=1456&originalType=binary&ratio=1&rotation=0&showTitle=false&size=646525&status=done&style=none&taskId=ua093ced4-fbab-4ecb-b65f-e2afac5a6ab&title=&width=728)

1.6 日志

web日志分析工具:goaccess

1.7 SSl安全协议

![image.png](https://img-blog.csdnimg.cn/img_convert/765e71d44e2b05963f0da598491c8bec.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=433&id=u167fc52b&margin=[object Object]&name=image.png&originHeight=866&originWidth=1512&originalType=binary&ratio=1&rotation=0&showTitle=false&size=771135&status=done&style=none&taskId=ueb77d876-4757-4a44-929f-609bbe79b3b&title=&width=756)

![image.png](https://img-blog.csdnimg.cn/img_convert/9194fd240c0abcc046ff29bc20fba349.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=428&id=uc42cac93&margin=[object Object]&name=image.png&originHeight=856&originWidth=1486&originalType=binary&ratio=1&rotation=0&showTitle=false&size=651764&status=done&style=none&taskId=u66318642-6518-4f37-881c-daa3d2ee47b&title=&width=743)

1.7.1 对称加密

![image.png](https://img-blog.csdnimg.cn/img_convert/7c1b704a6ed8c85e613c15786dacc07a.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=418&id=u555e3556&margin=[object Object]&name=image.png&originHeight=836&originWidth=1326&originalType=binary&ratio=1&rotation=0&showTitle=false&size=194153&status=done&style=none&taskId=u171d1452-7cc7-4148-819a-3072fd184a3&title=&width=663)

基于异或算法,明文可以转为密文,密文也可以转为明文,而且性能好,只需要一次便历过程。

1.7.2 非对称加密

![image.png](https://img-blog.csdnimg.cn/img_convert/fd3fbb5fbb960452435c45b3cc29224d.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=355&id=u8daa4a38&margin=[object Object]&name=image.png&originHeight=710&originWidth=1590&originalType=binary&ratio=1&rotation=0&showTitle=false&size=341051&status=done&style=none&taskId=u9747b1f9-8adb-4fff-904d-31432c7860a&title=&width=795)
自己发出去的文本用私钥加密,接收方使用公钥加密;反之,接收方回复消息使用公钥加密,自己使用私钥解密。

![image.png](https://img-blog.csdnimg.cn/img_convert/39d03fffcf3a084561b1c6156a12bcb1.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=450&id=u88a77c62&margin=[object Object]&name=image.png&originHeight=900&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=529082&status=done&style=none&taskId=ue0ecf4c4-4058-4ead-8437-50c04108c19&title=&width=767)

在Nginx上可以设置为:

ssl_verify_client on;#以便 OCSP 验证工作
ssl_ocsp on;#启用客户端证书链的 OCSP 验证
resolver 192.0.2.1;#解析器应指定为解析 OCSP 响应器主机名

![image.png](https://img-blog.csdnimg.cn/img_convert/69e078c9d8fdb1af94f76bdd54a26491.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=424&id=u08d2c9e7&margin=[object Object]&name=image.png&originHeight=848&originWidth=1510&originalType=binary&ratio=1&rotation=0&showTitle=false&size=644753&status=done&style=none&taskId=u3637df4c-3da2-4c23-8cc1-93edeb8830b&title=&width=755)

浏览器获取到证书后如何生效,需要验证证书链:

![image.png](https://img-blog.csdnimg.cn/img_convert/2c002bc589a99d0a9f8e65007aa060de.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=403&id=u7bd89cd0&margin=[object Object]&name=image.png&originHeight=806&originWidth=1596&originalType=binary&ratio=1&rotation=0&showTitle=false&size=706121&status=done&style=none&taskId=u25b277c3-4a01-4f3a-aa71-ab14d0bed78&title=&width=798)
说明:
站点证书由三部分构成(根证书、二级证书、主证书),操作系统的根证书很难修改,大部分浏览器(除firebox)使用的是操作系统的证书库。所以浏览器在验证证书是否有效时,除了验证nginx发过来的两个证书(二级证书和主站点证书)是否过期外,还要要在根证书是否有效且被认证。

1.7.3 TLS的通信过程

![image.png](https://img-blog.csdnimg.cn/img_convert/f339ad9338f8dc16768cc927f20e99cd.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=445&id=ufb99ad14&margin=[object Object]&name=image.png&originHeight=890&originWidth=1614&originalType=binary&ratio=1&rotation=0&showTitle=false&size=717638&status=done&style=none&taskId=u72971e82-41b9-420d-b364-d9cf4dc558a&title=&width=807)

第一步:浏览器向服务器发送clinet hello消息,告诉服务器我支持哪些加密算法;
第二步:服务器把最偏向的加密算法发送给客户端,发送server hello消息,告诉服务器最终选择哪个安全套件;
第三步:服务器向客户端发送证书链;
第四步:客户端验证服务器相关证书;
第五步:服务器发送server hello done,且在第五步前向客户的发送加密算法的公共参数;
第六步:浏览器根据公共参数生成自己的私钥,再把公钥发送给服务器;
第七步:服务器生成自己的一对公钥和私钥,用自己的私钥和客户端发来的私钥,生成双方加密的密钥。
第八步:浏览器根据服务器发来的公钥和自己生成的私钥也会生成双方加密的密钥,通过非对称加密,二者生成的密钥是相同的。
第九步:服务器使用生成的密钥加密发送的消息,传给浏览器。

Nginx对加密算法的优化:

对于小文件,Nginx需要优化非对称加密算法,适当弱化密码强度;
对于大文件,需要考虑优化对称加密算法(AES)。

1.7.4 使用免费SSL证书把Http网站改造为Https网站
[root]:yum install python2-certbot-nginx
[root]:certbot --nginx --nginx-server-root=conf目录 -d 需要安装证书的server name

1.8 基于openResty使用lua实现简单服务

1.8.1 下载

openresty.org–>下载–>源码发布–下载–>解压

1.8.2 分析目录结构

![image.png](https://img-blog.csdnimg.cn/img_convert/8e64c04ec1fa6875e0165ab5bc5a2f3d.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=216&id=u1ff86b65&margin=[object Object]&name=image.png&originHeight=432&originWidth=1130&originalType=binary&ratio=1&rotation=0&showTitle=false&size=497671&status=done&style=none&taskId=u7369271d-1f04-43a0-9dcf-43f18a49c33&title=&width=565)

1.8.3 编译

编译一个基本的openresty .configure
make&make install

1.8.4 添加lua代码

![image.png](https://img-blog.csdnimg.cn/img_convert/8ff7fd74b248eb71038c46e939aab14f.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=295&id=u2936c073&margin=[object Object]&name=image.png&originHeight=590&originWidth=1524&originalType=binary&ratio=1&rotation=0&showTitle=false&size=230878&status=done&style=none&taskId=uba1fba36-a7c0-4dda-9ee6-9a7020d9543&title=&width=762)

1.8.5 运行

二、Nginx架构基础

![image.png](https://img-blog.csdnimg.cn/img_convert/92991b0bb602363177d3d0211bc1591f.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=438&id=ud746df97&margin=[object Object]&name=image.png&originHeight=876&originWidth=1600&originalType=binary&ratio=1&rotation=0&showTitle=false&size=816530&status=done&style=none&taskId=ua40d20a8-ec6a-4ac8-b50b-dac5dec87ec&title=&width=800)

2.1 Nginx的进程结构

![image.png](https://img-blog.csdnimg.cn/img_convert/132a2632c10ec0bc69bcf6e24f431b67.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=427&id=u487ab640&margin=[object Object]&name=image.png&originHeight=854&originWidth=1412&originalType=binary&ratio=1&rotation=0&showTitle=false&size=560212&status=done&style=none&taskId=u3bf290f2-ccfd-458a-94da-318e85a25e4&title=&width=706)
Nginx包含master进程和子进程,子进程又分为两大类,Cache相关进程和worker进程,子进程间的通信是通过共享内存来解决的。
master进程:用来管理worker进程,负责监控worker进程正常工作,是否需要重新加载配置文件等。
缓存:是多个worker进程共享的,同时也会被cache manager(缓存的关联)和cache loader(缓存的载入)进程使用。cache manager和cache loader进程使用是用于后端发来的动态请求做缓存的来使用的。
为了保证Nginx的高可用性,nginx被设计为多进程的模式,因为多线程不同线程会共享一块内存空间,线程间相互影响,如果一个第三方模块导致地址越界等问题会使得整个Nginx全部挂掉。

2.2 使用信号管理Nginx父子进程

![image.png](https://img-blog.csdnimg.cn/img_convert/76a9a9f2f5fadfbd23b014247897b9cf.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=420&id=u1019b4de&margin=[object Object]&name=image.png&originHeight=840&originWidth=1520&originalType=binary&ratio=1&rotation=0&showTitle=false&size=556853&status=done&style=none&taskId=u1a9a6968-3180-4cb3-9b6f-c758e22b7be&title=&width=760)

2.3 reload流程

![image.png](https://img-blog.csdnimg.cn/img_convert/13350fb3a5e7a3daa389954c93f8d6d7.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=480&id=ua44596f6&margin=[object Object]&name=image.png&originHeight=960&originWidth=1794&originalType=binary&ratio=1&rotation=0&showTitle=false&size=965935&status=done&style=none&taskId=u8e0ac1bc-328a-46e5-b34d-a6332fcd8a0&title=&width=897)

![image.png](https://img-blog.csdnimg.cn/img_convert/47fc12acc8a8782671c24e68ac3d7614.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=494&id=ue50573a9&margin=[object Object]&name=image.png&originHeight=988&originWidth=1800&originalType=binary&ratio=1&rotation=0&showTitle=false&size=579088&status=done&style=none&taskId=ua1f257c9-6f0c-4c10-886d-298b0cd6a84&title=&width=900)

2.4 热升级流程

![image.png](https://img-blog.csdnimg.cn/img_convert/bfa2d518a1a0c01c52530a5a8cec6b41.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=393&id=u5e6dc846&margin=[object Object]&name=image.png&originHeight=786&originWidth=1450&originalType=binary&ratio=1&rotation=0&showTitle=false&size=703236&status=done&style=none&taskId=u2436f5c7-22ff-44a9-b7c7-dff30a2e78d&title=&width=725)
![image.png](https://img-blog.csdnimg.cn/img_convert/43b1b71f4c35dc3d73724868c7e7b5ec.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=399&id=u06a3e15a&margin=[object Object]&name=image.png&originHeight=798&originWidth=1512&originalType=binary&ratio=1&rotation=0&showTitle=false&size=442930&status=done&style=none&taskId=u6576c8e6-74a3-4490-b5e9-24029966232&title=&width=756)

2.5 优化的关闭worker进程

优化的关闭只针对Http请求,对于websocket,TCP,UDP,Nginx无法得知worker是否在处理请求。

![image.png](https://img-blog.csdnimg.cn/img_convert/066e2fb4943863f6fa2bf51a410b9b7c.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u267339ed&margin=[object Object]&name=image.png&originHeight=792&originWidth=1426&originalType=binary&ratio=1&rotation=0&showTitle=false&size=504452&status=done&style=none&taskId=ubc2ac892-79a0-4e7d-ba7b-80c350f4624&title=&width=713)

2.6 网络收发和Nginx事件间的对应关系

Nginx是一个事件驱动的框架,事件是指网络事件,一个网络连接对应两个事件(读事件和写事件)

2.6.1 网络传输

![image.png](https://img-blog.csdnimg.cn/img_convert/9280954645b4f9265cbc81fbcac07fcb.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=674&id=u0565fcd0&margin=[object Object]&name=image.png&originHeight=1348&originWidth=2472&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1078525&status=done&style=none&taskId=u633d97ba-b09e-4edb-94b3-01ebc78ba71&title=&width=1236)

2.6.2 TCP流和报文

![image.png](https://img-blog.csdnimg.cn/img_convert/d29b4aafc136d5d2757bb3ba373b6e59.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=672&id=u5ede5806&margin=[object Object]&name=image.png&originHeight=1344&originWidth=2434&originalType=binary&ratio=1&rotation=0&showTitle=false&size=971254&status=done&style=none&taskId=u834386c2-d0e9-410e-85a1-edc29a53265&title=&width=1217)

![image.png](https://img-blog.csdnimg.cn/img_convert/08c76618ae8f5ccfd5ec683262cfd5dd.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=657&id=ue85904c3&margin=[object Object]&name=image.png&originHeight=1314&originWidth=2394&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1049871&status=done&style=none&taskId=uaea3a798-39f8-4825-9bcb-400c221f76b&title=&width=1197)

2.7 Nginx事件循环

![image.png](https://img-blog.csdnimg.cn/img_convert/1d96a2afb5dd2a97bdcc69b15f9b7d94.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=659&id=u1e9fce32&margin=[object Object]&name=image.png&originHeight=1318&originWidth=2266&originalType=binary&ratio=1&rotation=0&showTitle=false&size=570999&status=done&style=none&taskId=u6cc79520-a8d8-41a7-9be6-5c635283aa3&title=&width=1133)

2.7.1 epool优劣已经原理

上图nginx等待服务器内核的事件队列使用epool来处理的。

![image.png](https://img-blog.csdnimg.cn/img_convert/9474b53f85db98bf69f54525559ffae8.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=677&id=uf37f6e9b&margin=[object Object]&name=image.png&originHeight=1354&originWidth=2398&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1073766&status=done&style=none&taskId=udcf0d437-d241-47e1-b3bc-2995e6b7fb1&title=&width=1199)

2.8 Nginx的请求切换

![image.png](https://img-blog.csdnimg.cn/img_convert/0de6f4b958800851f83c494f6ac2ad96.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=673&id=u30e09ba8&margin=[object Object]&name=image.png&originHeight=1346&originWidth=2418&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1149441&status=done&style=none&taskId=u6a575f63-c9a8-4d8e-87d2-dc1be5c0ebc&title=&width=1209)

nginx是用户态直接切换的,除非操作系统分给worker的时间分片到期了,否则一直工作,所以将worker的优先级调为-19,可以使得操作系统给worker分配更多的时间分片,提高Nginx性能。

2.9 同步和异步、阻塞和非阻塞的区别

阻塞和非阻塞是线程在访问某个资源时,数据是否准备就绪的一种处理方式。

阻塞方法:操作系统或者底层C库提供的方法或者是一个系统调用,这个方法可能是我的进程进入sleep状态(当前条件不满足,操作系统把我的进程切换到另外一个进程)。
非阻塞方法:我们调用该方法永远不会在我们时间分片未用完时,切换到另外一个进程。

同步和异步是用户态的调用方式而言。

同步:调用方法时,需要等待返回结果。
异步:调用方法后,无需等待返回结果,被调用方法处理完成后后主动通知给调用方。(支付回调)

2.9.1 阻塞调用:

![image.png](https://img-blog.csdnimg.cn/img_convert/5ce9869660cf411fea86265e2e5259a0.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=635&id=mmbW1&margin=[object Object]&name=image.png&originHeight=1270&originWidth=2308&originalType=binary&ratio=1&rotation=0&showTitle=false&size=756496&status=done&style=none&taskId=ufef84591-1516-49f2-bdb2-77410e81f32&title=&width=1154)

2.9.2 非阻塞调用:

![image.png](https://img-blog.csdnimg.cn/img_convert/c4ac4d3b176088f38c291a011f86417c.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=668&id=ue53dda1d&margin=[object Object]&name=image.png&originHeight=1336&originWidth=2320&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1003491&status=done&style=none&taskId=uc340540a-9101-4d2d-b070-8579213e891&title=&width=1160)

2.9.3 非阻塞调用下的同步和异步:

![image.png](https://img-blog.csdnimg.cn/img_convert/9b0d811d24cdf1061d68c45fd0cdd533.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=670&id=u34e4073a&margin=[object Object]&name=image.png&originHeight=1340&originWidth=2498&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1394172&status=done&style=none&taskId=u5d50ab4e-b982-4007-8151-ab0a6cb8a63&title=&width=1249)
openResty使得我们可以通过写同步的的方法,实际上以异步的来执行。

2.10 Nginx模块

![image.png](https://img-blog.csdnimg.cn/img_convert/e28a283a8cdeee392c2e3164fe55f244.png#clientId=u4080493f-2439-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=682&id=u8e0d1bec&margin=[object Object]&name=image.png&originHeight=1364&originWidth=2400&originalType=binary&ratio=1&rotation=0&showTitle=false&size=951445&status=done&style=none&taskId=u1e94db26-886a-48c5-9d00-3bb89d8d66e&title=&width=1200)

2.10.1 Nginx模块分类

![image.png](https://img-blog.csdnimg.cn/img_convert/da7ede8968243725eef8515bce8704eb.png#clientId=ue2063783-0659-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=504&id=uceec0e31&margin=[object Object]&name=image.png&originHeight=1008&originWidth=2000&originalType=binary&ratio=1&rotation=0&showTitle=false&size=765616&status=done&style=none&taskId=u78964cdd-88b3-461b-bb13-9d9927ab610&title=&width=1000)

2.11 Nginx连接池



说明:
每一个连接对应2个事件(读事件和写事件),如上图是通过数组序号来配合使用的。消耗的内存如下:
一个connection(232)+2个event(96*2) = 424字节。设置的连接数越多,消耗的内存就越大。


2.12 Nginx内存池


2.12.1 connection_pool_size:
  • Default:connection_pool_size:256|512

内存池配置512字节,并不意味着只能分配512字节,当内存超过预分配内存大小时,是可以继续分配的。提前分配内存空间,减小分配的资源消耗。

2.12.2 request_pool_size:
  • Default:request_pool_size:4k

请求池大小,默认4K。

2.12.3 为什么请求内存池大于远远大于连接内存池?


因为连接需要存储的上下文信息很少,只需要帮助后面的请求读取最初一部分字节就行;对于请求而言,需要保存大量上下文信息,比如:url和header。其对性能的影响比较小,极端场景下,url特别长,可以修改配置,增大请求内存池预分配的空间大小;通常情况下,url和header都很小,可以考虑降低请求内存池的预分配空间大小,最大化Nginx的并发量。

内存池对减小内存碎片和第三方模块开发是很有意义的。

2.13 Nginx进程间通信方式

陶辉Nginx核心100讲笔记_第1张图片

2.13.1 哪些官方模块使用了共享内存呢?

  • Nginx_http_lua_api是OpenResty的核心模块:

陶辉Nginx核心100讲笔记_第2张图片

在如上代码中,同时使用了rbtree和链表:

lua_shared_dict dogs 10m;//使用红黑树来保存每一个key-value,每一个节点是它的key,节点值就是value。
//当内存大于10m时,使用lru方式淘汰,最先设置了key-value就会被淘汰,这就说明每个key-value连在了一起形成了一张链表。

2.13.2 Slab内存分配管理

如何把一整块内存切割成小块分配给每个红黑树节点使用的?Slab内存管理

Slab会把共享内存切割很多页面(4K),每个页面被切分为不同的slot(不同的slot分配内存空间不同128|256|512,乘2方式向上增长)。

Bestfit:比如30字节的内存,会被分配到32字节的slot。

2.13.3 查看slot使用状态


2.13.4 在OpenResty上使用tengine的slab_stat模块查看共享内存分配情况

编译安装(在编译安装OpenResty时,使用add-module把tengine的slab_stat模块安装进来):
image.png
案例:
陶辉Nginx核心100讲笔记_第3张图片

2.14 Nginx数据容器

nginx的数据容器包括:数组、链表、队列、哈希表、红黑树、基数树

Nginx数组(nginx_array_T):

多块连续内存,每块连续内存中可以存放许多元素。

链表:

nginx_list_T

队列:

nginx_queue_T

哈希表

nginx_hash_elt_T

陶辉Nginx核心100讲笔记_第4张图片

哈希表每个元素占用连续的内存。value是指针,指向用户数据,len长度,name就是hash的key。

陶辉Nginx核心100讲笔记_第5张图片

Hash表应用于静态不变的内容。

Max size:控制了最大的hash表Bucket的个数,并不是实际最大hash表bucket的个数。

Bucket size:每个bucket的大小,向上对齐(cache line)。比如64位操作系统,操作系统每次读取64个字节,但bucket size配置60,这个时候实际是Nginx会设置为64,与操作系统对齐。,bucket size配置尽量不要超过64字节,以免占用内存过高。

红黑树

陶辉Nginx核心100讲笔记_第6张图片

红黑树本身是一个二叉树,包含左节点和右节点。其次是一个查找二叉树,左节点比右节点小。可能会退化成一个链表,如右图。

  • 红黑树优点:

陶辉Nginx核心100讲笔记_第7张图片

  • 使用红黑树的模块:

陶辉Nginx核心100讲笔记_第8张图片

2.15 动态模块

陶辉Nginx核心100讲笔记_第9张图片

使用案例:

(1)查看哪些模块支持动态模块:./configure —help | more

(2)把一个模块动态编译到nginx
image.png
(3)打开动态模块配置

load_module module/nginx_http_image_filter_module.so
image_filter resize 15 10;

2.16 配置指令

陶辉Nginx核心100讲笔记_第10张图片

2.16.1 什么是指令的context?

该条配置指令能处于的配置块。

陶辉Nginx核心100讲笔记_第11张图片

上图表明:log_format能在http模块上配置;access_log能在http,server…等模块配置。

陶辉Nginx核心100讲笔记_第12张图片

一个配置存在多个配置块是是可以合并的。值指令可以合并;动作类指令不可以合并。判断依据:看该条配置的生效阶段。

值指令向上覆盖:

陶辉Nginx核心100讲笔记_第13张图片

http模块指令合并规则:

陶辉Nginx核心100讲笔记_第14张图片

三、详解HTTP模块

3.1 Listen指令

陶辉Nginx核心100讲笔记_第15张图片

3.2 接收请求的事件模块

陶辉Nginx核心100讲笔记_第16张图片
陶辉Nginx核心100讲笔记_第17张图片

3.3 正则表达式:

陶辉Nginx核心100讲笔记_第18张图片

3.4 如何找到处理请求的server指令块

3.4.1 server_name
  • 指令说明:

陶辉Nginx核心100讲笔记_第19张图片

  • server_name多域名:

例如:

server{
		server_name [aa.com](http://aa.com) [bb.com](http://bb.com); #其中aa.com是主域名
		server_name_in_redirect off;
		redirect 302 /redirect;
}

如上配置:如果访问bb.com,会直接跳转到bb.com/redirect

如果配置:

server{
		server_name [aa.com](http://aa.com) [bb.com](http://bb.com); #其中aa.com是主域名
		server_name_in_redirect on;
		redirect 302 /redirect;
}

如上配置:如果访问bb.com,会302到aa.com/redirect

陶辉Nginx核心100讲笔记_第20张图片

  • server_name匹配顺序:

陶辉Nginx核心100讲笔记_第21张图片

3.5 HTTP请求11个阶段

陶辉Nginx核心100讲笔记_第22张图片

HTTP请求11个阶段的执行顺序:
陶辉Nginx核心100讲笔记_第23张图片
上图说明:

(1)每一个阶段会有多个模块得到执行。

(2)limit_req和limit_conn都在preaccess阶段得到执行,但是如果limit_req阻止了本次请求,就会直接返回,limit_conn就得不到执行。

(3)access阶段的access执行通过后,后续auth_basic和auth_request两个阶段不会执行,直接跳到precontent阶段,同理content阶段也是如此。

3.5.1 postread阶段

(1)realip模块

把realip模块编译进Nginx模块?

陶辉Nginx核心100讲笔记_第24张图片

三个指令:

陶辉Nginx核心100讲笔记_第25张图片

set_real_ip_from:设置可信赖的ip(如本机IP或者机器某台机器IP),找到用户真实ip

real_ip_header:ip值从哪个参数中取(X-Real_Ip |X-Forwarded-For)

real_ip_recursive:环回地址,取 X-Forwarded-For最后一个地址如果和客户端地址一样就pass掉,取上一个地址。

(2)如何拿到真实的用户IP地址?
陶辉Nginx核心100讲笔记_第26张图片
说明:当网络请求过程中,存在很多反向代理服务器时,Nginx会把用户真实的ip写在X-Real_IP中,而每经过一层反向代理,会吧上一层IP追加在X-Forwarded-For中。

拿到真实用户IP后如何使用?
陶辉Nginx核心100讲笔记_第27张图片

3.5.2 rewrite阶段

(1)rewrite模块return指令

陶辉Nginx核心100讲笔记_第28张图片

error_page:收到某个特定的返回码时,重定向某个url或者给用户返回特定内容。

陶辉Nginx核心100讲笔记_第29张图片

return示例:

陶辉Nginx核心100讲笔记_第30张图片

server与location块下的return指令关系?

server块的return先于location块的return执行。

return与error_page指令的关系?

访问不存在的资源,执行error_page指令;如果执行了return指令,error_page得不到执行。

(2) rewrite指令

案例:

陶辉Nginx核心100讲笔记_第31张图片

问题1:rewrite指令优先级高于return

问题2:依次返回“test3”、“test3”、”third!”

问题3:不携带break,就往下执行到return 200 ‘second’模块

陶辉Nginx核心100讲笔记_第32张图片

问题:依次返回301、302、302、301

rewrite日志记录:rewrite_log:on就可以开启了

(3)if指令
陶辉Nginx核心100讲笔记_第33张图片陶辉Nginx核心100讲笔记_第34张图片

3.5.3 find_config阶段

(1)location指令

陶辉Nginx核心100讲笔记_第35张图片

匹配规则:

陶辉Nginx核心100讲笔记_第36张图片陶辉Nginx核心100讲笔记_第37张图片

匹配结果:

/Test1:5,6;

/Test1/:1,3,5;

/Test1/Test2:2,4,5

/Test1/Test2/:4,5

/test1/Test2:2

匹配顺序

陶辉Nginx核心100讲笔记_第38张图片

同上问题,返回什么?

/Test1:exact match!

/Test1/:stop regular expressions match!

/Test1/Test2:lonest regular expressions match!

/Test1/Test2/:lonest regular expressions match!

/test1/Test2:lonest regular expressions match!

3.5.4 preaccess阶段

(1)limit_conn指令

陶辉Nginx核心100讲笔记_第39张图片

key一般为用户的IP地址(remote_addr变量)。
陶辉Nginx核心100讲笔记_第40张图片陶辉Nginx核心100讲笔记_第41张图片

$binary_remote_addr 关键字,这里是限制同一客户端ip地址;

限制连接数:

要限制连接,必须先有一个容器对连接进行计数,在http段加入如下代码:

“zone=” 给它一个名字,可以随便叫,这个名字要跟下面的 limit_conn 一致

$binary_remote_addr = 用二进制来储存客户端的地址,1m 可以储存 32000 个并发会话

上图配置说明:现在某个ip的并发数为1,超过1就返回500,记warn级别日志,网站返回速率为50字节/s

(1)limit_req指令

陶辉Nginx核心100讲笔记_第42张图片

陶辉Nginx核心100讲笔记_第43张图片

leaky bucket算法:

limit_req_zone:$binary_remote_addr zone=one:10m rate=2r/m;
location / {
	limit_req zone=one burst=3 nodely;
}

第一段配置参数:

  • $binary_remote_addr :表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地
  • zone=one:10m:表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息
  • rate=2r/s:表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,即每秒只处理一个请求,还可以有比如30r/m的,即限制每2秒访问一次,即每2秒才处理一个请求。

第二段配置参数:

  • zone=one :设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应
  • burst=5:重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内等待,但是这个等待区里的位置只有5个,超过的请求会直接报503的错误然后返回。
  • nodelay:
  • 如果设置,会在瞬时提供处理(burst + rate)个请求的能力,请求超过**(burst + rate)的时候就会直接返回503,永远不存在请求需要等待的情况**。(这里的rate的单位是:r/s)
  • 如果没有设置,则所有请求会依次等待排队

说明:limit_conn模块优先级大于limit_req。

3.5.5 access阶段
  • access模块(对用户ip校验)

判断请求是否可以继续向下访问。
陶辉Nginx核心100讲笔记_第44张图片陶辉Nginx核心100讲笔记_第45张图片

  • auth_basic模块(对用户用户名+密码验证)

陶辉Nginx核心100讲笔记_第46张图片

示例:

陶辉Nginx核心100讲笔记_第47张图片
陶辉Nginx核心100讲笔记_第48张图片

  • auth_request模块(用于做统一用户鉴权系统)

  • satisfy指令

陶辉Nginx核心100讲笔记_第49张图片

satisfy all:access的3和指令均放行这个请求,这个请求才向下执行,任何一个拒绝,400或500返回。

   anny:access的3和指令有一个指令放行这个请求,这个请求就向下执行。

陶辉Nginx核心100讲笔记_第50张图片

  1. 不会。
  2. 有影响。
  3. 可以
  4. 可以
  5. 没有机会输入

3.5.6 precontent阶段
  • try_file指令

陶辉Nginx核心100讲笔记_第51张图片

  • mirror模块(做流量拷贝)

陶辉Nginx核心100讲笔记_第52张图片

3.5.7 content阶段
  • static模块

(1)root和alias指令
陶辉Nginx核心100讲笔记_第53张图片陶辉Nginx核心100讲笔记_第54张图片

/root :404

/root/1.txt :—>html/first/root/1.txt 也是404

/alias:—>html/index.html 200

/alias/1.txt:—>html/first/1.txt 200

(2)3个nginx变量
陶辉Nginx核心100讲笔记_第55张图片陶辉Nginx核心100讲笔记_第56张图片陶辉Nginx核心100讲笔记_第57张图片
(3)static模块对url不以斜杠结尾却访问目录的的做法
陶辉Nginx核心100讲笔记_第58张图片陶辉Nginx核心100讲笔记_第59张图片

  • index模块和autoindex模块

陶辉Nginx核心100讲笔记_第60张图片陶辉Nginx核心100讲笔记_第61张图片陶辉Nginx核心100讲笔记_第62张图片

  • concat模块(合并小文件,提升网络性能)

3.5.8 log阶段

陶辉Nginx核心100讲笔记_第63张图片陶辉Nginx核心100讲笔记_第64张图片

3.5.9 HTTP过滤模块

  • sub模块

陶辉Nginx核心100讲笔记_第65张图片陶辉Nginx核心100讲笔记_第66张图片

示例:

陶辉Nginx核心100讲笔记_第67张图片

  • addition模块

陶辉Nginx核心100讲笔记_第68张图片陶辉Nginx核心100讲笔记_第69张图片

3.6 HTTP的变量

陶辉Nginx核心100讲笔记_第70张图片

3.6.1 HTTP请求相关变量

陶辉Nginx核心100讲笔记_第71张图片陶辉Nginx核心100讲笔记_第72张图片陶辉Nginx核心100讲笔记_第73张图片

3.6.2 TCP连接相关的变量

陶辉Nginx核心100讲笔记_第74张图片
陶辉Nginx核心100讲笔记_第75张图片

3.6.3 请求中产生的变量

陶辉Nginx核心100讲笔记_第76张图片陶辉Nginx核心100讲笔记_第77张图片

3.6.4 方式HTTP响应时相关的变量

陶辉Nginx核心100讲笔记_第78张图片

3.6.5 系统变量

陶辉Nginx核心100讲笔记_第79张图片

3.7 referer模块

陶辉Nginx核心100讲笔记_第80张图片

valid_referers指令

陶辉Nginx核心100讲笔记_第81张图片

结果:403,valid,valid,valid,403,valid,403,valid

3.8 map模块

陶辉Nginx核心100讲笔记_第82张图片陶辉Nginx核心100讲笔记_第83张图片

3.9 split_clients模块

陶辉Nginx核心100讲笔记_第84张图片

3.10 geo模块

陶辉Nginx核心100讲笔记_第85张图片

3.11 geoip模块

陶辉Nginx核心100讲笔记_第86张图片陶辉Nginx核心100讲笔记_第87张图片

3.12 keepalive


四、反向代理和负载均衡

4.1 基本介绍

4.1.1 负载均衡

陶辉Nginx核心100讲笔记_第88张图片

一个服务的扩展方向:

A:水平扩展,加机器;

B:纵向扩展:把业务复杂的服务,拆分为业务小的服务,上层nginx通过location把请求分发到不同的服务中去;

C:Z轴扩展:基于用户的信息进行扩展。例如根据请求ip或者其他信息,把请求分发到特定的服务中去;

4.1.2 反向代理

陶辉Nginx核心100讲笔记_第89张图片

4.1.3 缓存

时间缓存:Nginx从下游服务拿到信息后,一边发给客户端,一边把返回内容缓存在nginx中;

空间缓存:上游服务请求nginx,nginx可以预请求下游服务,把数据缓存到nginx中;

4.2 负载均衡策略

4.2.1 upstream与server指令

陶辉Nginx核心100讲笔记_第90张图片

  • 加权Round-Robin负载均衡算法:

  • 对下游服务使用keepalive长链接:

陶辉Nginx核心100讲笔记_第91张图片

  • upstream_keepalive指令:

陶辉Nginx核心100讲笔记_第92张图片

keepalive:nginx和下游服务最多保持多少个空闲的http连接

keepalive_request:一个tcp最多跑多少个请求

keepalive_timeout:一个tcp连接空闲多少秒后关闭

  • resolver指令

陶辉Nginx核心100讲笔记_第93张图片

官方解释下就是:反向代理的场景,upstream后端用域名时,配置resolver以便于nginx能够解析该域名。

当proxy_pass 后面接变量时,而且设置了resolver,会把变量的负载值通过resolver来解析,其他情况通过本地dns服务,etc或host 来解释域名。

https://www.jianshu.com/p/5caa48664da5

4.3 负载均衡哈希算法

4.3.1 upstream_ip_hash模块

陶辉Nginx核心100讲笔记_第94张图片

4.3.2 upstream_hash模块

陶辉Nginx核心100讲笔记_第95张图片

4.3.3 演示
upstream iphashtest { 
	ip_hash;
	hash user_$arg_username;#使用username作为hash算法的关键字
	server 127.0.0.1:8011;
	server 127.0.0.1:8012;
}

4.4 一致性hash算法

使用hash算法,下游服务器异常会导致大量请求的路由策略失效。一致性hash算法能有效解决该问题。

陶辉Nginx核心100讲笔记_第96张图片陶辉Nginx核心100讲笔记_第97张图片

把0-232围成一个环,4个服务均有的分布在环上,0-230请求第一个服务,以此类推;

扩容后:

陶辉Nginx核心100讲笔记_第98张图片

扩容后只会改变node2—node4前半段的hash点。

4.4.1 使用方法

陶辉Nginx核心100讲笔记_第99张图片

4.5 最小连接数算法

4.5.1 upstream_least_conn模块

陶辉Nginx核心100讲笔记_第100张图片

4.6 怎么跨worker生效:upstream_zone模块

陶辉Nginx核心100讲笔记_第101张图片

如上所有算法均可以使用upstream_zone来使得所有worker生效。

4.7 upstream模块间的顺序

陶辉Nginx核心100讲笔记_第102张图片

4.8 http upstream提供的变量

4.9 反向代理

4.9.1 http反向代理proxy处理请求的流程

4.9.2 proxy模块

陶辉Nginx核心100讲笔记_第103张图片陶辉Nginx核心100讲笔记_第104张图片

  • 案例

陶辉Nginx核心100讲笔记_第105张图片

http://proxyups/addurl会被换为:http://proxyups/a

4.9.3 修改请求下游服务的的请求

陶辉Nginx核心100讲笔记_第106张图片陶辉Nginx核心100讲笔记_第107张图片

4.10 接收用户请求body

client_body_buffer_size:Nginx分配给请求数据的Buffer大小,如果请求的数据小于client_body_buffer_size直接将数据先在内存中存储。如果请求的值大于client_body_buffer_size小于client_max_body_size,就会将数据先放到client_body_buffer_size的内存中,再一遍一遍地写到临时文件中。

client_body_in_single_buffer:客户端请求数据的body一律存储到内存buffer中。当然,如果HTTP包体的大小超过了下面client_body_buffer_size设置的值,包体还是会写入到磁盘文件中。

陶辉Nginx核心100讲笔记_第108张图片

client_max_body_size 默认 1M,表示 客户端请求服务器最大允许大小,在“Content-Length”请求头中指定。如果请求的正文数据大于client_max_body_size,HTTP协议会报错 413 Request Entity Too Large。就是说如果请求的正文大于client_max_body_size,一定是失败的。如果需要上传大文件,一定要修改该值。

陶辉Nginx核心100讲笔记_第109张图片陶辉Nginx核心100讲笔记_第110张图片

2次读取body时间超过60s后,返回408.

4.11 连接下游服务器

陶辉Nginx核心100讲笔记_第111张图片
当与下游服务建立连接超时时,再换一台服务器重新连接。

4.11.1 TCP keepalive

关闭无用的连接,减少资源浪费。

陶辉Nginx核心100讲笔记_第112张图片

使用操作系统设置的默认keepalive相关配置来控制tcp的keepalive来降低资源使用。

4.11.2 HTTP keepalive

陶辉Nginx核心100讲笔记_第113张图片

4.11.3 修改TCP连接中的local address

陶辉Nginx核心100讲笔记_第114张图片

proxy_bind隶属于proxy_module,为向后端建立连接时的local ip,在nginx源码中只支持bind一个ip进行回源,若想使用多个ip进行回源时,可以修改源码支持bind ip数组。在实际应用中我就是这样做的。bind ip数据轮询选择ip进行回源与upstream建立连接,以解决单ip回源连接数限制问题。

proxy_bind:它的用法主要有两类用途,第一类用途就是当我们nginx上有多个ip地址时,可能有多个路由的策略是不同的,比如内网或者外网等,这个时候不要使用系统默认给我们选择的ip地址,而是主动使用一个ip地址。这个时候用proxy_bind。第二种场景,很可能为了传递一个ip地址,就是透传ip地址的策略,比如在stream反向代理中会很常用,在之后还会详述。这里先说下proxy_bind用法。

proxy_bind $remote_addr 也就是客户端的地址绑定到这里。绑定变量的时候呢,如果地址不是本地的地址,linux必须要加transparent。非linux操作系统呢需要保证worker进程有root 权限的,才能人为的修改socket的local address。

陶辉Nginx核心100讲笔记_第115张图片陶辉Nginx核心100讲笔记_第116张图片

4.12 接收下游的响应

4.12.1 接收下游服务的响应头部

陶辉Nginx核心100讲笔记_第117张图片

proxy_buffer_size:限定了接收自上游的http response中header的最大值。所以当上游的server发送了http响应,如果有set cookie这种特别长的header可能就会导致整个全部的response header超出了这个值。超出完之后这个请求就不能够被nginx正确的处理了。我们的error.log中会看到upstream sent too big header
就是这样的一个原因。

4.12.2 接收下游服务的响应body

陶辉Nginx核心100讲笔记_第118张图片

proxy_buffering:来控制我们是不是先接收完整的包体,接收完了才开始转发。或者说不接收完,而是每接收一部分就同步的向客户端发送我收到的那部分响应。这两种方式各有各的好处。通常情况下默认开启(on)。因为我们认为上游服务和我们nginx走的是内网,网速更快。如果我们边发边接收上游边往客户端发。因为客户端跟nginx之间的网速可能很慢。所以就会导致,对于比较大的body 的时候,nginx长时间与上游建立连接。而上游比如说tomcat、Django等它们的并发能力是很弱的。当然如果我们用了proxy_buffering off 它的优点是能让客户端及时接收到响应,特别是一些大包体的情况下。客户端不用再等待。

在我们接收上游发来的HTTP包体,即使我们开启了proxy_buffering on也并不一定向磁盘中写入包体,因为如果包体非常的小,在内存中就可以放入的话,就没有必要写到磁盘中,因为磁盘io总是比较慢的。所以这个时候就有了proxy_buffers指令。也就是包体大小没有超过这个设定值就不用写入磁盘。否则的话就要写入磁盘了。

陶辉Nginx核心100讲笔记_第119张图片

proxy_buffering ,默认开启,希望尽快释放上游服务器的连接,当然proxy_buffering 还有一个nginx特定的header。这个header(X-Accel-Buffering头部)只有nginx才会认。当上游的tomcat 如果在response中加入X-Accel-Buffering头部,如果配置为yes,就会强制要求nginx先接收完上游的http body 再向client发送。也就是它会替换指定的内容。

当我们向磁盘中写入包体的时候还有三个指令,proxy_max_temp_file_size、proxy_temp_file_write_size、proxy_temp_path。

proxy_max_temp_file_size:限制写入磁盘中这个文件的最大值。如果上游服务中返回了非常大的文件超出了临时文件大小也会出错的。默认是1G。

proxy_temp_file_write_size:每一次向磁盘文件中写入的字节数。

proxy_temp_path:设定了存放临时文件的目录在哪里,以及目录level层级。

4.12.3 及时转发body

陶辉Nginx核心100讲笔记_第120张图片

proxy_busy_buffers_size。虽然被缓存所有的响应,我们希望更及时的向客户端发送部分响应。比如我们收到1G文件。当我们接收到前8k或前16k(proxy_busy_buffers_size 8k|16k)的时候,就先向客户端转发接收到的这一部分响应的话就可以使用proxy_busy_buffers_size 。

4.12.4 接收下游服务时网络速度相关指令

陶辉Nginx核心100讲笔记_第121张图片

proxy_read_timeout:两次读取操作之间最多60秒的超时。两次读取是一个TCP层的一个概念。

proxy_limit_reate:限速,和客户端limit_rate 有些类似,但是它限制的是读取上游的响应,而不是发送给上游服务的网速。设置为0表示不限制读取上游响应的速度。

4.12.5 上游body的持久化

陶辉Nginx核心100讲笔记_第122张图片
proxy_store_access:配置指定目录权限。

proxy_store:把临时文件改名到root对应的目录下,默认不开启,如果是string,可再次指定,使用变量的方式,指定这个文件存放的位置。

4.13 处理下游响应头部

4.13.1 返回响应-加工响应内容

我们接收到了上游发来的http header跟http body,其实对上游发来的http header是有很多控制nginx行为的这样一些头部的。我们在反向代理这一层也可以去修改上游发来的header中的内容,以及它们所产生的效用。接下来看看这两种行为是怎么发生的。

第三部分讲的http 过滤模块。当我们生成的响应向客户端发送的时候。这个内容必须经历过滤模块的处理。对于nginx作为反向代理的时候也是同样的。nginx下游服务返回的一些header会被那些过滤模块处理(图中)。

比如ngx_http_modified_filter_module,它根据上游服务返回的cache control等等这些header,去修改到底是发送200还是304响应码给客户端。所以上游一些header的内容会改变作为反向代理的nginx的行为。

  • proxy_ignore_header指令

proxy_ignore_header可以禁止某些响应头改变nginx行为。

陶辉Nginx核心100讲笔记_第123张图片

  • proxy_hide_header指令

nginx提供了一个指令proxy_ignore_header,禁用上游中一些header 的功能。当然不是所有的header 都具有功能,这个指令只针对于具有特殊功能的header才发生作用。

陶辉Nginx核心100讲笔记_第124张图片
说明:
(1)X-Pad:是apache 使用的header,目前已经很少用了。
(2)X-Aceel-:只有nginx才认。
(3)如果上述这四类header你想发送给客户端,就使用proxy_pass_header。

  • 修改返回的set-cookie头部

陶辉Nginx核心100讲笔记_第125张图片
修改下游服务器response header中的头部set-cookie中的内容。proxy_cookie_domain修改下游服务器返回的cookie中的域名;

  • 修改返回的Location头部

proxy_dedirect:对于我们上游服务发送的响应中有一个location,location后面的url可以做一次替换。

陶辉Nginx核心100讲笔记_第126张图片

4.13.2 处理返回响应演示

(1)反向代理服务配置:
陶辉Nginx核心100讲笔记_第127张图片
(2)下游服务配置:
陶辉Nginx核心100讲笔记_第128张图片
直接访问localhost:8012如下所示有个aaa的header:
陶辉Nginx核心100讲笔记_第129张图片
访问反向代理服务时也有个aaa的header:
陶辉Nginx核心100讲笔记_第130张图片
(3)禁用反向代理服务的aaa:

proxy_hide_header aaa;

再次访问反向代理服务,发现没有了aaa的header。
(4)打开proxy_pass_header,可以把下游服务的nginx版本返回给客户端:

proxy_pass_header server

再次访问反向代理服务,发现server是nginx 1.15.6而非反向代理的openresty。

总结:以上几节课包括从proxy_pass指令来指定由反向代理来指定请求到生成向上游发送请求的内容,以及接收客户端发来的http body并与上游服务建立连接并上游服务的响应内容以及处理响应头部,以上几个环节,就是nginx作为反向代理处理客户端与上游服务之间的所有流程。

4.13.3 下游返回失败时处理方法

我们讨论了nginx作为反向代理时,从客户端接收http body,到完整的接收下游的响应并转发响应的流程。其中在nginx与下游服务建立连接时。提到过proxy_next_upstream指令,这个指令可以在第一台的错误的响应后重新选择另一台下游服务器处理请求返回给客户端这样的功能。

陶辉Nginx核心100讲笔记_第131张图片
能够生效的前提是没有向客户端发送一个字节。只要向客户端已经发送了一个字节了,说明下游的服务已经生效了,就不能选用一个新的下游服务了。它一定是在接收到并开始转发一个字节之前nginx判定为错误,这个功能才能生效。proxy_next_upstream后面可以跟很多不同的参数(error、timeout那些)。
配置:

  • error:

nginx与上游建立连接读取响应,发送请求等等这些过程中,只要出现错误等等。error都可以满足这样的场景。这种错误主要是网络错误。比如TCP层、IP层的错误。

  • timeout:

超时有connection timeout 、read timeout、 write timeout,这个timeout可以命中这些场景。当出现这种场景的时候将执行重选另一个下游服务。

  • invalid_header:

则是我们收到的下游服务http header,它是不合法的。

  • http_:

http_可以跟一个明确的响应code。上游返回一个403或500,其实它既不是网络错误,也不是超时,也不是invalid_header。但是我们就是可以针对这样的错误从新选择一个新的upstream上游去处理。

  • non_idempotent:

根据RFC 7231文档中规定了post、lock等method的请求。在下游服务不能使用next_upstream上游服务的,去重选一个新的服务时候,当我们配置了这个non_idempotent就可以启用proxy_next_upstream功能。

  • off:

关闭 proxy_next_upstream功能。

两个相关指令:

proxy_next_upstream_timeout 超时时间;proxy_next_upstream_tries 重试次数

陶辉Nginx核心100讲笔记_第132张图片

4.13.4 下游返回失败时处理演示

反向代理配置:
陶辉Nginx核心100讲笔记_第133张图片
下游服务:

(1)关闭proxy_next_upstream,访问反向代理服务就会在8011和8012端口服务上轮询
(2)打开proxy_next_upstream,且关闭下游8013服务,访问反向代理服务,一直是8011服务做响应。
(3)修改反向代理服务配置:

location /httperr {
	proxy_next_upstream http_500;//下游服务返回500时生效
	proxy_pass http://nextups;
}

访问反向代理服务,一直是8011服务做响应。

4.13.5 使用error_page拦截下游失败响应

当下游响应码大于等于 300时,就应该使用error_page来处理请求返回给客户端。

image.png
proxy_intercept_errors 默认off。这个时候上游返回怎样的响应,客户端就会原封不动的拿到这个响应。比如上游返回来一个404,我们的error_page 配置的404是不会生效的。只有把proxy_intercept_errors 设置为on的时候error_page 就会生效了。

  • 演示:

代理服务配置:
陶辉Nginx核心100讲笔记_第134张图片
proxy_intercept_errors 为on时,配置了error_page,发现500错误码的时候返回test1.txt。

4.14 对下游使用SSL连接

陶辉Nginx核心100讲笔记_第135张图片
Nginx提供以上4种关于证书的指令。

  • 对上游使用证书

陶辉Nginx核心100讲笔记_第136张图片

  • 验证上游证书

陶辉Nginx核心100讲笔记_第137张图片

  • 对下游使用证书

陶辉Nginx核心100讲笔记_第138张图片

  • 验证下游证书

陶辉Nginx核心100讲笔记_第139张图片

4.14.1 SSL模块提供的变量

陶辉Nginx核心100讲笔记_第140张图片

4.14.2 创建证书命令示例

陶辉Nginx核心100讲笔记_第141张图片

4.15 浏览器缓存

在互联网中使用缓存是最有效的提升访问速度的方法。在web服务器场景中不仅要考虑nginx作为缓存服务时的使用方法,还要考虑浏览器缓存生效的场景。浏览器的缓存是否生效可以通过nginx的指令去控制。而浏览器的缓存对用户的体验提升也是最大的。

4.15.1 浏览器缓存和Nginx缓存的比较

陶辉Nginx核心100讲笔记_第142张图片

4.15.2 浏览器缓存

陶辉Nginx核心100讲笔记_第143张图片
  • Etag头部

陶辉Nginx核心100讲笔记_第144张图片
陶辉Nginx核心100讲笔记_第145张图片

  • If-None-Match

  • If-Modified-Since

陶辉Nginx核心100讲笔记_第146张图片
Last-Modified:比较简单,也就是我们访问的资源,比如我们使用了一个js文件,这个js文件的在服务器上上次被修改时间。

4.16 Nginx决策浏览器过期缓存是否有效

4.16.1 Expires指令

陶辉Nginx核心100讲笔记_第147张图片
演示:

4.16.2 not_modified过滤模块

陶辉Nginx核心100讲笔记_第148张图片

not_modified过滤模块处理过程:
陶辉Nginx核心100讲笔记_第149张图片

  • if_modified_since

陶辉Nginx核心100讲笔记_第150张图片

  • If-Match

  • If-Unmodified-Match

陶辉Nginx核心100讲笔记_第151张图片

4.17 Nginx缓存

这节课介绍在nginx之上配置上游服务器返回的响应的缓存。会涉及到一些指令的值,它是与第二部分课程中介绍过nginx进程结构的时候谈到的Cache Manager、Cache Loader 这两个进程。
陶辉Nginx核心100讲笔记_第152张图片

4.17.1 nginx的cache使用

内容是放到磁盘上的,但是它的元素信息为了加快访问是放到内存中的。所以首先在proxy_cache_path指令中定义好共享内存。因为我们有多个worker进程,所以这些元信息一定是在共享内存中的。第二个定义在磁盘中哪个位置去存放缓存文件。proxy_cache_path定义好以后,其中keys_zone的name就是共享内存的名字,size就是共享内存的大小。共享内存的名字就是给proxy_cache使用的。也就是在proxy_cache_path定义了一批缓存文件存放的位置和共享内存的名称。也许有很多location,它们定义了各自独立的缓存的key或缓存策略。但是它们都可以使用同一个proxy_cache_path指定的keys_zone。所以proxy_cache在location中可以通过这个zone指定使用哪一个proxy_cache中的设置。

4.17.2 proxy_cache_path

陶辉Nginx核心100讲笔记_第153张图片陶辉Nginx核心100讲笔记_第154张图片
use_temp_path:使用这个临时文件目录,最后改名都会放到path中。但为什么会有这个设置呢?是因为,很可能nginx所在的机器中有多个文件系统,甚至有些网络文件系统。如果我们开始的use_temp_path 目录是在一个磁盘上,而path是在另外一个磁盘上。跨磁盘复制是在cp文件。如果在一个磁盘上,那最后的改名也只是改名而已。
陶辉Nginx核心100讲笔记_第155张图片

4.17.3 proxy_cache_valid: 缓存什么样的响应

陶辉Nginx核心100讲笔记_第156张图片

4.17.4 proxy_no_cache: 什么样的响应不缓存

陶辉Nginx核心100讲笔记_第157张图片

proxy_cache_convert_head:默认为on,会把header方法转换成get方法。

4.17.5 upstream_cache_status变量

陶辉Nginx核心100讲笔记_第158张图片
EXPIRED:表示nginx cache_vaild设置的时间还没有过期,用户的请求获取到缓存,但是上游服务器指定的缓存时间也许是小于cache_vaild设置的时间,根据上游的说法来说缓存已经过期了,但nginx配置的时候,这个缓存仍然在使用。所以和这个时候是EXPIRED,缓存已经过期。

4.18 对客户端请求的缓存处理

补充说明:

proxy_cache_methods GET | POST|HEAD...//对哪些请求方法使用缓存

4.19 接收下游响应缓存处理

补充说明:

  • X-Accel-Expires头部:

从下游服务定义缓存多少时间(0不缓存;@前缀表示缓存当天的某个时间)

  • Vary头部:

陶辉Nginx核心100讲笔记_第159张图片

  • Set-Cookie:

陶辉Nginx核心100讲笔记_第160张图片

4.19.1 缓存流程

陶辉Nginx核心100讲笔记_第161张图片

4.19.2 使用分片提示缓存效率
  • slice模块

陶辉Nginx核心100讲笔记_第162张图片

  • slice模块运行流程

陶辉Nginx核心100讲笔记_第163张图片

4.19.3 open_flie_cache提示系统性能

陶辉Nginx核心100讲笔记_第164张图片

  • 缓存元信息

陶辉Nginx核心100讲笔记_第165张图片

  • 其他open_flie_cache指令

陶辉Nginx核心100讲笔记_第166张图片

  • 案例

下游服务配置:
陶辉Nginx核心100讲笔记_第167张图片
第一次访问:

第二次访问:

4.20 Nginx缓存失效时如何减轻下游服务压力

nginx重启或者意外退出时,所以缓存就会失效,这个时候接收下游服务全部穿透Nginx打到下游服务,导致下游服务压力剧增。

4.20.1 合并回源请求


4.20.1 减少回源请求

陶辉Nginx核心100讲笔记_第168张图片
proxy_cache_use_stale:第一个请求来了后打到下游服务,后续的请求给客户端响应旧的缓存内容,直至第一个请求的下游响应被缓存。

对应缓存有问题的响应:
陶辉Nginx核心100讲笔记_第169张图片
例子:
陶辉Nginx核心100讲笔记_第170张图片
proxy_cache_background_update:第一个请求来了把旧的缓存响应给客户端,同时向下游服务发送一个子请求,后续的请求给客户端响应旧的缓存内容。直至第一个请求的子请求收到下游服务响应内容后,更新缓存,后续的请求均可使用到新缓存。

4.21 及时清除缓存

陶辉Nginx核心100讲笔记_第171张图片

4.22 http反向代理和uwcgi、fastcgi、scgi反向代理的指令对照

4.22.1 构造请求内容的指令对照

陶辉Nginx核心100讲笔记_第172张图片

4.22.2 建立连接并发送请求的指令对照

陶辉Nginx核心100讲笔记_第173张图片

4.22.3 接收下游响应的指令对照


4.22.4 转发响应的指令对照


4.22.5 SSL的指令对照


4.22.6 缓存的指令对照


4.22.7 独有配置

陶辉Nginx核心100讲笔记_第174张图片

4.23 memcached反向代理用法

陶辉Nginx核心100讲笔记_第175张图片

4.23.1 memcached指令

陶辉Nginx核心100讲笔记_第176张图片
演示:
代理服务器配置:
image.png

[root]:#curl xxx.com/get?key=hello
[root]:#world//取出了hello的值

补充说明:
memcached_gzip_flag:如果设置的key使用了gzip压缩,取出的时候需要这个指令来标识。

4.24 webSocket反向代理

  • 功能

由nginx_http_proxy_module模块实现

  • 配置

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
陶辉Nginx核心100讲笔记_第177张图片

websocket协议帧

陶辉Nginx核心100讲笔记_第178张图片陶辉Nginx核心100讲笔记_第179张图片

websocket协议和扩展

陶辉Nginx核心100讲笔记_第180张图片

测试

陶辉Nginx核心100讲笔记_第181张图片

4.25 HTTP2.0

4.25.1 http2.0特性

陶辉Nginx核心100讲笔记_第182张图片

4.25.2 http2.0核心概念

陶辉Nginx核心100讲笔记_第183张图片

  • 协议分层:

陶辉Nginx核心100讲笔记_第184张图片

  • 多路复用

陶辉Nginx核心100讲笔记_第185张图片

  • 传输无序,接收时组装

陶辉Nginx核心100讲笔记_第186张图片

  • 数据流优先级

陶辉Nginx核心100讲笔记_第187张图片

  • 标头压缩

陶辉Nginx核心100讲笔记_第188张图片

  • Frame格式

陶辉Nginx核心100讲笔记_第189张图片

  • 服务器PUSH

陶辉Nginx核心100讲笔记_第190张图片

4.25.3 搭建http2.0服务并推送资源
  1. 使用模块ngx_http_v2_module

陶辉Nginx核心100讲笔记_第191张图片

  1. 推送资源

陶辉Nginx核心100讲笔记_第192张图片

  1. 测试


服务器配置:

设置了http2_push和http3_push_preload

陶辉Nginx核心100讲笔记_第193张图片
请求:nghttp2 -ns https://localhost:4430/
image.png
请求:nghttp2 -ns https://localhost:4430/test/test.html
image.png

  1. 其他指令
  • 最大并行推送数

image.png

  • 超时控制

陶辉Nginx核心100讲笔记_第194张图片

  • 并发请求控制

陶辉Nginx核心100讲笔记_第195张图片

  • 连接最大请求数

陶辉Nginx核心100讲笔记_第196张图片

  • 缓存区大小设置

陶辉Nginx核心100讲笔记_第197张图片

4.26 grpc反向代理

协议:grpc协议(https://grpc.io)
模块:ngx_http_grpc_module,默认开启,可以通过without–ngx_http_grpc_module禁用
依赖:ngx_http_v2_module模块

2.26.1 grpc代理和http反向代理指令对照


4.27 传输层stream四层反向代理的七个阶段

  • 七个阶段

陶辉Nginx核心100讲笔记_第198张图片

  • stream模块的ssl阶段

陶辉Nginx核心100讲笔记_第199张图片

  • content阶段return模块

陶辉Nginx核心100讲笔记_第200张图片

4.27.1 常用变量

陶辉Nginx核心100讲笔记_第201张图片
陶辉Nginx核心100讲笔记_第202张图片
陶辉Nginx核心100讲笔记_第203张图片

  • 系统变量

  • 演示

服务器配置:
陶辉Nginx核心100讲笔记_第204张图片
连接:
telnet localhost:10004,返回如下:
陶辉Nginx核心100讲笔记_第205张图片

4.27.2 POST_ACCEPT阶段realip模块

proxy_protocol协议

陶辉Nginx核心100讲笔记_第206张图片 Nginx读取proxy_protocol协议超时控制:
陶辉Nginx核心100讲笔记_第207张图片

stream处理proxy_protocol流程

陶辉Nginx核心100讲笔记_第208张图片

post_accept阶段:realip模块

陶辉Nginx核心100讲笔记_第209张图片

演示

服务器配置:
陶辉Nginx核心100讲笔记_第210张图片
连接:
陶辉Nginx核心100讲笔记_第211张图片

4.27.3 PREACCESS阶段limit_conn模块限制并发

陶辉Nginx核心100讲笔记_第212张图片

limit_conn模块指令

陶辉Nginx核心100讲笔记_第213张图片

4.27.4 ACCESS阶段access模块限制ip

陶辉Nginx核心100讲笔记_第214张图片

access模块指令

陶辉Nginx核心100讲笔记_第215张图片

4.27.5 LOG阶段stream_log模块记录日志

陶辉Nginx核心100讲笔记_第216张图片

4.27.6 stream四层反向代理处理SSL上游客户端请求

stream模块TSL/SSL应用场景

陶辉Nginx核心100讲笔记_第217张图片

stream中的ssl

陶辉Nginx核心100讲笔记_第218张图片

对比stream模块的ssl和http模块的ssl配置

陶辉Nginx核心100讲笔记_第219张图片image.pngimage.png

stream中的ssl模块提供的变量

陶辉Nginx核心100讲笔记_第220张图片 陶辉Nginx核心100讲笔记_第221张图片

stream ssl模块实战

陶辉Nginx核心100讲笔记_第222张图片

反向代理配置:
image.png
下游服务配置:
陶辉Nginx核心100讲笔记_第223张图片
收到上游带ssl的请求,剥离调ssl证书,向下游服务发送请求。

stream_preread取出ssl关键信息

陶辉Nginx核心100讲笔记_第224张图片
陶辉Nginx核心100讲笔记_第225张图片
实战:
陶辉Nginx核心100讲笔记_第226张图片
反向代理层根据域名代理到不同的下游服务。

4.27.7 stream proxy四层反向代理的用法

陶辉Nginx核心100讲笔记_第227张图片

proxy模块对上下游的的限速指令

陶辉Nginx核心100讲笔记_第228张图片

反向代理相关指令

陶辉Nginx核心100讲笔记_第229张图片陶辉Nginx核心100讲笔记_第230张图片

4.28 UDP反向代理

基本流程:
陶辉Nginx核心100讲笔记_第231张图片
简要说明:
陶辉Nginx核心100讲笔记_第232张图片
实战:
陶辉Nginx核心100讲笔记_第233张图片

4.29 透传IP地址的3种解决方案

方案一:protocol协议
方案二:修改IP报文
陶辉Nginx核心100讲笔记_第234张图片
陶辉Nginx核心100讲笔记_第235张图片
B–>A:
陶辉Nginx核心100讲笔记_第236张图片

陶辉Nginx核心100讲笔记_第237张图片


五、Nginx的系统层性能优化

优化方法论:
陶辉Nginx核心100讲笔记_第238张图片

5.1 内存效率

5.1.1 用tcmalloc优化内存分配

tcmalloc是什么?

陶辉Nginx核心100讲笔记_第239张图片

使用方法?

陶辉Nginx核心100讲笔记_第240张图片

5.2 CPU效率

5.2.1 如何增大Nginx使用CPU的有效时长?

陶辉Nginx核心100讲笔记_第241张图片

worker进程数等于cpu核数
worker_process number | auto #一般设置为cpu核数

为何一个CPU能同时运行多个进程?
陶辉Nginx核心100讲笔记_第242张图片

确保进程在运行态

陶辉Nginx核心100讲笔记_第243张图片

减少进程间切换

陶辉Nginx核心100讲笔记_第244张图片

延迟处理新连接

陶辉Nginx核心100讲笔记_第245张图片

如何查看上下文切换次数?
陶辉Nginx核心100讲笔记_第246张图片
什么决定CPU时间片的大小?
陶辉Nginx核心100讲笔记_第247张图片
O1调度算法(CFS)
陶辉Nginx核心100讲笔记_第248张图片

设置worker进程的静态优先级

陶辉Nginx核心100讲笔记_第249张图片

5.2.2 多核间的负载均衡

陶辉Nginx核心100讲笔记_第250张图片
使用linux内核3.9以上,打开reuseport,提高性能。

多队列网卡对多核CPU的优化(RSS、RPS、RFS)

陶辉Nginx核心100讲笔记_第251张图片

绑定worker到指定CPU,提升CPU的缓存利用率

陶辉Nginx核心100讲笔记_第252张图片
worker_cpu_affinity:
陶辉Nginx核心100讲笔记_第253张图片

NUMA架构,提升CPU访问内存的效率

陶辉Nginx核心100讲笔记_第254张图片

5.3 网络效率

5.3.1 控制TCP三次握手参数


SYN_SENT状态

陶辉Nginx核心100讲笔记_第255张图片

主动建立连接时应用层超时时间

陶辉Nginx核心100讲笔记_第256张图片

SYN_RECVD状态

陶辉Nginx核心100讲笔记_第257张图片

Linux服务器处理三次握手

陶辉Nginx核心100讲笔记_第258张图片

5.3.2 建立TCP连接的优化

如何应对SYN攻击

陶辉Nginx核心100讲笔记_第259张图片

设置tcp_syncookies

陶辉Nginx核心100讲笔记_第260张图片

设置句柄数上线

陶辉Nginx核心100讲笔记_第261张图片

设置worker进程最大连接数量

陶辉Nginx核心100讲笔记_第262张图片

设置两个队列的长度

陶辉Nginx核心100讲笔记_第263张图片

开启TCP Fast Open

陶辉Nginx核心100讲笔记_第264张图片
说明:正常TCP三次握手需要等待server返回syn+ack后,发送ack+http请求,fast open tcp是第一次建立连接后,client保存cookie,第二次直接带上cookie请求sever,减少前面2次握手。
陶辉Nginx核心100讲笔记_第265张图片

5.3.3 传输数据阶段滑动窗口和读写缓冲区

滑动窗口

陶辉Nginx核心100讲笔记_第266张图片
通告窗口?
收到对方的syn后,在回复ack时需要告诉请求方我还有多大的空间接收你的内容,这就是通告窗口。
陶辉Nginx核心100讲笔记_第267张图片

发送TCP消息

陶辉Nginx核心100讲笔记_第268张图片

TCP接收消息

陶辉Nginx核心100讲笔记_第269张图片

TCP接收消息发生CS(进程间切换)

陶辉Nginx核心100讲笔记_第270张图片

TCP消息接收时新报文到达

陶辉Nginx核心100讲笔记_第271张图片

Nginx的超时指令和滑动窗口

陶辉Nginx核心100讲笔记_第272张图片

TCP传输时的丢包重试

陶辉Nginx核心100讲笔记_第273张图片

5.3.4 优化缓冲区和传输效率

TCP缓冲区

陶辉Nginx核心100讲笔记_第274张图片

TCP调整接收窗口和应用缓存

陶辉Nginx核心100讲笔记_第275张图片
BDP=带宽*时延,吞吐量=窗口/时延
陶辉Nginx核心100讲笔记_第276张图片

禁用Nagle算法?

陶辉Nginx核心100讲笔记_第277张图片

Nginx可以避免发送小报文

陶辉Nginx核心100讲笔记_第278张图片

启用CORK算法

陶辉Nginx核心100讲笔记_第279张图片

5.3.5 慢启动和拥塞窗口

滑动窗口:发送方主动限制流量
滑动窗口:接收方限制限制流量
实际流量:滑动窗口和滑动窗口的最小值

拥塞窗口

陶辉Nginx核心100讲笔记_第280张图片

RTT和RTO

陶辉Nginx核心100讲笔记_第281张图片

5.3.6 TCP协议的keepalive功能

应用场景

检查实际断连的连接
用于维持和客户端的防火墙有活跃的网络包

设置

陶辉Nginx核心100讲笔记_第282张图片

5.3.7 减少关闭连接时的time_wait端口数量

陶辉Nginx核心100讲笔记_第283张图片

服务器被动关闭连接端的状态

陶辉Nginx核心100讲笔记_第284张图片

服务器主动关闭连接端的状态

陶辉Nginx核心100讲笔记_第285张图片

优化time_wait

time_wait状态过短或者不存在会怎么样?
陶辉Nginx核心100讲笔记_第286张图片

tcp_tw_reuse

陶辉Nginx核心100讲笔记_第287张图片 陶辉Nginx核心100讲笔记_第288张图片

5.3.8 lingering_close延迟关闭TCP连接

lingering_close延迟的意义?

image.png

lingering配置指令

陶辉Nginx核心100讲笔记_第289张图片

以RTS代替正常的四次握手关闭连接

陶辉Nginx核心100讲笔记_第290张图片

5.3.9 应用层协议优化

TLS/SSL优化握手性能

陶辉Nginx核心100讲笔记_第291张图片

TLS/SSL中的会话票证tickets

陶辉Nginx核心100讲笔记_第292张图片

HTTP长链接

陶辉Nginx核心100讲笔记_第293张图片

gzip压缩模块

陶辉Nginx核心100讲笔记_第294张图片
压缩哪些请求的响应?
陶辉Nginx核心100讲笔记_第295张图片
是否压缩下游的响应?
陶辉Nginx核心100讲笔记_第296张图片
其他压缩参数:
陶辉Nginx核心100讲笔记_第297张图片

升级更高效的http2.0协议

陶辉Nginx核心100讲笔记_第298张图片

5.4 磁盘IO效率

陶辉Nginx核心100讲笔记_第299张图片

5.4.1 大致优化方向

减少磁盘IO

陶辉Nginx核心100讲笔记_第300张图片

直接IO绕开磁盘高速缓存

陶辉Nginx核心100讲笔记_第301张图片
直接IO适用于大文件:
陶辉Nginx核心100讲笔记_第302张图片

异步IO

陶辉Nginx核心100讲笔记_第303张图片
陶辉Nginx核心100讲笔记_第304张图片

异步读IO线程池

陶辉Nginx核心100讲笔记_第305张图片
做静态资源服务读取文件时使用异步读IO线程池:
image.png

异步IO缓存

陶辉Nginx核心100讲笔记_第306张图片

5.4.2 减少磁盘读写次数

empty_gif模块

陶辉Nginx核心100讲笔记_第307张图片

access日志的压缩

陶辉Nginx核心100讲笔记_第308张图片

error.log日志输出到内存

陶辉Nginx核心100讲笔记_第309张图片

syslog协议

陶辉Nginx核心100讲笔记_第310张图片
陶辉Nginx核心100讲笔记_第311张图片
rsyslog与nginx:
陶辉Nginx核心100讲笔记_第312张图片

5.4.3 零拷贝与gzip_static模块

sendfile 零拷贝提升性能

陶辉Nginx核心100讲笔记_第313张图片
注意:直接IO会自动禁用sendfile
陶辉Nginx核心100讲笔记_第314张图片

gzip_static模块

陶辉Nginx核心100讲笔记_第315张图片

gunzip模块

陶辉Nginx核心100讲笔记_第316张图片

5.5 监控分析Nginx运行状态

5.5.1 使用gperftools定位Nginx性能问题

陶辉Nginx核心100讲笔记_第317张图片
文本展示说明:
陶辉Nginx核心100讲笔记_第318张图片

5.5.2 使用stub_status模块监控Nginx状态

陶辉Nginx核心100讲笔记_第319张图片

stub_status模块监控项

陶辉Nginx核心100讲笔记_第320张图片

六、从源码视角深度使用Nginx和OpenResty

6.1 Nginx与第三方模块的关联关系

6.1.1 第三方模块源代码的快速阅读方法

陶辉Nginx核心100讲笔记_第321张图片

config结构

陶辉Nginx核心100讲笔记_第322张图片

configure脚本分析

陶辉Nginx核心100讲笔记_第323张图片

configure执行结果

陶辉Nginx核心100讲笔记_第324张图片
(1)configure概要,使用了哪些库或者功能
(2)一些重要文件的路径

6.1.2 Nginx启动流程

HTTP第三方模块初始化

陶辉Nginx核心100讲笔记_第325张图片

HTTP模块的11个阶段:初始化

陶辉Nginx核心100讲笔记_第326张图片

添加模块到11个阶段的两种常用方式

陶辉Nginx核心100讲笔记_第327张图片

过滤模块的单链表

陶辉Nginx核心100讲笔记_第328张图片

添加过滤模块的方式

陶辉Nginx核心100讲笔记_第329张图片

6.1.3 Rewrite脚本

协程与Rewrite脚本

陶辉Nginx核心100讲笔记_第330张图片

Rewrite脚本设置变量

陶辉Nginx核心100讲笔记_第331张图片

脚本式编程:指令的实现

陶辉Nginx核心100讲笔记_第332张图片

6.1.4 if指令

当if指令块连续出现时

image.png
说明:当if指令连续出现时,最后一个if为真的模块将一直影响到该模块结束。

if指令出现问题的根本原因

陶辉Nginx核心100讲笔记_第333张图片

if指令的正确姿势

陶辉Nginx核心100讲笔记_第334张图片

6.1.5 解读Nginx核心转储文件(coredump)

coredump核心转储文件

陶辉Nginx核心100讲笔记_第335张图片

gdb调试基本命令

陶辉Nginx核心100讲笔记_第336张图片

启用多进程模式

陶辉Nginx核心100讲笔记_第337张图片

Debug定位问题:出现错误时的应对方案

陶辉Nginx核心100讲笔记_第338张图片

6.1.6 通过debug日志定位问题

控制debug级别error.log日志的输出

陶辉Nginx核心100讲笔记_第339张图片

debug日志类别

陶辉Nginx核心100讲笔记_第340张图片

6.2 OpenResty的用法

6.2.1 OpenResty概述

OpenResty组成部分

陶辉Nginx核心100讲笔记_第341张图片

OpenResty运行机制

陶辉Nginx核心100讲笔记_第342张图片

OpenResty中的SDK

陶辉Nginx核心100讲笔记_第343张图片

OpenResty的使用要点

陶辉Nginx核心100讲笔记_第344张图片

6.2.2 OpenResty中的Nginx模块

核心模块

陶辉Nginx核心100讲笔记_第345张图片

反向代理模块

陶辉Nginx核心100讲笔记_第346张图片

工具模块

陶辉Nginx核心100讲笔记_第347张图片陶辉Nginx核心100讲笔记_第348张图片

6.2.3 OpenResty中的Lua模块

陶辉Nginx核心100讲笔记_第349张图片陶辉Nginx核心100讲笔记_第350张图片陶辉Nginx核心100讲笔记_第351张图片

6.2.4 如何在Nginx中嵌入Lua代码

陶辉Nginx核心100讲笔记_第352张图片

Nginx启动过程中嵌入Lua代码

陶辉Nginx核心100讲笔记_第353张图片

在11个HTTP阶段中嵌入Lua代码

陶辉Nginx核心100讲笔记_第354张图片

控制rewrite/access是否延迟执行Lua代码

陶辉Nginx核心100讲笔记_第355张图片

Http反向代理流程嵌入Lua代码(balancer_by_lua)

陶辉Nginx核心100讲笔记_第356张图片

Http反向代理收到响应-加工响应内容

陶辉Nginx核心100讲笔记_第357张图片

在负载均衡和过滤响应时嵌入Lua代码

陶辉Nginx核心100讲笔记_第358张图片

在OpenSSL处理SSL协议时嵌入Lua代码

陶辉Nginx核心100讲笔记_第359张图片

在Lua代码中获取当前阶段

陶辉Nginx核心100讲笔记_第360张图片

6.2.5 Openresty中Lua和C代码交互原理

Lua FFI


系统级配置指令

陶辉Nginx核心100讲笔记_第361张图片

取得配置参数的SDK


6.2.6 获取、修改请求和响应的SDK

读取、修改变量的SDK

陶辉Nginx核心100讲笔记_第362张图片

客户端提前关闭连接

陶辉Nginx核心100讲笔记_第363张图片

获取请求头部的SDK

陶辉Nginx核心100讲笔记_第364张图片

获取请求URL的SDK

陶辉Nginx核心100讲笔记_第365张图片

获取请求Body的SDK

陶辉Nginx核心100讲笔记_第366张图片

HTTP请求方法名

你可能感兴趣的:(Nginx,Linux,linux,nginx)