Nginx的性能优化

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

Nginx的性能优化


Nginx的架构

在说明性能优化之前,先来回顾一下Nginx的架构

默认情况下nginx每个worker进程都是单线程的,可以为每个worker进程开始多线程

两种工作模式,总的来说一样的地方:一个master管理多个worker进程

  • master进程:负责管理worker进程的生命周期
  • worker进程:负责具体工作

工作模式1(默认):所有worker进程共享同一个全连接队列

  • master进程负责bind()、listen()之后,负责创建出多个worker进程
    • listen就是通知操作系统开启一个半连接池、对应着也得开启一个全连接池,该全连接池是所有worker进程共享的
  • 所有worker进程,都会去同一个全连接队列里用accept()取走一个全连接,然后进行收发消息
    • worker进程在取连接的时候无法预判该链接一会承载的请求是耗时还是不耗时,即woker进程是基于链接调度的,而不是请求
  • 特点:所有worker进程共享一个全连接队列(都是由master的listen发起的)
  • 优点:
    • 某个worker进程拿到一个链接之后,该链接里发来的请求是非常耗时的,此时该worker的处理能力在变弱--》从全连接队列里拿新链接来处理的能力变慢
    • 此时不会影响其他worker的处理能力,因为大家的队列是共享的
    • 总结:基于共享的方式,会平衡所有worker进程的压力
  • 缺点:
    • 全连接队里是共享的,而worker是并发/并行去队列里拿链接的
    • 这涉及到争抢问题,需要加锁处理,会带来额外的损耗

工作模式2:每个worker进程独享自己单独的一个全连接队列

  • 还是由master进程发起listen监听端口,每个worker进程会重用reuse主进程的那个端口,即端口都一样,但是每个worker会单独开辟一个自己的全连接队列
  • 每个worker进程都处理自己独享的那一个全连接队列,其他worker进程无法看到你的这个队列
  • 特点:每个worker进程都独享自己的listener全连接队列
  • 优点:不需要多个进程/线程竞争某个公共资源,减少竞争的资源消耗,处理效率自然提高了。
  • 缺点:当某个worker进程处理不过来,其他worker不能为其分摊压力

总结:

  • 开启了reuseport,让每个worker独享自己的全连接队列,减少了进程层面的资源争抢
  • 为了解决worker进程繁忙的情况下无人帮其分摊的压力的问题,在worker进程内开启了多线程
    • 好处:缓解压力;让cpu的使用分配更加均匀
    • 坏处:又需要考虑资源争抢问题(虽然也需要考虑,但至少比进程之间的资源争抢要效率高);增加了出bug风险,可能会因为某个线程的bug而引发整个进程挂掉
  • 每个线程处理网络io问题的时候用的都是epoll模型
  • ingress-nginx:开启了reuseport;开启了线程池
  • 重点:nginx worker进程调度是以连接为单位,不是以请求为单位,所以无法分别请求的耗时长短

单节点nginx优化

bash 复制代码
# 全局配置优化
进程数修改为CPU核数
配合着系统内核参数把文件描述符调为一致的数值
cpu亲和
	把某些worker进程绑定到具体的cpu上运行,当一个进程始终使用一个cpu,意味着可以有效率地利用cpu的缓存,减少内存的访问延迟
	配置的前提是服务器上没有其他的计算密集型的任务,因为如果服务器上还有其他的运行着计算密集型的任务,会对某个cpu造成非常大的消耗与占用,此时因为绑定,会导致某个worker进程长期得不到cpu,效率反而会低

# events块
使用epoll网络io模型
调大连接数

