前端了解 这些 Nginx 基础操作就够了

简介: 前端了解 这些 Nginx 基础操作就够了

官方文档

  • 应用场景

    • 静态资源服务器:通过本地文件系统提供服务
    • 反向代理服务器:Nginx 强大的性能,缓存,负载均衡
    • API 接口服务:OpenResty
  • 优势

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

Nginx 架构

Nginx 采用多进程(单线程)和多路 IO 复用模型

  • 轻量

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

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

    • nginx.org 开源
    • nginx.com 商业
    • openresty.org 开源
    • openresty.com 商业

工作流程

  1. Nginx 启动后会有一个 master 进程和多个相互独立的 worker 进程
  2. 接收来自外界的信号,向 worker 进程发送信号,每个进程都有可能来处理这个连接
  3. master 进程能监控 worker 进程的运行状态,当 worker 进程退出后(异常情况),会自动启动新的 worker 进程

  • worker 进程数,一般会设置为机器的 CPU 核数,因为更多的 Worker 数,只会导致进程相互竞争 CPU,从而带来不必要的上下文切换
  • 使用多进程模式,不仅能提高并发率,而且进程之间相互独立,一个 worker 进程挂了不会影响其他进程
  • 请求处理流程

Nginx 进程管理及通信

  • 基础同步工具

    • 信号
    • 共享内存(跨 worker 进程通讯)

      • Ngx_http_lua_api
      • rbtree
      • 单链表
  • 高级通信方式

    • Slab 内存管理器(Bestfit)

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

    • 监控 worker 进程 CHLD
    • 管理 worker 进程
    • 接收信号

      • TERM,INT
      • QUIT
      • HUP
      • USR2
      • WINCH
  • Worker 进程
    接收信号

    • TERM,INT
    • QUIT
    • USR1
    • WINCH
  • Nginx 命令行

    • reload: HUP
    • reopen: USR1
    • stop: TERM
    • quit: QUIT

Nginx 容器

  • 数组
  • 链表
  • 队列
  • 哈希表

    • Bucket size (对齐)
    • Max size
  • 红黑树
    自平衡二叉查找树

    • 高度不会超过 2 倍 log(n)
    • 增删改查算法复杂度 O(log(n))
    • 遍历复杂度 O(n)
  • 基数树

网络收发与 Nginx 事件对应关系

  • TCP 流与报文

  • TCP 协议与非阻塞接口

    • 读事件

      • Accept 建立连接
      • Read 读消息
    • 写事件

      • Write 写事件

  • 连接池
    构成:

    • 对上游服务器的连接
    • 对下游客户端的连接

Nginx 事件循环

  • epoll
    前提:高并发连接中,每次处理的活跃连接数量占比很小
    实现:红黑树、链表
    使用:

    • 创建
    • 操作:添加/修改/删除
    • 获取句柄
    • 关闭

内存池

  • 连接内存池
  • 请求内存池

IO 多路复用

异步阻塞 IO

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

CPU 亲和

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

sendfile

  • sendfile 零拷贝传输模式

Nginx 模块

  • 内聚
  • 抽象

    • 配置
    • 启停回调方法
    • 子模块抽象

      • http
      • event
      • mail
      • stream
  • nginx 模块分类

编译

  • 下载

    wget http://nginx.org/download/nginx-1.14.0.tar.gz
    
    tar -xzf nginx-1.14.0.tar.gz
    
    cd nginx-1.14.0
  • 编译

    # 进入解压目录下
    ./configure --prefix=/home/cellinlab/nginx # 指定安装目录
    make # 编译 编译结果再 /objs 目录
  • 安装

    make install

安装

  • 关闭防火墙
systemctl disable firewalld.service
  • 安装依赖模块
yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
yum -y install wget httpd-tools vim
  • 创建仓库文件 /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
  • 安装
yum install nginx
  • 检查
nginx -v # 查看安装版本
nginx -V # 查看编译参数

