通俗易懂理解nginx

117 阅读7分钟

nginx

简介

Nginx(发音为 "engine-x")是一个高性能的 Web 服务器、反向代理服务器和电子邮件(IMAP/POP3)代理服务器,它以其稳定性、丰富的功能、高性能和低资源消耗而著称。Nginx 最初由 Igor Sysoev 开发,并于 2004 年首次公开发布。如今,它已经成为全球最受欢迎的 Web 服务器之一,许多大型网站和应用程序都在使用 Nginx

Nginx是用C语言编写的,速度极快,性能卓越。在后端语言中,C和C++被公认为性能最高的语言。Nginx的单机并发量可达到5w+,远高于一般的后端Java程序。因此,通常会选择将Nginx作为网关放在Java程序之前,以提升整体系统性能

术语

  • 模块:不同模块包含不同指令。nginx包含默认模块、支持第三方模块、支持动态加载模块
  • 指令:不同指令支持不同功能,指令包含参数和值
  • 变量:内置变量

功能

  • 静态文件服务:可以快速地为客户端提供 CSS、JavaScript、图片等静态资源
  • 反向代理、负载均衡、容错性:可以将传入的请求转发到其他服务器或应用程序上,在多个后端服务器之间分配流量,从而提高系统的可用性和性能
  • 动态网页处理:可以与PHP、Python等动态语言配合使用,通过FastCGI协议或uWSGI协议来处理动态网页的请求
  • 缓存:可以缓存静态和动态内容,以减少对后端服务器的访问次数,提高应用程序的响应速度和性能
  • 日志:可以记录详细的访问日志和错误日志,以帮助管理员更好地监控和管理服务器
  • 模块化:拥有丰富的扩展模块,例如gzip压缩、HTTP/2协议、WebSocket支持、缓存刷新等,可以按需加载,从而满足不同场景下的需求

FAQ

  • nginx怎么处理一个http请求

    • 根据请求中host指定的域名,匹配server_name,如果没匹配,用默认的server_name,通常为第一个,或者指定default_server
    • 在listen配置ip,同时server_name存在时,ip优先级大于server_name
    • nginx.org/en/docs/htt…
  • nginx怎么实现高并发

    • nginx采用一个master进程负责一组worker进程,每个worker进程采用异步非阻塞方式处理请求
    • 每个请求来有一个worker处理,但不是全处理,如向后端转发请求,worker发送后注册一个事件event,开始处理新请求,当后端返回会触发事件,worker才接着处理
    • nginx采用单worker线程异步非阻塞方式处理请求,不用为每个请求分片cpu和内存,节省资源同时减少cpu的上下文切换,所有nginx支持并发更高
    • nginx没有采用多线程,进程和线程都需要cpu和内存资源,并发过大会耗光服务器资源
  • nginx怎么优化性能

    • 全局优化
      • 调整worker进程数 worker_processes (建议与系统cpu核数相同),event连接数 worker_connections
      • 最大客户端数/秒 = worker_processes * worker_connections
      • 禁用全局访问日志 access_log off
    • 与客户端之间优化
      • 启用压缩 gzip ,减少客户端http的传输带宽,提高页面加载速度
      • 启用静态文件缓存 expires 、Cache-Control
      • 启用 sendfile tcp_nodelay tcp_nopush
    • 与后端服务之间优化
      • 启用长连接 keepalive 减少打开和关闭连接需cpu和内存开销
      • 启用代理缓存 proxy_cache
  • nginx的内存大小

  • nginx怎么实现灰度发布

    • 请求路由:通过请求中的标识(如用户ID、设备ID、请求头、Cookie/Session等)来决定是否将请求路由到灰度环境
    • 权重控制:将流量按照一定的权重比例分配到不同的环境中
    • 特性开关:通过在代码中嵌入特性开关(Feature Flag)来控制功能的开启与关闭
    • 分阶段发布:将功能的发布分为多个阶段,从内部测试到灰度环境再到全量发布
    • A/B测试:将流量分为多个不同版本的应用程序,比较它们的性能和用户反馈
    • mp.weixin.qq.com/s/7-URYtEMz…
  • nginx怎么防止攻击

    • SSL加密: 启用https访问
    • 黑名单: allow/deny
    • 防盗链: valid_referers
    • 限流: 对请求限制,防止系统完全不可用。限制单位时间内IP请求次数、IP请求频率、请求大小,返回503 limit_req 、limit_conn 、limit_rate_after
    • 熔断: 依赖下游服务是否故障来触发熔断,避免单位时间对下游服大量请求导致下游崩溃,下游恢复后自动恢复 max_fails 、fail_timeout 、proxy_next_upstream
    • 降级:服务分优先级,非核心服务不可用,保证核心服务可用
  • nginx怎么加速访问

    • 启用静态缓存 Cache-Control、Expires
    • 启用代理缓存 proxy_cache
    • 负载均衡
    • 动静资源分离:静态访问本地或存储,动态访问后端服务
    • 长连接
  • nginx怎么会话保持

    • 基于IP地址:upstream 中设置 ip_hash 指令
    • 基于cookie:启用 nginx-sticky-module-ng 模块中 sticky 指令
  • nginx怎么监控流量

    • 启用 nginx-module-vts 模块
    • 分析 nginx 日志,服务请求聚合,服务质量监控
  • 怎么批量管理nginx

    • ansible
  • 概念

    • 流量切分: 一套系统,给更新服务器设置较低权重,逐渐提高权重
    • 保证新上线的系统稳定
      • 蓝绿部署: 两套系统,一套绿色、一套蓝色,考虑如何切换、数据是否需同步
      • 金丝雀发布/灰度发布:一套系统,逐步替换。先给更新的服务器设置较低权重,逐渐提高权重
    • 效果测试
      • A/B测试: 同时有多个版本对外服务

