Nginx 从入门到实战

一、系统环境

  • 系统版本:Centos 7.0 以上版本,64 位。
  • 环境调试
    • 四个确认
      • 确认系统网络:ping www.baidu.com
      • 确认 yum 可用:yum list | grep gcc
      • 确认关闭 iptables 规则:iptables -F && iptables -t nat -F
      • 确认停用 selinux:setenforce 0
    • 两项安装
      • yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
      • yum -y install wget httpd-tools vim
      • yum -y install net-tools
    • 一次初始化
      • cd /opt
      • mkdir app download logs work backup
    • SSH 登录
      • 编辑 SSH 配置文件:vi /etc/ssh/sshd_config
        • Port 22
        • ListenAddress 0.0.0.0
        • ListenAddress ::
        • PermitRootLogin yes
        • PasswordAuthentication yes
      • 启用 SSH 服务:service sshd restart
      • 设置 SSH 开机启动:systemctl enable sshd.service
      • 虚拟机设置端口转发规则:https://www.jianshu.com/p/120ee4a6be9e

二、Nginx 的中间件架构

Nginx 简述

Nginx 是一个开源、高性能、可靠的 HTTP 中间件、代理服务器。

Nginx 优势

  • IO 多路复用 epoll。
  • 功能模块少、代码模块化。
  • CPU 亲和(affinity)
  • sendfile

什么是 IO 多路复用

多个描述符的 IO 操作都能在同一个线程内并发交替地顺序完成,这就叫 IO 多路复用。

什么是 epoll

IO 多路复用的实现方式。

什么是 CPU 亲和(affinity)

是一种把 CPU 核心和 Nginx 工作进程绑定凡事,把每个 worker 进程固定在一个 CPU 上执行,减少切换 CPU 的 Cache Miss,获得更好的性能。

什么是 sendfile

Nginx 安装

1). 新增 yum 源

1
vim /etc/yum.repos.d/nginx.repo

2). 编辑 yum 源

1
2
3
4
5
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

3). 测试 yum 源是否可用

1
yum list | grep nginx

4). 安装 nginx

1
yum -y install nginx

Nginx 基础使用

1). 安装目录讲解

1
2
# 显示程序安装目录
rpm -ql nginx

路径 类型 作用
/etc/logrotate.d/nginx 配置文件 Nginx 日志轮转,用于 logrotate 服务的日志切割
/etc/nginx 目录 Nginx 目录
/etc/nginx/nginx.conf 配置文件 Nginx 主配置文件
/etc/nginx/conf.d 配置文件 Nginx 主配置文件
/etc/nginx/conf.d/default.conf 配置文件 Nginx 主配置文件
/etc/nginx/fastcgi-params 配置文件 cgi 配置文件
/etc/nginx/uwsgi-params 配置文件 cgi 配置文件
/etc/nginx/scgi-params 配置文件 cgi 配置文件
/etc/nginx/mime.types 配置文件 设置 HTTP 协议的 Content-Type 与扩展名对应关系
/etc/lib/systemd/system/nginx-debug.service 配置文件 用于配置出系统守护进程管理器管理方式
/etc/lib/systemd/system/nginx.service 配置文件 用于配置出系统守护进程管理器管理方式
/etc/sysconfig/nginx 配置文件 用于配置出系统守护进程管理器管理方式
/etc/sysconfig/nginx-debug 配置文件 用于配置出系统守护进程管理器管理方式
/etc/lib64/nginx/modules 目录 Nginx 模块目录
/etc/nginx/modules 目录 Nginx 模块目录
/usr/sbin/nginx 命令 Nginx 服务的启动管理的终端命令
/usr/sbin/nginx-debug 命令 Nginx 服务的启动管理的终端命令
/usr/share/doc/nginx-1.12.0 目录 Nginx 的手册和帮助文件
/var/cache/nginx 目录 Nginx 的缓存目录
/var/log/nginx 目录 Nginx 的日志目录

2). Nginx 编译参数

1
2
# 显示编译参数
nginx -V

