nginx 学习

197 阅读2分钟

八股文

先放一段八股文镇贴。

nginx 的架构

轻量

  • 源代码只包含核心模块
  • 其他非核心功能都是通过模块实现,可以自由选择

工作流程

  1. Nginx 在启动后,会有一个 master 进程和多个独立的 woeker 进程。
  2. 接收来自外界的信号,向各 worker 进程发送信号,每个进程都有可能来处理这个连接。
  3. master 进程能监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会启动新的 worker 进程。
  4. worker 进程数,一般会设置成机器 cpu 核数。因为更多的 worker 数,只会导致进程相互竞争 cpu,从而带来不必要的上下文切换。
  5. 使用多进程模式,不仅能提高并发率,而且进程之间相互独立,一个 worker 进程挂了不会影响到其他 worker 进程。

IO 多路复用

  • 多个文件描述符的 IO 操作都能在一个进程里并发交替顺序完成,复用线程。

CPU 亲和

  • 把 CPU 内核和工作进程绑定在一起,让每个 worker 进程固定在一个 CPU 上执行,从而减少 CPU 的切换并提高缓存命中率,提高性能。

sendfile

  • sendfile 零拷贝传输模式

安装

这个在网上教程很多,我这边用的阿里云服务器,使用 yum 安装。大家自己安装了。

yum install nginx -y // 安装 nginx
nginx -v // 查看版本
nginx -V // 查看编译时的参数

目录

安装目录

查看 nginx 安装的配置文件和目录

rpm -ql nginx // 查看 nginx 安装的配置文件和目录

日志切割文件

/etc/logrotate.d/nginx

对访问日志进行切割

/var/log/nginx/*.log {
    daily
}

主配置文件

路径用途
/etc/nginx/nginx.conf核心配置文件
/etc/nginx/conf.d/default.conf默认http服务器配置文件
user nginx; // 启动 nginx 的用户
worker_processes auto; // worker 进程数,一般和 cpu 核数相等
error_log /var/log/nginx/error.log; // 错误日志的路径,日志的格式
pid /run/nginx.pid; // 进程 ID 写入的文件

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024; // 工作进程的最大连接数
}

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; // 包含 mime 文件
    default_type        application/octet-stream; // 默认类型是二进制文件
    
    include /etc/nginx/conf.d/*.conf; // 引入 /etc/nginx/conf.d/ 下所有配置

    server { // 配置服务的,是最核心的配置文件
        listen       80; // 监听端口
        listen       [::]:80; 
        server_name  _; // 服务名字或者是域名;或者IP
        root         /usr/share/nginx/html; // 根目录文件

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        
        // location = 表示完全匹配 没有 = 表示匹配前缀
        // 当两个前缀匹配成功时,取最长的
        location / {
            root /usr/share/nginx/html; // 文件根路径 根目录
            index index.html index.htm; // 索引文件 默认文件
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

常用命令

systemctl restart nginx.service // 重启nginx服务
systemctl reload nginx.service // 重新加载
nginx -t // 检查nginx配置

nginx 核心模块

监听nginx客户端的状态

模块名

  • --with-http_stub_status_module 监控nginx客户端的状态

代码

server {
    location /status {
        stub_status on;
    }
}

通过 /status 路径访问(http://127.0.0.1/status)

Active connections: 2   当前nginx正在处理的活动连接数
server accepts handled requests
        3       3       10
Reading: 0 Writing: 1 Waiting: 1
参数含义
Active connections当前nginx正在处理的活动连接数
acceptss总共处理的连接数
handled总共创建的握手数
requests总共处理的请求数
Reading读取到客户端Header信息
Writing正在返回给客户端Header信息
Waiting等待 如果开启了keep-alive = active - (raading+writing)

模块名

  • --with-http_random_index_module 在根目录里随机选择一个主页显示

代码

server {
    location /status {
        random_index on;
    }
}

内容替换

  • --with-http_sub_module 内容替换

代码

server {
    location /status {
        sub_filter 'name' 'aaa';
    }
}

请求限制

  • --with-limit_conn_module 连接频率限制
  • --with-limit_req_module 请求频率限制
  • limit_conn_zone 共享内存空间
  • limit_req_zone 共享内存空间

代码

limit_conn_zone $binary_remote_addr zone=conn_zone: 10m;
limit_req_zone $binary_remote_addr zone=req_zone: 10m rate=1r/s;
server {
    location / {
       root /usr/share/nginx/html;
       index index.html index.htm;
       # 并发连接配置
       limit_conn conn_zone 1;
       limit_conn_status 500;
       limit_conn_log_level warn;
       limit_rate 50;
       # 并发请求配置
       limit_req zone=req_zone burst=3; # 漏斗算法缓存的数量
    }
}

访问控制

  • 基于IP的访问控制 -http_access_module

代码

server {
    location / {
        deny 192.171.207.100;
        allow all;
    }
}