Nginx基础

主流Web服务器

Nginx,Apache,Tomcat

Nginx优点

高并发高性能高可靠,可扩展性好,热部署,BSD许可证

Nginx应用场景

  • 静态资源服务
  • 反向代理服务
  • API服务

Nginx分析 - 图1

Nginx组成

  • 二进制可执行文件
  • conf配置文件
  • access.log访问日志
  • error.log错误日志

Nginx配置语法

  • 配置文件由指令和指令块构成
  • 指令以分号结尾,指令与参数间以空格分隔
  • include允许组合多个配置文件以提升可维护性
  • 使用#添加注释
  • 使用$使用变量
  • 部分指令参数支持正则表达式

四大块:http、server、upstream、location

Nginx命令行使用

  • 使用指定的配置文件:-c
  • 指定配置指令:-g
  • 指定运行目录:-p
  • 发送信号:-s
    立刻停止服务:stop
    优雅停止服务:quit
    重载配置文件:reload
    重载开始记录日志文件:reopen
  • 测试配置文件是否有语法错误:-t -T

搭建简单的静态资源Web服务器

搭建简单的具备缓存功能的反向代理服务

Nginx架构

Nginx请求处理流程

Nginx分析 - 图2

Nginx进程结构

Nginx分析 - 图3

多进程结构足够健壮,能够利用多核特性,单进程结构不适用于生产环境

不使用多线程结构:多进程结构高可用高可靠,防止第三方模块出现段错误导致整个Nginx挂掉

  • Master进程:管理Worker进程
  • Worker进程:处理请求,每个Worker进程绑定一个CPU
  • Cache进程:缓存相关
  1. nginx -s reload # 优雅退出Worker和Cache进程并重新生成Worker进程和Cache进程
  2. kill -SIGHUP MASTERPID # 同上
  3. kill -SIGTERM WORKERPID # 杀死某个Worker进程,Master进程收到SIGCHLD信号后重新生成一个Worker进程

Nginx信号机制

红色信号只能使用kill命令发送

Nginx分析 - 图4

Nginx命令行原理:启动Nginx后会把pid写到某个文件中,执行Nginx命令行时才去读取该pid文件

Nginx reload流程

Nginx分析 - 图5 reload流程.jpg>)

  1. 更新Nginx配置文件
  2. 向Master进程发送HUP信号(或者reload命令)
  3. Master进程检查配置文件语法的正确性
  4. Master进程打开新的监听端口
  5. Master进程使用新配置启动新的Worker子进程
  6. Master进程向旧的Worker子进程发送QUIT信号
  7. 旧的Worker进程关闭监听句柄,处理完连接后结束进程

Nginx热升级流程

Nginx分析 - 图6

  1. 将旧的Nginx可执行文件替换成新的Nginx可执行文件(备份)
  2. 向Master进程发送USER2信号(kill)
  3. Master进程修改pid文件名(加后缀.oldbin)
  4. Master进程用新的Nginx可执行文件启动新的Master进程
  5. 向旧的Master进程发送WHICH信号,关闭旧的Worker进程
  6. 回滚:向旧的Master进程发送HUP信号,向新的Master进程发送QUIT信号

优雅关闭Woker进程

  1. 设置定时器:worker_shutdown_timeout
  2. 关闭监听句柄
  3. 关闭空闲连接
  4. 在循环中等待全部连接关闭
  5. 退出进程

Nginx事件循环

Nginx分析 - 图7

Nginx请求切换

Nginx分析 - 图8

一个进程只处理一个连接:不做连接切换,依赖OS的进程调度实现并发,并发数很大时性能很低

一个进程同时处理多个连接:用户态代码完成连接切换,尽量减少OS进程切换

Nginx的同步和异步

Nginx模块

ngx_modules.c

  • 内聚
  • 抽象

Nginx模块分类

Nginx分析 - 图9

Nginx连接池

Nginx分析 - 图10

Nginx内存池

Nginx进程间通讯方式

  • 信号
  • 共享内存
    锁(自旋锁)
    slab内存管理器

Slab内存管理器

  • 适合小对象
  • 避免碎片和重复初始化
  • 最多两倍内存消耗

Nginx容器

数组,链表,队列,哈希表,红黑树,基数树

Nginx动态模块

减少编译环节

HTTP模块详解

反向代理和负载均衡

Nginx性能优化

性能优化方法论

软件层面优化

  • 增大CPU利用率
  • 增大内存利用率
  • 增大磁盘IO利用率
  • 增大网络带宽利用率

硬件层面优化

  • 网卡:万兆网卡以上
  • 磁盘:固态硬盘,关注IOPS和BPS指标
  • CPU:更高主频,更多核心,更大缓存,更优架构
  • 内存

超出硬件性能上限后使用DNS

高效使用CPU

  • master-worker多进程架构,worker进程数量应等于CPU核数
  • worker进程不应在繁忙时主动让出CPU,或者说阻止API引发的时间片内主动让出CPU
    速度不一致(硬件速度不一致,如CPU和磁盘)
    业务场景(等待网络IO)
  • 提高优先级占用CPU更长的时间
  • 减少OS上耗资源的非Nginx进程

补充

  • worker进程尽可能处于R状态
  • 尽可能减少进程间切换
    减少主动切换
    减少被动切换(增大优先级提高CPU时间片)
  • 绑定CPU

多核负载均衡

Nginx分析 - 图11

  • accpet加互斥锁
  • REUSEPORT

多队列网卡对多核CPU的优化

  • RSS:硬中断负载均衡
  • RPS:软中断负载均衡
  • RFS

提升CPU缓存命中率

  • 绑定woker进程到CPU

NUMA架构

Nginx分析 - 图12

控制TCP三次握手参数

SYN_SEND状态

  • net.ipv4.tcp_syn_retries = 6 主动建立连接时,发SYN的重试次数
  • net.ipv4.ip_local_port_range = 32768 60999 建立连接时本地端口可用范围

SYN_RCVD状态

  • net.ipv4.tcp_max_syn_backlog SYN_RCVD状态连接的最大个数
  • net.ipv4.tcp_synack_retries 被动建立连接时,发SYN+ACK的重试次数

Nginx分析 - 图13

建立TCP连接的优化

SYN攻击:攻击者短时间内伪造不同IP地址的SYN报文,快速占满backlog队列,使服务器不能正常服务

  • net.ipv4.tcp_max_syn_backlog SYN_RCVD状态连接的最大个数
  • net.ipv4.tcp_abort_on_overflow 超出处理能力时,对新来的SYN直接回包RST

tcp_syncookies

Nginx分析 - 图14 cookie.jpg>)

net.ipv4.tcp_syncookies = 1

当SYN队列满后,新的SYN不进入队列,计算出cookie再以SYN+ACK返回给客户端,客户端发送报文时,服务端根据报文携带的cookie恢复连接

cookie会导致TCP可选功能失效,如扩展窗口,时间戳等

net.core.somaxconn 系统最大backlog队列长度

TFO(Tcp Fast Open)

Nginx分析 - 图15
net.ipv4.tcp_fastopen =

0关闭,1作为客户端使用TFO,2作为服务端使用TFO,3都能使用TFO