编译选项 作用
–prefix=/etc/nginx 设定 Nginx 安装目录
–sbin-path=/usr/sbin/nginx 设定 Nginx 可执行文件安装路径
–modules-path=/usr/lib64/nginx/modules 设定 Nginx 模块目录
–conf-path=/etc/nginx/nginx.conf 设定 Nginx 配置文件路径
–error-log-path=/var/log/nginx/error.log 设定 Nginx 错误日志文件路径
–http-log-path=/var/log/nginx/access.log 设定 Nginx HTTP 请求日志文件路径
–pid-path=/var/run/nginx.pid 设定 nginx.pid 的路径
–lock-path=/var/run/nginx.lock 设定 nginx.lock 文件的路径
–http-client-body-temp-path=/var/cache/nginx 指定 HTTP 客户端请求缓存文件存放目录的路径
–http-proxy-temp-path=/var/cache/nginx/proxy_temp 指定 HTTP 反向代理缓存文件存放目录的路径
–http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp 指定 HTTP FastCGI缓存文件存放目录的路径
–user=nginx 设定 Nginx 进程启动的用户
–group-nginx 设定 Nginx 进程启动的用户组

3). Nginx 日志类型

  • error_log:存储 Nginx 错误日志
  • access_log:存储 HTTP 请求相关日志

内置的日志级别有:

  • 第一级别日志
    • stderr
    • emerg
    • alert
    • crit
    • error
    • warn
    • notice
    • info
    • debug
  • 第二级别日志
    • debug_core
    • debug_alloc
    • debug_mutex
    • debug_event
    • debug_http
    • debug_mail
    • debug_mysql
1
2
3
4
5
6
7
8
# 定义错误日志
error_log path/logs/error.log info
# 自定义日志格式
log_format customLog "$remote_addr^A$remote_user^A$time_local^A$request_method^A$uri^A$args^A$server_protocol"
"^A$status^A$body_bytes_sent^A$http_referer"
"^A$http_user_agent";
access_log path/logs/access.log customLog

4). Nginx 变量

  • HTTP 请求变量
  • 内置变量
  • 自定义变量

5). Nginx 模块

  • Nginx 官方模块
  • Nginx 第三方模块

5-1). http_stub_status_module 模块

这个模块的作用是展示 Nginx 当前处理连接的状态。

模块的配置语法:

  • Syntax: stub_status;
  • Default:
  • Context: server, location
1
2
3
location /nginx-http-stub-status-module {
stub_status;
}
  • Active connections:Nginx 当前活跃的连接数
  • server accepts handled requests
    • 第一个参数:Nginx 处理握手总次数
    • 第二个参数:Nginx 处理连接总次数
    • 第三个参数:Nginx 处理请求总次数
  • Reading
    • 第一个参数:表示正在读取的连接数量
    • 第二个参数:表示正在写入的连接数量
    • 第三个参数:表示正在等待的连接数量

5-2). http_random_index_module 模块

这个模块的作用是从指定目录中随机选择一个文件作为主页。

模块的配置语法:

  • Syntax: random_index on | off;
  • Default: random_index off;
  • Context: server, location
1
2
3
4
location /nginx-http-random-index-module {
alias /opt/app/HttpRandomIndexModule/;
random_index on;
}

5-3). http_sub_module 模块

这个模块的作用是用于 HTTP 内容替换。

模块的配置语法:

  • Syntax: sub_filter (string) (replacement);
  • Default:
  • Context: http, server, location
  • 设置字符串替换;string 是被替换的字符串,replacement 是新的字符串。

  • Syntax: sub_filter_last_modified on | off;

  • Default: sub_filter_last_modified off;
  • Context: http, server, location
  • 判断是否存在更新,存在更新则返回新的资源,否则返回缓存。

  • Syntax: sub_filter_once on | off;

  • Default: sub_filter_once on;
  • Context: http, server, location
  • 设置字符串替换是多次替换或只是替换一次。
1
2
3
4
5
6
location /nginx-http-sub-module {
alias /opt/app/HttpSubModule/;
index index.html;
sub_filter '<h1>Hello World</h1>' '<h5>Luis Edware</h5>';
sub_filter_once off;
}