目录说明

  • 日志切割文件 /etc/logrotate.d/nginx
    对访问日志进行切割

    /var/log/nginx/*.log {
      daily
    }
  • 主配置文件

    • 核心配置文件 /etc/nginx/nginx.conf
    • 默认 http 服务器配置文件 /etc/nginx/conf.d/default.conf
  • CGI 配置

    • CGI(Common Gateway Interface) 通用网关接口
    • Web Server 通过 cgi 协议可以把动态的请求传递给如 php、jsp、python 等应用程序
    • FastCGI 是带有拓展功能的 CGI,描述了客户端和 Web 服务器程序之间传输数据的一种标准
    • SCGI 协议是一个 CGI 协议的替代品,应用与 HTTP 服务器的接口标准,类似于 FastCGI,当设计更容易实现
    • uwsgi 是一个 Web 服务器,实现了 WSGI 协议、uwsgi、http 等协议
    路径 用途
    /etc/nginx/fastcgi_params fastcgi 配置
    /etc/nginx/scgi_params scgi 配置
    /etc/nginx/uwsgi_params uwsgi 配置
  • 编码转换映射转换文件

    路径 用途
    /etc/nginx/koi-utf koi8-r <-> utf-8
    /etc/nginx/koi-win koi8-r <-> windows-1251
    /etc/nginx/win-utf windows-1251 <-> utf-8
  • 扩展名文件
    /etc/nginx/mime.types 设置 http 协议的 Content-Type 与 扩展名对应关系
  • 守护进程管理
    用于配置系统守护进程管理器管理方式

    路径 用途
    /usr/lib/systemd/system/nginx-debug.service
    /usr/lib/systemd/system/nginx.service
    /etc/sysconfig/nginx
    /etc/sysconfig/nginx-debug
  • nginx 模块目录
    /etc/nginx/modules 最基本的共享库和内核模块
  • 文档
    手册和帮助文档

    路径 用途
    /usr/share/doc/nginx-1.14.1 帮助文档
    /usr/share/doc/nginx-1.14.0/COPYRIGHT 版权声明
    /usr/share/man/man8/nginx.8.gz 手册
  • 缓存目录 /var/cache/nginx
  • 日志目录 /var/log/nginx
  • 可执行命令
    nginx 服务的启动管理的可执行文件

    路径 用途
    /usr/sbin/nginx 可执行命令
    /usr/sbin/nginx-debug 调试执行可执行命令

配置文件

  • /etc/nginx/nginx.conf 主配置文件
  • /etc/nginx/cond.d/*.conf
  • /etc/nginx/conf.d/default.conf

配置语法

# 使用 # 可以添加注释,使用 $ 可以使用变量
# 配置文件由指令与指令块组成,指令块以 {} 将多条指令组织在一起
http {
  # include 允许把多个配置文件组合起来以提升可维护性
  include mime.types; # 每条指令以 ; 结尾,指令与参数之间以空格分割
  default_type application/octet-stream; # 默认的 Content-Type
  sendfile on; # 启用零拷贝模式
  keepalive_timeout 65; # 活动连接超时时间 单位是 s
  server { # 每个server 对应一个网站
    listen 80;
    server_name localhost; # 域名
    # 有些指令可以支持正则表达式
    location / { # 匹配所有路径
      root html;
      index index.html index.htm;
    }
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
      root html;
    }
  }
}
  • http 配置的指令块

    • http
    • server
    • location
    • upstream

Nginx 命令行

nginx -s reload

  • -? -h 帮助
  • -c 指定配置文件
  • -g 指定配置命令
  • -p 指定运行目录
  • -s 发送信号

    • stop 立即通知服务
    • quit 优雅停止
    • reload 重载配置文件
    • reopen 重新开始记录日志文件
  • -t -T 测试配置文件是否有语法错误
  • -v -V 版本信息 编译参数

日志

  • 日志类型

    • /var/log/nginx/access.log 访问日志
    • /var/log/nginx/error.log 错误日志
  • log_format

    类型 用法
    语法 log_format name [escape=default[json] string]
    默认 log_format combined ""
    Context http
  • 使用 GoAccess 实现 access 日志可视化及实时监控
    参考

    goaccess access.log -o /var/www/html/report.html --log-format=COMBINED --real-time-html

用例

搭建静态资源 web 服务器

将静态资源放在 nginx 目录下指定目录中,如 /nginx/blog


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
  worker_connections  1024;
}

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;

  sendfile        on;
  #tcp_nopush     on;

  #keepalive_timeout  0;
  keepalive_timeout  65;

  gzip on;
  gzip_min_length 1;
  gzip_min_level 2;
  gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;

  server {
    listen 8080;
    server_name blog.cellinlab.xyz;

    access_log log/blog.access.log main;
    location / {
      alias blog/;
      #autoindex on;
      #set $limit_rate 1k;
      #index index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   html;
    }
  }
}

SSL

  • SSL, Secure Sockets Layers
  • TLS, Transport Layer Security

  • TLS 安全密码
  • 对称加密
  • 非对称加密
  • PKI 公钥基础设施
  • CA 证书类型

    • 域名验证证书,DV Domain Validated
    • 组织验证证书,OV Organization Validated
    • 扩展验证证书, EV Extended Validation
  • TLS 通信过程

免费 SSL 实现 HTTPS

yum install python2-certbot-nginx
certbot --nginx --nginx-server-root=/usr/local/openresty/nginx/conf/ -d blog.cellinlab.xyz

HTTP 模块

指令冲突

  • 配置块嵌套

    main
    http {
      upstream {}
      split_clients {}
      map {}
      geo {}
      server {
        location {
          limit_except {}
        }
        location {
          location {
          }
        }
      }
      server {
      }
    }
  • 指令合并

    • 值指令 存储配置项的值

      • 可以合并
      • 如 root、access_log、gzip
      • 继承规则:向上覆盖,子配置覆盖父配置
    • 动作类指令 指定行为

      • 不可以合并
      • 如 rewrite、 proxy_pass
      • 生效阶段 server_rewrite 阶段、rewrite 阶段、content 阶段

listen 指令

  • 语法
    listen address[:port]listen 127.0.0.1:8000
    listen portlisten 800;
    listen unix:pathlisten unix:/var/run/nginx.sock;
  • 默认 listen *:80|*:8000;
  • Context server

接收请求及建立连接

  • 接收请求事件模块
  • 接收请求 HTTP 模块

HTTP 请求处理

HTTP 请求的 11 个阶段

阶段 描述 模块
POST_READ 获取到Header后的第一个阶段 realip
SERVER_REWRITE 配置在server模块中的rewrite阶段 rewrite
FIND_CONFIG 根据配置查找由谁处理请求的阶段
REWRITE 配置在location模块中的rewrite阶段 rewrite
POST_REWRITE
PREACCESS 向上游服务请求连接前的阶段 limit_conn、limit_req
ACCESS 与上游服务器连接的验证阶段 auth_basic、access、auth_request
POST_ACCESS
PRECONTENT 发送data数据前的阶段 try_files
CONTENT 发送数据阶段 index、autoindex、concat
LOG 记录请求日志、错误日志阶段 access_log

11 个阶段的处理顺序

server 模块

  • server_name 指令

    • 指令后可以跟多个域名,第一个是主域名
    • *泛域名:仅支持在最前或者最后 server_name *.cellinlab.xyz
    • 正则:在前面加 ~ server_name www.cellinlab.xyz ~^www\d+\.cellinlab\.xyz$;

      • 用正则创建变量

        # 匿名变量
        server {
          server_name ~^(www\.)?(.+)$;
          location / {
            root /sites/$2;
          }
        }
        # 命名变量
        server {
          server_name ~^(www\.)?(?<domain>.+)$;
          location / {
            root /sites/$domain;
          }
        }
    • .cellinlab.xyz 可以匹配 cellinlab.xyz *.cellinlab.xyz
    • _ 匹配所有
    • "" 匹配没有传递 Host 头部
  • server 匹配顺序

    1. 精准匹配
    2. *在前的泛域名
    3. *在后的泛域名
    4. 按文件中的顺序匹配正则表达式域名
    5. default server
相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
6月前
|
缓存 负载均衡 前端开发
写给前端的nginx知识
写给前端的nginx知识
47 1
|
1月前
|
前端开发 应用服务中间件 nginx
Nginx配置详解Docker部署Nginx使用Nginx部署vue前端项目
Nginx配置详解Docker部署Nginx使用Nginx部署vue前端项目
132 0
|
5月前
|
负载均衡 前端开发 应用服务中间件
【Linux】Nginx安装使用负载均衡及动静分离(前后端项目部署),前端项目打包
【Linux】Nginx安装使用负载均衡及动静分离(前后端项目部署),前端项目打包
387 0
|
12天前
|
前端开发 JavaScript 应用服务中间件
前端vue2、vue3去掉url路由“ # ”号——nginx配置(二)
前端vue2、vue3去掉url路由“ # ”号——nginx配置
37 0
|
5月前
|
前端开发 应用服务中间件 nginx
前端破圈使用Docker Nginx容器部署项目🏴‍☠️
前端破圈使用Docker Nginx容器部署项目🏴‍☠️
|
4月前
|
前端开发 应用服务中间件 nginx
Docker 安装 Nginx 部署前端项目
Docker 安装 Nginx 部署前端项目
324 1
|
5月前
|
缓存 前端开发 网络协议
前端必备 Nginx 配置
前端必备 Nginx 配置
51 0
|
6月前
|
前端开发 JavaScript 应用服务中间件
nginx配置vue前端代理
nginx配置vue前端代理
83 0
|
6月前
|
前端开发 应用服务中间件 nginx
用docker和nginx部署前端项目访问本地java网关gateway服务
本地开发 java 微服务项目,但是拿到的对应的web前端项目只有打包编译过后的 dist 目录里的静态资源(里面只有一个index.html和一些编译过后的 js、css文件),前端接口需要先访问到 java 的网关服务,然后网关里再做转发
204 1
|
6月前
|
前端开发 应用服务中间件 nginx
Nginx启动本地前端项目
Nginx启动本地前端项目