Author:liuchao
email:mirschao@gmail.com
github: https://github.com/mirschao
gitee: https://gitee.com/mirschao
快速跳转目录:
nginx高性能web服务中间件第一章 nginx简介及部署方案1.1 nignx的简介1.2 学习nginx的建议1.3 在操作系统上部署nginx中间件第二章 HTTP协议原理2.1 HTTP请求体、响应体2.2 HTTP 响应状态码第三章 nginx中间件服务原理及组成3.1 主配置文件的识别3.2 使用nginx上线前端代码3.3 对上线的项目配置HTTPS3.4 nginx的日志识别3.5 服务集群构建应对大流量访问3.6 location的uri匹配顺序及规则第四章 nginx调优4.1 调优方法论4.2 具体的调优问题和答案4.3 网络层优化建议
Nginx是一个强大的Web服务器, 它可以帮助你构建和管理网站。想象一下, 当你在浏览器中输入一个网址时, Nginx就像一个交通警察, 负责将你的请求引导到正确的目的地。
它的功能很多, 其中一项重要的功能是作为Web服务器, 可以提供网页和文件给用户浏览。它的高性能和可靠性让网站可以快速响应用户的请求, 并处理大量的访问流量。
此外, Nginx还可以作为反向代理服务器, 帮助你隐藏真实的Web服务器, 并将用户请求转发给后端的服务器。这对于保护服务器的安全性和负载均衡非常有帮助, 让你的网站可以同时处理多个请求, 提高用户体验。
Nginx还支持许多其他功能, 如缓存静态内容, 减轻后端服务器的负载;支持SSL/TLS加密, 确保数据传输的安全性;以及提供灵活的配置选项, 让你可以根据你的需求来定制和扩展服务器的功能。
总的来说, Nginx是一个强大而灵活的Web服务器, 可以帮助你提供高性能、安全可靠的网站, 并实现负载均衡和灵活的配置选项。无论是小型网站还是大型应用程序, Nginx都是一个非常有用的工具。
当谈论到Nginx的付费版本和开源版本时, 我们主要是指Nginx Plus(付费版本)和Nginx(开源版本)。下面是它们之间的区别以及开源版本的优势:
功能差异:Nginx Plus相对于开源版本提供了一些额外的高级功能。这些功能包括HTTP/2、流控制、动态更新配置、实时监控和分析、高级负载均衡、健康检查等。这些功能对于大规模和复杂的应用程序可能非常有用。
商业支持:Nginx Plus是由Nginx公司提供商业支持的产品。这意味着你可以获得专业的技术支持、定期的更新和补丁, 以及优先访问新功能。对于企业级应用程序, 这种商业支持可以提供额外的可靠性和信心。
高级负载均衡:Nginx Plus提供了更高级的负载均衡功能, 如Session Persistence、Upstream SSL、IP 黑名单/白名单、动态重载等。这些功能可以提供更强大的负载均衡能力, 确保应用程序的高可用性和性能。
高级监控和分析:Nginx Plus提供实时的监控和分析功能, 可以帮助你深入了解服务器的性能和行为。这些功能包括实时活动监控、性能指标、日志记录等, 有助于快速故障排除和性能优化。
虽然Nginx Plus提供了这些额外的功能和商业支持, 但开源版本的Nginx仍然有许多优势:
开源免费:Nginx是完全免费的开源软件, 你可以自由地使用、修改和分发它。这使得Nginx成为许多人和组织的首选, 尤其是对于那些预算有限的项目。
社区支持:Nginx拥有庞大的用户和开发者社区, 你可以在社区中寻求帮助、分享经验和获取解决方案。这个活跃的社区为开发者提供了丰富的资源和支持。
高性能和稳定性:无论是Nginx Plus还是开源版本, Nginx都以其出色的性能和稳定性而闻名。开源版本的Nginx已经在大量生产环境中得到广泛应用, 并经过了广泛的测试和验证。
可扩展性:开源版本的Nginx具有可扩展的架构, 允许你通过加载模块来扩展其功能。这意味着你可以根据自己的需求选择和定制所需的功能, 使得Nginx非常灵活和适应性强。
总的来说, Nginx Plus在提供额外功能和商业支持方面具有优势, 适用于那些需要高级功能和专业支持的企业级项目。而开源版本的Nginx在免费、社区支持、高性能和可扩展性方面具有优势, 非常适合个人项目和预算有限的应用程序。选择哪个版本取决于你的具体需求和预算限制。
善于使用Nginx开源版本的帮助文档可以帮助你更好地理解和应用Nginx。以下是一些指导, 帮助你充分利用Nginx的帮助文档:
阅读官方文档:Nginx官方网站提供了全面而详细的文档, 包括安装指南、配置指南、模块文档和常见问题解答等。首先, 确保你阅读官方文档并熟悉基本的概念和语法。这将成为你深入学习和理解Nginx的基石。
学会搜索:当你遇到问题或需要了解某个特定主题时, 善于使用搜索引擎。使用相关的关键词和术语来搜索, 以找到与你的问题相关的Nginx文档和相关资源。通常, 官方文档、Nginx的邮件列表、Stack Overflow等社区论坛都是寻找帮助的好去处。
注意版本匹配:确保你查阅的文档和你正在使用的Nginx版本相匹配。Nginx的功能和配置选项可能会有一些变化和更新, 所以选择适合你版本的文档是很重要的。
理解文档结构:熟悉Nginx文档的结构和布局, 这样你可以更快地找到所需的信息。通常, 文档按照主题和模块进行组织, 通过导航栏或目录结构进行浏览和导航。
通过示例和案例学习:文档中通常会包含示例配置和使用案例。这些示例可以帮助你理解特定功能的用法和配置方法。尝试在自己的环境中实践这些示例, 以便更好地理解和掌握。
参考附加资源:除了官方文档外, 还有一些其他的资源可以帮助你更好地理解和应用Nginx。这些资源包括书籍、博客文章、视频教程和在线课程。探索这些资源, 可以从不同的角度深入学习和掌握Nginx。
参与社区:加入Nginx的用户社区, 如官方论坛、邮件列表或社交媒体群组, 与其他Nginx用户和开发者交流。这是一个互相学习和分享经验的好机会。通过与他人互动, 你可以获得更多的洞察和解决方案。
重要的是要有耐心和持续的学习态度。Nginx是一个功能丰富而灵活的软件, 学习它需要时间和实践。通过善用帮助文档和其他资源, 你将逐渐掌握并善于使用Nginx开源版本。
在部署nginx中间件之前, 我们先来规划一下环境, 特此声明 “禁止一切理由使用克隆的机器” , 请安装一台全新的机器或者使用保存好的快照。对于实验环境而言, 机器配置不低于 2core CPU、2GB memory 即可完成本章节的实验。至于操作系统采用 CentOS 7.9 即可, 更高的版本当然更好。
下面是具体的安装步骤:
x#> 系统初始化
$ sudo systemctl disable --now firewalld
$ sudo sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
#> 下载nginx源码包
$ wget https://nginx.org/download/nginx-1.24.0.tar.gz
$ sudo tar -xf nginx-1.24.0.tar.gz -C /opt
$ cd /opt/nginx-1.24.0
#> 安装必要的依赖软件
$ sudo yum -y groupinstall "Development Tools"
$ sudo yum -y install pcre-devel zlib-devel openssl-devel
#> 对源代码进行编译安装
$ ./configure --prefix=/usr/local/nginx
$ make -j 2 && make install
#> 将nginx加入到systemd进行管理
$ sudo vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /usr/local/nginx/logs/nginx.pid)"
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /usr/local/nginx/logs/nginx.pid)"
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now nginx
#> 配置vim识别高亮显示nginx配置文件
$ sudo cp -r contrib/vim/* /usr/share/vim/vim[VERSION]
$ exit 【退出当前的终端再次登陆进来即可完成vim新配置的加载】
⚠️ 此时打开浏览器, 在地址栏输入:http://[ipaddress]:[port] 即可访问到 nginx 的欢迎界面了
HTTP(Hyper Text Transfer Protocol)是一种用于在客户端和服务器之间传输超文本的协议。它是基于请求-响应模型, 客户端发送HTTP请求给服务器, 服务器返回HTTP响应给客户端。下面是对HTTP协议的详细描述:
通信模型:HTTP采用客户端-服务器模型。客户端发起请求并向服务器发送HTTP请求, 服务器处理请求并返回HTTP响应给客户端。
请求方法(Method):HTTP定义了一些常用的请求方法, 包括:
GET:获取资源
POST:提交数据
PUT:更新资源
DELETE:删除资源
HEAD:获取资源的头部信息
OPTIONS:获取服务器支持的HTTP方法 等等。每个请求方法对应不同的操作和语义。
URL(Uniform Resource Locator):URL是用于定位资源的标识符。它由协议类型、主机名、端口号、路径和查询字符串组成, 例如:http://test.example.com/path?param=value
请求头(Headers):HTTP请求可以包含各种请求头, 用于传递额外的信息给服务器。常见的请求头包括:
Host:指定服务器的主机名和端口号
User-Agent:标识客户端类型和版本
Content-Type:指定请求主体的数据类型
Authorization:用于进行身份验证 等等。请求头提供了关于请求的元数据信息。
请求主体(Body):某些请求方法(如POST)可以包含请求主体, 用于发送数据给服务器。请求主体的格式由Content-Type头部字段指定。
状态码(Status Code):HTTP响应包含一个状态码, 用于表示请求的处理结果。常见的状态码包括:
200 OK:请求成功
404 Not Found:未找到资源
500 Internal Server Error:服务器内部错误 等等。不同的状态码表示不同的响应情况
响应头(Headers):HTTP响应可以包含各种响应头, 用于传递额外的信息给客户端。常见的响应头包括:
Content-Type:指定响应主体的数据类型
Content-Length:指定响应主体的长度
Set-Cookie:设置Cookie信息 等等。响应头提供了关于响应的元数据信息。
响应主体(Body):HTTP响应可以包含响应主体, 其中包含了实际的响应数据, 如HTML文档、JSON数据等。
持久连接(Keep-Alive):HTTP支持持久连接, 可以在单个连接上传输多个请求和响应, 减少了连接的建立和关闭开销, 提高了性能效率。
HTTP协议是现代Web通信的基础, 它定义了客户端和服务器之间的通信方式和规范。通过HTTP, 我们可以在Web上浏览、访问资源、提交表单、与服务器进行交互等。
当我们在浏览器输入URL并按下Enter键时, 浏览器就会向站点的服务器发送一个HTTP请求, 服务器接收并处理请求, 然后将相关资源和HTTP标头一起返回。可以在浏览器的Network中查看 HTTP 的请求状态码:
HTTP状态码(HTTP Status Code)是用以表示网页服务器超文本传输协议响应状态的3位数字代码。它由 RFC 2616 规范定义的, 并得到 RFC 2518、RFC 2817、RFC 2295、RFC 2774 与 RFC 4918 等规范扩展。所有状态码被分为五类, 状态码的第一个数字代表了响应的五种状态之一。所示的消息短语是典型的, 但是可以提供任何可读取的替代方案。除非另有说明, 状态码是HTTP/1.1标准(RFC 7231)的一部分。 ---引用自《维基百科》
HTTP 状态代码是从 Web 服务器发送的 3 位代码(如 200 OK 或 404 Not Found), 用于让我们和搜索引擎知道请求中是否存在任何错误或服务器尝试处理请求时是否存在任何问题。HTTP协议的应用通常就是客户端向服务器发出请求, 服务器做出响应。状态码就是让我们知道 HTTP 请求是成功、失败还是其他。HTTP状态码通常分为五类:
类别 | 定义 | 描述 |
---|---|---|
1xx | Information 信息性状态码 (临时状态码) | 已经接受请求并正在处理 |
2xx | Success 成功状态码 | 请求正常处理完毕 |
3xx | Redirection 重定向状态码 | 需要进行附加操作来完成请求 |
4xx | Client Error 客户端错误状态码 | 服务器无法处理请求 |
5xx | Server Error 服务器错误状态码 | 服务器处理请求出错 |
解析:
1xx状态码:1XX的状态码是在HTTP/1.1 中引入的, 它们是信息性的状态码, 是临时的, 表示请求已被接受, 需要继续处理。这些状态码并没有提供太多有用的信息, 我们可能永远看不到1XX相关的状态码
2xx状态码:状态码表示客户端的请求被成功接收、理解和接受
200: 表示客户端发来的请求被服务器端正常处理了, 所有链接页面都在正常工作
3xx状态码:响应结果表明浏览器需要执行某些特殊的处理以正确处理请求(⚠️这不是错误)
301: 永久重定向。已为目标资源分配了一个新的永久 URI
302: 临时重定向。请求的资源被分配到了新的 URI, 希望用户(本次)能使用新的 URI 访问资源
4xx状态码:客户端构造请求体错误
400: 请求报文中存在语法错误
401: 认证信息不存在于请求头(header)中
403: 请求资源未找到 or 对访问的uri地址没权限
404: 请求资源未找到
413: 请求体中的数据过大, 服务端无法处理这么大的请求体
429: 客户端在短时间内发送了太多请求, 被限制访问了
431: 请求体中的header头字段太大了, 服务端无法处理这么大的头部信息
5xx状态码: 响应结果表明服务器本身发生错误
500: 服务端中的代码存在bug
502: 多指代理服务器的配置有问题
503: 服务器处于超负载 or 维护状态
504: 多指代理的上游服务器错误, 通常是代码执行超时、代码发生了死循环
访问流程描述: 客户端浏览器通过地址栏输入要访问的域名(www.example.com), 浏览器通过本地的DNS or 远程的公网DNS将域名解析成IP地址, 浏览器将本地的IP地址及本地的端口作为源地址源端口与远程的IP地址(DNS 解析得来)及默认的监听端口(80/tcp), 建立三次握手, 形成通讯的通道, 此时浏览器通过通讯通道发送HTTP请求至对应的服务器的中间件(nginx)中, nginx的master进程在接收到请求时会将请求分发到worker进程进行处理, worker进程读取配置文件的默认配置及http板块中的配置将请求体解包, 根据请求体中的URL找到对应的server虚拟主机板块, 由server虚拟主机识别请求行中的uri确定由哪个location对请求进行响应(读取数据 or 加载本地数据), 此时worker进程会等到相关的指令将要加载的数据以及识别到的请求头部信息以及本次处理的结果状态码, 依次封装到响应体中, 透过TCP连接的通道将响应体返回给客户端, 此时客户端接收到响应体之后在浏览器中进行解包, 并将数据渲染到界面中进行显示。
Nginx是一个事件驱动的异步Web服务器, 它的工作原理可以概括为以下几个步骤:
启动和监听:Nginx服务器启动时会监听一个或多个指定的端口, 通常是80端口(HTTP)和443端口(HTTPS)。它在这些端口上等待客户端的连接请求。
接收和处理请求:当客户端发起连接请求时, Nginx会接收到该请求。它使用事件驱动的机制(如epoll、kqueue或select)来管理并发连接。Nginx的事件驱动模型允许它在单个或少量的线程上同时处理大量的并发请求。
配置和处理请求:Nginx根据配置文件中的规则(location)对请求进行处理。这些规则指定了Nginx如何处理不同类型的请求, 包括静态资源请求和动态内容请求。
静态资源服务:对于静态资源请求, 如HTML文件、图片、CSS和JavaScript文件, Nginx可以直接从磁盘上提供这些文件。它在文件系统中查找请求的静态资源, 并将其作为响应发送给客户端。
反向代理和负载均衡:对于动态内容或需要后端应用服务器处理的请求, Nginx可以充当反向代理服务器。它将这些请求转发给配置的后端服务器群集(如应用服务器), 通过负载均衡算法将请求分发给其中的一个服务器。这样可以实现请求的分发和负载均衡, 确保每个服务器充分利用并均匀分担负载。
处理响应:当后端服务器处理完请求并生成响应后, Nginx将接收到的响应返回给客户端。它负责管理和维护与客户端之间的连接, 确保响应正确地传输回客户端。
SSL/TLS加密:如果启用了HTTPS, Nginx会处理SSL/TLS加密和解密。它使用配置的SSL证书对数据进行加密, 并确保传输的安全性和保密性。
日志记录和监控:Nginx会记录每个请求的相关信息, 包括请求时间、客户端IP地址、响应代码等。这些日志可以用于监控和分析服务器的运行情况, 进行故障排查和性能优化。
通过这些步骤, Nginx实现了高性能、高可用性和可扩展性的Web服务。它的事件驱动模型和异步处理机制使得它能够有效地处理大量并发请求, 同时提供灵活的配置选项和强大的反向代理功能。这使得Nginx成为许多Web应用程序的首选服务器。
在nginx运行过程中如何向用户提供服务以及提供服务的方式都是依靠配置文件来进行提前设定的。在nginx中为了运维人员方便管理配置文件, 提供了主配置文件、子配置文件两个概念。通常主配置文件使用include指令来加载子配置文件的, 主配置文件中通常写一些公共的配置来应用到所有的 “虚拟主机(server)” 中, 而子配置文件中可以写独立的站点(虚拟主机)的配置, 用不同的文件名称来区分不同的站点配置文件, 极大的方便了运维进行管理。
以下代码为nginx主配置文件示例文件, 注意其中的包含关系
xxxxxxxxxx
#> 通用设定板块
user nginx;
worker_processes auto;
error_log logs/error.log info;
pid logs/nginx.pid;
events {
use epoll;
worker_connections 1024;
}
#> http七层通用设定板块
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
error_log logs/error.log;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;
#> 单域名虚拟主机设定板块
server {
listen 80;
server_name test.example.com;
access_log logs/test.example.com.access.log main;
error_log logs/test/example.com.error.log;
#> 单域名下的uri接口配置
location / {
root /usr/local/nginx/html;
index index.html index.htm;
}
}
#> 指定被单独加载的子配置文件
include "/usr/local/nginx/conf.d/*.conf";
}
各字段解析:
user 指定nginx服务的所有运行进程的用户身份
worker_processes 指定worker进程的数量(一般为CPU数量 or auto[自动识别])
error_log 指定nginx所有进程的错误日志存储位置及收集级别
pid 指定nginx服务运行起来后的master进程的pid号
events.use 指定事件驱动模型
events.worker_connections 指定单独的worker进程启用的最大处理请求数; 要配合操作系统的单进程最大文件打开数进行设定
http.include 指定要 包含 or 加载 的配置
http.log_format 指定所有服务在生产日志时要遵循的日志格式
http.access_log 指定所有服务的访问日志存储位置
http.sendfile 用于控制是否启用sendfile机制来处理文件传输
http.tcp_nopush 配合sendfile一起使用, 用于延迟发送tcp数据, 将多个小的数据包合并为一个更大的数据包发送, 从而减少网络I/O
http.keepalive_timeout 用于允许在单个 TCP 连接上连续发送多个 HTTP 请求和响应, 用于长链接设定
http.gzip 指定在传输过程中对HTTP响应的内容进行压缩, 减少数据传输的大小, 提高网络传输效率
http.server 指定虚拟主机配置
http.server.listen 指定虚拟主机的监听端口
http.server.server_name 指定虚拟主机的服务域名
http.server.access_log 指定虚拟主机的访问日志存储位置
http.server.error_log 指定虚拟主机的错误日志存储位置
http.server.location 指定虚拟主机域名下的URI接口(可以在server中写多个)
在nginx进行设定的过程中, 我们通常都, 现在想将其上线到生产环境中, 而我们通过一定的手段得知, 生产环境是使用nginx来作为Vue项目的中间件服务的。这里有三个问题需要解决:
Vue的代码是否需要做什么其他的操作?
应该如何将Vue项目的代码进行上传呢?
应该如何编写nginx的配置文件以提供Vue项目的访问?
第一个问题, Vue官方文档要求, 在上线Vue项目之前需要对项目进行依赖项的安装[ npm install ]
, 在安装完依赖项之后要执行构建命令以生产上线的产物 dist
目录(其中生成的文件都是html、css、javascript的源代码)。也就是说需要在项目代码目录中运行两条指令:
npm install
安装依赖项
npm run build
生成可用于生产的部署目录 dist/
第二个问题:传送到指定的服务器中, 就简单了, 使用 scp -r
即可将 dist
目录上传至对应的服务器中了
第三个问题就是该如何编写配置文件了, 看下面的示例:
xxxxxxxxxx
server {
listen 80;
server_name test.example.com;
location / {
root /app;
index index.html;
try_files $uri $uri/ /index.html;
}
}
根据上述的提示相信你已经将Vue项目顺利的上线到指定的服务器中了, 并且能够访问到Vue项目的欢迎界面了, 但是我们现在有个迫切的需求就是, 浏览器中显示我们的服务是不安全!那我们该如何对这个服务进行安全设置呢?答案是HTTP + SSL = HTTPS 协议来实现。
下面是对 test.example.com 这个虚拟主机的SSL配置项:
xxxxxxxxxx
server {
listen 443 ssl;
server_name test.example.com;
ssl_certificate test.example.com.crt;
ssl_certificate_key test.example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
root /app;
index index.html;
try_files $uri $uri/ /index.html;
}
}
HTTPS(Hypertext Transfer Protocol Secure)是一种通过加密和身份验证来保护Web通信安全的协议。它基于HTTP协议, 使用TLS(Transport Layer Security)或其前身SSL(Secure Sockets Layer)协议来加密通信数据。下面是HTTPS的工作原理的简要描述:
客户端发起连接:客户端(通常是Web浏览器)通过向服务器的HTTPS端口发送连接请求来启动HTTPS连接
服务器证书:服务器收到客户端的连接请求后, 会将自己的数字证书发送给客户端。证书包含了服务器的公钥、服务器的身份信息以及证书颁发机构(CA)的数字签名
客户端验证证书:客户端会验证服务器证书的有效性。它会检查证书的签名是否有效, 是否在有效期内, 以及证书中包含的域名是否与访问的域名匹配。如果验证失败, 连接可能会终止或显示警告
客户端生成加密密钥:如果服务器的证书验证成功, 客户端会生成一个用于加密通信的对称密钥(称为会话密钥或对话密钥)
会话密钥加密:客户端使用服务器的公钥对会话密钥进行加密, 并将其发送给服务器
服务器解密会话密钥:服务器使用自己的私钥对接收到的加密的会话密钥进行解密, 得到原始的会话密钥
加密通信:客户端和服务器现在都拥有相同的会话密钥。他们使用这个密钥来加密和解密在之后的通信过程中传输的数据。这保证了通信内容的保密性, 只有客户端和服务器才能解密和理解传输的数据
通过使用HTTPS, 通信双方之间的数据传输变得安全, 第三方无法窃听或篡改通信内容。HTTPS还提供了身份验证机制, 确保客户端正在与预期的服务器进行通信, 防止中间人攻击。需要注意的是, 为了使用HTTPS, 服务器需要获得有效的数字证书, 可以通过向可信的证书颁发机构(CA)申请证书。这样, 客户端才能正确验证服务器的身份。
原理总结: 浏览器构造请求体向服务端发送请求, 服务端接收到请求后将被访问域名的证书返回给浏览器, 此时浏览器对证书进行验证, 如果验证为不合法则浏览器警告用户“不安全”, 如果验证正常则生成一个随机数, 并使用证书对该随机数进行加密, 并将加密后的随机数传给服务端, 此时服务端通过私钥解密随机数, 再使用随机数对要返回的响应体进行加密传送给浏览器, 浏览器在通过对应的随机数进行解密, 以此建立的加密通信
上方的证书颁发机构(CA)签发证书是需要付费的, 生产环境还是比较推荐在云厂商处进行购买的, 而对于个人网站及测试环境服务可以使用 "Let's Encrypt"来签发合法的免费证书。Let's Encrypt 是一个免费的证书颁发机构, 它提供了一种简便的方式来为Nginx服务器签发和管理SSL/TLS证书。
使用let's encrypt
申请证书及私钥分为两步: 首先管理软件(certbot)向证书颁发机构证明该服务器拥有域名的控制权。 之后该管理软件就可以申请、续期或吊销该域名的证书。
Certbot 是 let's encrypt
申请证书的官方自动化工具, 你也可以访问 (https://certbot.eff.org/)提供的指南来安装适用于其他操作系统的Certbot工具。好消息是现在certbot支持泛域名申请证书了, 极大的方便了我们管理证书。
xxxxxxxxxx
#> 首先安装epel源 用于安装snap工具
$ yum -y install epel-release
#> 安装snap工具
$ yum -y install snapd
$ ln -s /var/lib/snapd/snap /snap
$ systemctl enable --now snapd
#> 安装核心模块用于运行certbot
$ snap install core; snap refresh core
#> 安装certbot
$ snap install --classic certbot
$ ln -s /snap/bin/certbot /usr/bin/certbot
#> 使用certbot对自己的域名进行证书申请
$ certbot certonly --manual --preferred-challenges dns -d 你的二级域,*.你的二级域
将生成的证书路径配置到对应的虚拟主机配置文件中对nginx进行重新加载 nginx -s reload
即可加载新的配置。但是现在还有一个必须要解决的问题就是:用户通常都不会自己在域名的前面加上 https 协议头, 所以为了用户访问方便应该做一个 http 自动跳转到https的配置:
xxxxxxxxxx
Syntax: rewrite regex replacement [flag];
Default: —
Context: server, location, if
xxxxxxxxxx
server {
listen 80;
server_name test.example.com;
location / {
rewrite ^(.*)$ https://test.example.com$1 permanent;
}
}
server {
listen 443 ssl;
server_name test.example.com;
ssl_certificate test.example.com.crt;
ssl_certificate_key test.example.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
root /app;
index index.html;
try_files $uri $uri/ /index.html;
}
}
此时即可打开浏览器访问 test.example.com 来验证是否会自动进行跳转。
日志格式的识别:
xxxxxxxxxx
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
remote_addr: 与当前nginx直接建立TCP连接的IP地址
remote_user: 远程的连接用户(一般是没有的) -
time_local: 被访问的时间 时刻
request: 请求行信息(请求方法 URI接口 HTTP版本)
status: 响应状态码
body_bytes_sent: 响应体大小
http_referer: 请求体中的请求行中的URL
http_user_agent: 浏览器内核的版本
http_x_forwarded_for: 当前置了代理时, 接收用户真实IP地址使用的header头部字段名
错误日志的三元素:
- 报错时间点
- 报错的接口(uri、url)
- 报错的描述
虚拟主机server
xxxxxxxxxx
server {
listen 443 ssl;
server_name mirrors.qfcc.online;
access_log /usr/local/nginx/logs/mirrors.qfcc.online.access.log main;
error_log /usr/local/nginx/logs/mirrors.qfcc.online.error.log;
ssl_certificate /usr/local/nginx/certs/fullchain.pem;
ssl_certificate_key /usr/local/nginx/certs/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
root /usr/local/nginx/html;
location / {
index index.html index.htm;
}
}
当单台Nginx服务器无法满足大量流量时, 负载均衡是一种常见的解决方案。Nginx可以配置为形成负载均衡集群, 将流量分发到多台后端服务器上, 从而实现高性能、高可用性和可扩展性。以下是负载均衡的基本原理和实现方式:
后端服务器群集:负载均衡需要至少两台或多台后端服务器来处理请求。这些后端服务器可以是相同的硬件和软件配置, 也可以是不同的服务器。它们都承担相同的应用程序或服务, 并具有相同的内容和功能。
负载均衡器:Nginx充当负载均衡器的角色, 它接收来自客户端的请求, 并将其分发到后端服务器。Nginx具有内置的负载均衡算法, 如轮询(round-robin)、IP哈希(ip_hash)、最少连接(least_conn)等, 用于决定将请求发送到哪个后端服务器。
请求分发:当Nginx接收到客户端的请求时, 根据负载均衡算法的规则, 它将请求分发到后端服务器上。负载均衡器可以根据每个后端服务器的负载情况、响应时间等因素来动态调整请求的分发策略。
响应返回:后端服务器处理请求并生成响应后, Nginx将接收到的响应返回给客户端。负载均衡器会管理和维护与客户端之间的连接, 确保响应正确地传输回客户端。
健康检查:负载均衡器可以定期对后端服务器进行健康检查, 以确保它们处于可用状态。如果某个后端服务器不可用(如宕机或故障), 负载均衡器将停止将请求发送到该服务器, 并将流量重新分发到其他可用的服务器上。
通过配置Nginx作为负载均衡器, 你可以创建一个高性能、高可用性的Web服务集群, 以应对大量的并发流量。负载均衡将请求分发到多个后端服务器上, 实现了流量的均衡分配, 提高了整体系统的处理能力和可靠性。负载均衡还具有可扩展性, 当流量增加时, 你可以通过添加更多的后端服务器来扩展负载均衡集群, 以满足更高的需求。
要实现nignx负载均衡的功能, 需要使用 upstream
模块来实现
xxxxxxxxxx
Syntax: upstream name { ... }
Default: —
Context: http
Syntax: server address [parameters];
Default: —
Context: upstream
xxxxxxxxxx
upstream dynamic {
server backend1.example.com weight=5;
server backend2.example.com:8080 fail_timeout=5s;
server 192.0.2.1 max_fails=3;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server backend.example.com:8080 down;
}
server {
listen 80;
server_name test.example.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://dynamic;
}
}
设置负载均衡机器的header将其传送到上游的服务器中进行识别:
比如上方的示例: 将用户的真实IP地址透传到上游服务器中
用户的真实IP地址记录到上游Nginx服务器的日志中, 你可以在负载均衡Nginx的配置中添加以下指令, 将用户的真实IP地址通过自定义的HTTP请求头传递给上游服务器:
在Nginx的负载均衡配置中, 找到代理服务器相关的位置块(如location
)。
在该location块内添加指令:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
这条指令将设置名为X-Forwarded-For
的HTTP请求头, 并将其值设置为包含用户真实IP地址的字符串。通过使用$proxy_add_x_forwarded_for
变量, 可以将用户真实IP地址添加到原始的X-Forwarded-For
请求头中。
保存配置文件并重新加载Nginx服务, 使配置生效。
通过上述配置, 当Nginx作为反向代理服务器接收到客户端请求时, 它会将客户端的真实IP地址添加到X-Forwarded-For
请求头中, 并将该请求头传递给上游服务器。
在上游服务器的日志中, 你可以通过读取X-Forwarded-For
请求头来获取用户的真实IP地址, 并记录到日志中。具体的读取方式和日志记录方式可能会根据上游服务器的配置和日志系统的不同而有所差异。
需要注意的是, X-Forwarded-For
请求头可以包含多个IP地址, 用逗号进行分隔。第一个IP地址是最初的客户端IP地址, 后续的IP地址是经过多个代理服务器转发的IP地址。因此, 在上游服务器中提取真实IP地址时, 需要根据具体情况进行适当的处理。
另外, 同样要注意保护负载均衡器和上游服务器的安全性, 确保只有受信任的负载均衡器可以修改X-Forwarded-For
请求头, 并防止IP伪造和其他安全问题。
对于nginx作为负载均衡器之后, 所能够采用的算法有以下几种:
轮询(RR):默认的负载均衡算法, 按顺序将请求依次分发给后端服务器, 实现简单的均衡负载。
IP哈希(ip_hash):根据客户端的IP地址对请求进行哈希计算, 将同一IP的请求分发给相同的上游服务器。
最少连接(least_conn):将请求发送给当前连接数最少上游服务器。这样可以使请求在服务器上分布得更均衡
加权轮询(weight):为每个上游服务器分配一个权重值, 按照权重比例分配请求。权重越高的服务器将接收到更多的请求。
加权URL哈希(hash $request_uri):根据请求的URL进行哈希计算, 并根据上游服务器的权重选择服务器来处理相同URL的请求
大部分负载均衡算法需要使用第三方模块来实现, 这意味着我们需要为Nginx增加这些模块的特性。为了做到这一点, 我们需要重新编译Nginx, 并在编译过程中将需要增加的功能特性一同编译进去。完成编译后, 我们可以通过平滑升级的方式将新编译的Nginx替换掉旧版本。这样Nginx就具备了所需的第三方负载均衡算法能力。
第三方模块查找地址: https://www.nginx.com/resources/wiki/modules/
xxxxxxxxxx
[root@nginx-test-mahines nginx]# /usr/local/nginx/sbin/nginx -t
nginx: [emerg] the "ssl" parameter requires ngx_http_ssl_module in /usr/local/nginx/conf.d/https-vue.conf:11
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
[root@nginx-test-mahines ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.24.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
configure arguments: --prefix=/usr/local/nginx
[root@nginx-test-mahines ~]# ls -l
总用量 1092
-rw-------. 1 root root 1764 9月 19 14:16 anaconda-ks.cfg
-rw-r--r-- 1 root root 1112471 8月 4 09:29 nginx-1.24.0.tar.gz
[root@nginx-test-mahines ~]# tar xf nginx-1.24.0.tar.gz -C /opt/
[root@nginx-test-mahines ~]# cd /opt/nginx-1.24.0/
[root@nginx-test-mahines nginx-1.24.0]# ./configure --help | grep ngx_http_ssl_module
--with-http_ssl_module enable ngx_http_ssl_module
[root@nginx-test-mahines nginx-1.24.0]#
[root@nginx-test-mahines nginx-1.24.0]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.24.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
configure arguments: --prefix=/usr/local/nginx
[root@nginx-test-mahines nginx-1.24.0]#
[root@nginx-test-mahines nginx-1.24.0]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module
checking for OS
+ Linux 3.10.0-1160.el7.x86_64 x86_64
checking for C compiler ... found
+ using GNU C compiler
+ gcc version: 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
checking for gcc -pipe switch ... found
checking for -Wl,-E switch ... found.
..................
..................
..................
[root@nginx-test-mahines nginx-1.24.0]# make
make -f objs/Makefile
make[1]: 进入目录“/opt/nginx-1.24.0”
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/core/nginx.o \
src/core/nginx.c
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-un
.................
..................
.................
[root@nginx-test-mahines nginx-1.24.0]# cd objs/
[root@nginx-test-mahines objs]# mv /usr/local/nginx/sbin/nginx{,.bak}
[root@nginx-test-mahines objs]# cp nginx /usr/local/nginx/sbin/
[root@nginx-test-mahines objs]# ls /usr/local/nginx/sbin/
nginx nginx.bak
[root@nginx-test-mahines objs]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.24.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module
[root@nginx-test-mahines objs]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-test-mahines objs]#
[root@nginx-test-mahines objs]#
[root@nginx-test-mahines objs]#
[root@nginx-test-mahines objs]# systemctl restart nginx
[root@nginx-test-mahines objs]# ps aux | grep nginx
root 18712 0.0 0.0 45988 1184 ? Ss 09:49 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nginx 18713 0.0 0.1 50240 5568 ? S 09:49 0:00 nginx: worker process
nginx 18714 0.0 0.1 50240 5568 ? S 09:49 0:00 nginx: worker process
nginx 18715 0.0 0.1 50240 5568 ? S 09:49 0:00 nginx: worker process
nginx 18716 0.0 0.1 50240 5568 ? S 09:49 0:00 nginx: worker process
root 18718 0.0 0.0 112824 992 pts/0 S+ 09:49 0:00 grep --color=auto nginx
xxxxxxxxxx
#
# author: liuchao
# email: mirschao@gmail.com
# github: https://github.com/mirschao
NGINX_HOME='/usr/local/nginx'
IP_REGEX="([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])"
IP="${IP_REGEX}\.${IP_REGEX}\.${IP_REGEX}\.${IP_REGEX}"
for confile in $(ls -l ${NGINX_HOME}/conf.d | egrep "*.conf$" | awk '{ print $NF }'); do
for iport in $(egrep "${IP}" ${NGINX_HOME}/conf.d/${confile} | awk '{ print $2 }' | sed 's/;//'); do
status_code=$(curl -sI ${iport} | awk 'NR==1{ print $2 }')
if [[ ${status_code} -ge 400 ]] || [[ ${status_code} == '' ]]; then
iport=$(echo ${iport%;})
sed -i "/${iport}/cserver ${iport} down\;" ${NGINX_HOME}/conf.d/${confile}
systemctl restart nginx
# source /opt/scripts.sh # 向监控平台或钉钉微信飞书等发送告警的信息
fi
done
done
在生产集群架构中是不能存在单点的, 因为不能因为一个服务器宕机, 而导致整个集群就瘫痪了。所以对于前置在架构边缘的负载均衡器而言需要做到高可用性。实现nginx负载均衡的高可用性可以采用keepalived来实现。下面是具体的配置步骤:
xxxxxxxxxx
#> 在每个负载均衡的节点安装keepalived
$ yum -y install epel-release
$ yum -y install keepalived
---------------------------------------------------------------
#> 修改每个负载均衡节点的kp配置文件
$ vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id NGINX_DEVEL
}
vrrp_script check_nginx_loadbalancer {
script "/etc/keepalived/check_nginx_loadbalancer.sh"
interval 5
weight -5
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface ens33
mcast_src_ip 192.168.19.21
virtual_router_id 200
priority 101
nopreempt
advert_int 2
virtual_ipaddress {
192.168.19.99
}
track_script {
check_nginx_loadbalancer
}
}
---------------------------------------------------------------
#> 编写健康检查脚本
$ cat /etc/keepalived/check_nginx_loadbalancer.sh
#
# author: mirschao
# usage: check nginx healthy.
err=0
check_code=$(pgrep nginx)
if [[ $check_code == "" ]];then
err=$(expr $err + 1)
fi
if [[ $err -ne 0 ]];then
/usr/bin/systemctl stop keepalived
exit 1
else
exit 0
fi
---------------------------------------------------------------
#> 分别在每台负载均衡节点启动kp
$ systemctl enable --now keepalived
$ ping 10.9.12.99 #> 测试VIP是否能够被ping通
将主节点的nginx手动停掉, 查看VIP是否会漂移到另外一个节点上去。
在Web开发中, "location" URI匹配通常指的是通过URL路径来匹配不同的请求处理程序或资源。匹配规则和顺序可能会因不同的Web框架和服务器而有所不同, 但通常遵循以下一般规则:(以下排序时按照优先级进行的)
静态路径匹配:首先, 服务器会尝试精确匹配URI路径。如果请求的URI路径与某个已知的静态资源路径完全匹配, 服务器将直接返回相应的资源, 例如HTML文件、图像或CSS文件。这是最简单的匹配方式, 无需进一步处理。
基于前缀的路径匹配:如果没有找到精确的静态资源路径匹配, 服务器将尝试使用基于前缀的路径匹配。这意味着服务器会查找与请求路径前缀匹配的处理程序或路由。例如, 如果请求的URI路径是/users
, 服务器可能会查找与/users
相关联的处理程序或路由。
通配符和正则表达式匹配:如果基于前缀的路径匹配也没有找到匹配项, 服务器可能会使用通配符或正则表达式匹配来处理更复杂的路由。这些匹配方法允许您定义模式, 以匹配多个URI路径。通配符匹配通常使用特殊字符, 例如*
或?
, 来表示通配符。正则表达式匹配使用正则表达式模式来匹配URI路径。
顺序匹配:在处理多个路由或处理程序时, 通常会按照它们在代码中的定义顺序来匹配。服务器将从上到下依次检查每个路由或处理程序, 直到找到与请求URI路径匹配的项为止。因此, 定义的路由或处理程序的顺序非常重要, 因为它们会影响匹配的顺序。
默认处理程序:如果没有找到与请求URI路径匹配的任何处理程序或路由, 服务器通常会使用默认处理程序或返回一个错误页面, 指示请求的页面不存在。
总的来说, URI路径匹配顺序是从最具体到最一般的顺序。服务器首先尝试静态资源匹配, 然后逐渐降低到更通用的路由匹配。路由的定义顺序以及使用通配符或正则表达式的方式都会影响匹配的结果。不同的Web框架和服务器可能会有不同的实现方式, 因此具体的细节可能会有所不同。
对于优化而言不能在部署完业务之后直接优化, 要有针对的优化, 没有任何一种优化方案具备普适性, 因为每个公司的业务都是不一样的, 所以就会衍生出很多不同的优化方案; 但是所有的优化方案都是有根据可循的;
从软件层面提升硬件的使用效率
增大CPU的利用率
增大内存的利用率
增大磁盘IO的利用率
增大网络带宽的利用率
提升硬件规格
网卡: 将千兆网卡替换成万兆网卡
磁盘: 将机械硬盘替换成固态硬盘, 更多的是关注IOPS、BPS等指标
CPU: 更快的主频、更多的核心、更大的缓存、更优架构
内存: 更快的访问速度, 比如DDR3替换成DDR4
超出硬件性能上限后使用DNS进行轮询解析, 形成集群提高负载
Question: 如何增大Nginx使用CPU的有效时长?
Response:
能够使用全部CPU资源
master-worker多进程架构
worker数量应当大于等于CPU核数, 但不要超过两倍
进程间不做无用功浪费CPU资源
worker进程不应该在繁忙的时候, 主动让出CPU
worker进程间不应该由于争抢造成资源耗散
worker进程数量应当等于CPU核数
worker进程不应该调用一些API导致主动让出CPU
拒绝类似需要大量CPU计算的第三方模块
不应该被其他进程争抢资源 【监控程序的agent】
提升优先级占用CPU更长的时间
减少操作系统上耗资源的非Nginx进程
Opera:
xxxxxxxxxx
// 在main范围内设置, 也就是http之外
// 设置worker进程的数量
worker_processes cpu_core_number | auto
// 设置worker进程的优先级 -->> ·-19 // -20· 提高其优先级
worker_priority number[default 0]
// 调优的方法可以使用ps将worker进程的pid号取出来, 并用pidstat -w -p pid查看cswch/s的主动切换值, 生产环境中应该尽量的将其降低, 如果有多次上下文切换就意味着在这个CPU上进行了多次进程间切换, 从而过多的消耗资源。而降低上下文切换的方法就是提高优先级和尽量少的使用消耗大量CPU资源的第三方模块;
// 在server指令块中设置listen延迟响应时间, 避免CPU计算浪费
listen 80 deferred;
// 延迟的由来是因为客户端浏览器向nginx发送一个请求之前需要建立三次握手, 当握手成功后只是出发nginx进入到就绪状态并启动worker进程进行就绪而已, 与此同时向客户端回包, 让客户端再将请求发送至这个链接通道中进行请求; 所以这段时间内其实是处于阻塞的状态, 如果在请求进入到通道后被传输到了80端口后, 再启动worker进程进行处理, 那么就解决了上述的问题;
Question: worker进程间负载均衡是怎么实现的? 有没有可能造成惊群问题?
Response: 不会!因为在 kernel-3.9 up的版本中使用reuseport功能将惊群的问题已经解决了, 并且还提高了稳定性, 降低了时延, 提高了每秒处理请求数;
Question: 如何提升CPU缓存命中率?
Response: 设置worker进程与cpu核心进行绑定
Opera:
xxxxxxxxxx
// 该设置在main板块进行设置, http模块之外设置, 如下为四核心cpu的设置方法
worker_cpu_affinity 0001 0010 0100 1000
00000001 00000010 00000100 00001000 00010000
// 绑定cpu可以更好的让worker每次处理请求的时候使用相同的CPU那么, 之前缓存在CPU中的上下文数据就能够很好的得到利用;
Answer: 以下为网络层的优化建议
TCP 建立连接的过程和优化TCP连接的参数和方法; 在建立TCP连接的时候其实有很多状态我们可以操作, 对于这些状态的查询可以使用netstat进行查询, 并且根据第二部分的了解, 只有在系统和客户端建立好TCP连接后才能进行应用层http协议的解析, 以及触发epoll_wait去处理连接;
对于上下游服务器而言, 由于反向代理需要向上游服务器主动建立连接, 所以也会进行tcp的三次握手过程, 还有就是反向代理服务器还要启动一个端口用来和上游服务器的80或443端口建立数据通信; 那这些在大场景下也会成为网络的性能瓶颈; 那么可以在内核中启用如下设置, 适当的调整参数值以提高连接效率和并发数量; 也可以在nginx配置文件中增加应用层的超时时间来提高连接效率;
xxxxxxxxxx
# 下游服务器: /etc/sysctl.conf 主动建立连接时, 发SYN的重试次数
net.ipv4.tcp_syn_retries = 6
# 下游服务器: /etc/sysctl.conf 建立连接时的本地端口可用范围
net.ipv4.ip_local_port_range = 32768 60999
# nginx配置文件中: 对location中的proxy_pass连接进行设置
proxy_connect_timeout 60s
# 对upstream中的server服务器进行设定
proxy_connect_timeout 60s
# 对上下游服务器之间使用TCP fast open功能, 提高上下游访问速度, 为了防止SYN攻击所以还需在listen中配置
net.ipv4.tcp_fastopen = 1 [0|1|2|3]
listen address[:port] [fastopen=number] [backlog=number]
那如上图所示的连接过程, 就可以有针对性的进行调整系统的内核参数了; 图中可以看出SYN队列中存储的都是tcp的半连接, accept队列中存储的是建立好的连接; 那么如果有大量无效的SYN报文发送到系统中时就会迅速的装满SYN队列, 导致新的或正常的连接进不来, 或者由于nginx被阻塞住而没有及时的从accept队列中获取待处理的连接导致accept队列占满, 新的半连接转化为握手成功的请求无处安放; 那我们可以调整两个队列的大小
xxxxxxxxxx
# SYN_RCVD状态连接的最大个数
net.ipv4.tcp_max_syn_backlog = 262144
# 被动建立连接时, 发SYN/ACK的重试次数
net.ipv4.tcp_synack_retries = 6
# 接收网卡, 但未被内核协议栈处理的报文队列长度
net.core.netdev_max_backlog = 276144
# 超出处理能力时, 对新来的SYN直接回包RST, 丢弃连接
net.ipv4.tcp_abort_on_overflow = 1
# 对于操作系统而言提升其可使用的句柄数也可以提升连接队列的长度
fs.file-max = 2168800
# 提高运行nginx进程用户的最大文件打开数, 提高句柄可用性 /etc/security/limits.conf
nginx soft nofile 65535
nginx hard nofile 65535
# 也可以在nginx配置中将worker进程的最大文件打开数进行调整
worker_rlimit_nofile number; // 所有worker的限制数, 仅仅是限制数, 可以调整的大一些
worker_connections number; // 上下游的连接数都算在里面
对于nginx服务而言, 重用连接是非常重要的, 但是连接长时间不被清理就会影响新晋用户的连接性能, 那在Linux中可以使用keepalive来设置包探测功能, 并且在nginx的listen指令中也内置了对应的指令;
xxxxxxxxxx
# 发送心跳周期
net.ipv4.tcp_keepalive_time = 7200
# 探测包发送间隔
net.ipv4.tcp_keepalive_intvl = 75
# 探测包重试次数
net.ipv4.tcp_keepalive_probes = 9
# nginx中的listen配置
listen 80[:port] [so_keepalive=30m:3:10]