5-4). limit_conn_module 模块

这个模块的作用是根据定义的键来限制每个键值的 TCP 连接数。

  • Syntax: limit_conn_zone key zone=name:size;
  • Default: none
  • Context: http

该指令描述会话状态存储区域。键的状态中保存了当前连接数,键的值可以是特定变量的任何非空值。key 定义键,zone=name 定义区域名称,size 定义各个键共享内存空间大小。如果内存空间被耗尽,服务器将会对后续所有的请求返回 503 错误。

  • Syntax: limit_conn zone number;
  • Default: none
  • Context: http, server, location

该指令给每个键值指定最大同时连接数,当超过这个数字时返回 503 错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
limit_conn_zone $binary_remote_addr zone=conn_zone:1m;
server{
...
location /nginx-limit-conn-module {
alias /opt/app/LimitConnModule/;
index index.html;
limit_conn conn_zone 1;
}
...
}

5-5). limit_req_module 模块

这个模块的作用是根据定义的键值来限制请求处理的频率。限制的方法如同漏斗,每秒固定处理请求数,推迟过多请求。

  • Syntax: limit_req_zone $variable zone=name:size rate=rate;
  • Default: none
  • Context: http

设置一块共享内存限制域用来保存键值的状态参数。速度可以设置为每秒处理请求数和每分钟处理请求数,其值必须是整数,所以如果你需要指定每秒处理少于1个的请求,2秒处理一个请求,可以使用 “30r/m”

  • Syntax: limit_req zone=name [burst=number] [nodelay];
  • Default: none
  • Context: http, server, location

设置对应的共享内存限制域和允许被处理的最大请求数阈值。 如果请求的频率超过了限制域配置的值,请求处理会被延迟,所以所有的请求都是以定义的频率被处理的。 超过频率限制的请求会被延迟,直到被延迟的请求数超过了定义的阈值,这时,这个请求会被终止,并返回503 (Service Temporarily Unavailable) 错误。这个阈值的默认值为0

1
2
3
4
5
6
7
8
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
location /nginx-limit-req-module {
alias /opt/app/LimitReqModule/;
index index.html;
# nodelay 参数表示不希望超过的请求被延迟,burst 参数表示请求阈值。
limit_req zone=req_zone burst=5 nodelay;
}

5-6). http_access_module 模块

这个模块的作用是提供对于特定 host 的客户端的访问控制。对于使用了代理服务器的客户端的请求识别率不高。

  • Syntax: allow address | CIDR | unix: | all;
  • Default: none
  • Context: http, server, location, limit_except
1
2
3
4
5
location /nginx-http-access-module {
alias /opt/app/HttpAccessModule/;
index index.html;
allow 192.168.1.103;
}
  • Syntax: deny address | CIDR | unix: | all;
  • Default: none
  • Context: http, server, location, limit_except
1
2
3
4
5
location /nginx-http-access-module {
alias /opt/app/HttpAccessModule/;
index index.html;
deny all;
}

5-7). http_auth_basic_module 模块

这个模块的作用是让用户输入正确的账号和密码才允许访问 Web 资源。使用 htpasswd 生成账号密码文件。

  • Syntax: auth_basic string | off;
  • Default: auth_basic off;
  • Context: http, server, location, limit_except
  • Syntax: auth_basic_user_file file;
  • Default: none
  • Context: http, server, location, limit_except
1
2
3
4
5
6
location /nginx-http-auth-basic-module {
alias /opt/app/HttpAuthBasicModule/;
auth_basic "Hello World! Please input your account and password!";
auth_basic_user_file /opt/app/HttpAuthBasicModule/AccountPassword;
index index.html;
}

http_auth_basic_module 局限性

  • 用户信息依赖文件方式
  • 操作管理机械,效率低下

解决方案

  • Nginx 结合 Lua 实现高效验证
  • Nginx 结合 LDAP,利用 nginx-auth-ldap 模块

Nginx 进阶学习

一、静态资源 Web 服务

二、代理服务

三、负载均衡调度器 SLB

四、动态缓存