基本操作

安装

# 查看版本
yum list nginx

# 安装指定版本
yum install nginx-1.20.1 -y

# 卸载
yum remove nginx-1.20.1 -y

目录结构

# 查看安装结构
rpm -ql nginx
# /usr/sbin/nginx 执行命令
# /usr/bin/nginx-upgrade 升级命令
# /etc/nginx/ 配置文件
# /usr/lib64/nginx/modules 模块
# /usr/share/nginx/modules 配置模块
# /var/log/nginx 日志
# /usr/share/nginx/html/404.html 静态文件
# /var/lib/nginx 
# /etc/logrotate.d/nginx 日志轮询
# /usr/lib/systemd/system/nginx.service 系统管理

启停

# 用一种方式即可,推荐systemd
# 系统管理
# 启动
systemctl start nginx
# 停止
systemctl stop nginx
# 重载
systemctl reload nginx

# 命令管理
# 检测配置
nginx -t
# 启动
nginx
# 停止
nginx -s stop
# 重载
nginx -s reload

进程结构

# 进程
ps aux |grep nginx | grep -v grep
# root      4429  0.0  0.0  39312   936 ?        Ss   13:39   0:00 nginx: master process /usr/sbin/nginx
# nginx     4430  0.0  0.0  39700  1820 ?        S    13:39   0:00 nginx: worker process
# nginx     4431  0.0  0.0  39700  1560 ?        S    13:39   0:00 nginx: worker process

# master process:由root用户运行的第一个进程,负责解析和读取配置文件,管理其他所有子进程
# worker process:由主进程启动的多个子进程,用于处理客户端请求,相互之间没有通信,提供并发处理
# cache loader process:处理Nginx反向代理缓存。当缓存过期或空间不足时,缓存进程会自动删除旧的缓存项,并将新的缓存项加载到内存中
# log processor process:处理Nginx访问日志和错误日志。由主进程自动创建和退出,与工作进程并行运行,同时处理多个日志文件,并可以记录各种详细的信息
# control process:处理Nginx通信。通过发送信号给主进程,控制进程可以启动、停止、重新加载Nginx配置文件,以及修改Nginx的运行参数等

配置结构

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

# http
http {
    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  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80;
        server_name  _;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;
        error_page 404 /404.html;
        location = /404.html {
        }
        location / {
            index index.html;
        }
    }
}

# tcp
stream {
    upstream tcp_backend {
        server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
    }

    server {
        listen 1234;
        proxy_pass tcp_backend;
    }
}

动态加载模块

# yum管理
# 查看模块
yum list nginx-mod*
# 安装支持stream指令配置tcp代理
yum install nginx-mod-stream-1.20.1 -y
# 查看安装后位置
rpm -ql nginx-mod-stream-1.20.1
# /usr/lib64/nginx/modules/ngx_stream_module.so
# /usr/share/nginx/modules/mod-stream.conf
# 重载
systemctl reload nginx 

第三方模块

# 源码编译安装
VERSION=1.20.1
wget -P /opt/ https://nginx.org/download/nginx-${VERSION}.tar.gz
tar xf nginx-1.20.1.tar.gz
cd nginx-1.20.1/
# 查看模块
./configure --help | grep module
# 下载第三方模块
mkdir module && git clone https://github.com/vozlt/nginx-module-vts.git && cd ..
# 编译
./configure \
        --prefix=/usr/local/nginx \
        --add-module=module/nginx-module-vts
# 编译
make
# 替换nginx二进制
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
cp objs/nginx /usr/local/nginx/sbin/nginx
# 平滑升级nginx
nginx -t
kill -USR2 $(cat /run/nginx.pid)
sleep 1
test -f /run/nginx.pid.oldbin
kill -QUIT $(cat /run/nginx.pid.oldbin)
# 查看nginx编译参数
nginx -v