# http块
网络IO优化
	1、开启sendfile优化静态文件的传输速率(零拷贝)
		因为该参数可以减少内核态和用户态之间的拷贝次数。没有sendfile的情况下,传输文件通常需要经历如下步骤,数据需要在用户空间和内核空间之间进行两次拷贝。
		(1)从硬盘读取文件到内核缓冲区(磁盘→内核)
		(2)内核缓冲区的数据拷贝到用户空间的缓冲区(内核→用户空间)
		(3)将读取的数据从用户空间缓冲区写入到操作系统的网络缓冲区(用户空间→内核)
		(4)操作系统网络缓冲区发送数据到网络(内核→网络)
		开启零拷贝后的流程
		(1)磁盘 → 内核缓冲区
		(2)内核缓冲区 → 内核网络缓冲区
		(3)内核网络缓冲区 → 网卡
	2、控制tcp连接的两个参数
		tcp_nopush:Nginx将尽可能发送较大的 TCP 数据包,减少 TCP 报文的数量,提高传输效率
		tcp_nodelay:数据将会尽快发送出去,而不是等待缓冲区满或者接收到ACK。这会减少延迟,但可能会造成网络利用率低。这个选项在处理需要快速响应的短数据流(例如HTTP/1.1的keep-alive连接)时非常有用。
	3、控制长连接的两个参数
		keepalive_timeout:如果客户端在xxx秒内没有再次发送新的请求,那么Nginx将关闭这个连接
		keepalive_requests:每个长连接在关闭前能处理的最大请求数量
	4、开启gzip压缩,节省带块加速网络传输
	5、控制客户端请求头的缓冲区大小和数量:应对请求头过大的情况

# server块
启用线程池、reuseport独享全连接队列

做代理服务器的代理配置优化

bash 复制代码
1、配置负载均衡代理到web的长连接,根据需要可以清除请求头字段
2、添加一些必要的请求头,比如透传客户端地址X-Forwarder-For;连接超时,缓冲区优化等配置
3、静态资源缓存
4、防盗链
5、配置允许跨域(前后端分离架构)
	(1)浏览器防止跨域是为了保护用户的数据,但是浏览器的同源策略与跨站请求伪造攻击是两个不相干的东西。跨站请求伪造攻击(CSRF),是利用了用户之前已经认证过的身份(比如登录后的cookie信息),在用户不知情的情况下,用用户的身份去做不良的操作。这里的关键是,恶意行为在于发送请求,而并不需要读取响应。同源策略对于防止CSRF帮助不大,因为同源策略并不能阻止恶意网站发起跨站请求只是限制响应包。
	(2)跨站请求伪造攻击的防止有效方法是:网站会在用户发送请求时,附带一个在服务端生成的token(称之为CSRF tokens),服务端在收到请求时,会检查这个token,只有当这个token是合法的,才会处理这个请求,从而预防了CSRF。
相关推荐
芳草萋萋鹦鹉洲哦16 小时前
【windows】nginx如何注册为开机自启的服务(WinSW实现)
运维·windows·nginx
尽兴-19 小时前
Elasticsearch 性能调优指南:写入、检索、聚合与缓存全链路优化
大数据·elasticsearch·缓存·性能优化·es 读写原理
钛态19 小时前
Flutter for OpenHarmony:shelf_web_socket 快速构建 WebSocket 服务端,实现端到端实时通信(WebSocket 服务器) 深度解析与鸿蒙适配指南
服务器·前端·websocket·flutter·华为·性能优化·harmonyos
LSL666_20 小时前
云服务上安装nginx
java·运维·nginx
禾小西1 天前
深入理解 Java String:从底层原理到高性能优化实战
java·开发语言·性能优化
桌面运维家1 天前
KVM虚拟机:存储IO瓶颈诊断与Linux性能优化实战
linux·运维·性能优化
刘~浪地球1 天前
Nginx + Tomcat 整合实战(五):性能优化与缓存策略
nginx·性能优化·tomcat
一个天蝎座 白勺 程序猿1 天前
KingbaseES性能优化实战:从CPU高使用率到高效运行的全路径解析
数据库·性能优化·时序数据库
Java刺客1 天前
故障复盘:前置机双网卡导致的路由冲突(XX医院院,偶发网络连接不上,路由网卡随机导致)
nginx
cyber_两只龙宝1 天前
【Nginx】Nginx中location的使用方法详解
linux·运维·nginx·云原生·php·web