参考文献

  • 深入理解Nginx模块开发与架构解析 陶辉
  • 极客时间 Nginx核心知识150讲 陶辉

Nginx的优点

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

Nginx的三个应用场景

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

Nginx的组成

  • Nginx二进制可执行文件
    • 由各个模块源码编辑出的一个文件
  • nginx.conf配置文件
    • 控制Nginx的行为
    • 默认放置于/usr/local/nginx/conf/etc/nginx/usr/local/etc/nginx
  • access.log访问日志
    • 记录每一条HTTP请求信息
  • error.log错误日志
    • 定位问题
  • nginx.pid 进程ID文件
    • 默认放置于/usr/local/nginx/logs/var/run

Nginx版本

使用Nginx的必备软件

  • GCC编译器

    • GCC(GNU Complier Collection)可以用来编译C语言程序
    1
    2
    yum install -y gcc
    yum install -y gcc-c++
  • PCRE

    • PRCE(Perl Compatible Regular Expressions, Perl 兼容正则表达式)
    1
    yum install -y pcre pcre-devel
  • zilb

    • zilb库用于对HTTP包内容做gzip格式的压缩
    1
    yum install -y zilb zlib-devel
  • OpenSSL开发库

    1
    yum install -y openssl openssl-devel

编译安装Nginx

  • 下载Ngnix

  • Nginx各个目录

    img

    • 执行cp -r contrib/vim/* ~/.vim/,使得Vim识别nginx.conf的配置语法,使其高亮
    • 执行./configure --help |more,查看configure支持的配置
  • Configure

  • 中间文件(objs)

    img

  • 编译

    • ./configure --prefix=/home/holelin/nginx
    • make
  • 安装

    • make install

Linux内核参数优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 表示进程(如一个worker进程)可以同时打开的最大句柄数,这个参数直接限制最大并发连接数,需要根据实际情况配置
fs.file.max = 99999
# 这个参数设置为1,表示允许将TIME-WAIT状态的socket重新用于新的TCP连接
net.ipv4.tcp_tw_resuse = 1
# 这个参数表示当keepalive启用事,TCP发送keepalive消息的频度。默认为2小时。若将其设置得小一点,可以更快的清理无效连接
net.ipv4.tcp_keepalive_time = 600
# 这个参数表示当服务器主动关闭连接时,socket保持在FIN-WAIT-2的状态的最大时间
net.ipv4.tcp_fin_timeout = 30
# 表示操作系统允许TIME_WAIT套接字数量的最大值,若超过这个数字,TIME_WAIT将立即被清除并打印告警信息。该参数默认为18000,过多的TIME_WAIT套接字会使WEB服务器变慢
net.ipv4.tcp_max_tw_buckets = 5000
# 这个参数定义了在UDP和TCP连接中本地(不包括连接的远端)端口的取值范围
net.ipv4.ip_local_port_range = 1024 610000
# 这个参数定义了TCP接收缓存(用于TCP接收滑动窗口)的最小值,默认值,最大值
net.ipv4.tcp_rmem = 4096 32768 262142
# 这个参数定义了TCP发送缓存(用于TCP接收滑动窗口)的最小值,默认值,最大值
net.ipv4.tcp_wmem = 4096 32768 262142

# 当网卡接收数据包的速度大于内核处理的速度时,会有一个队列保存这些数据包,这个参数表示该队列的最大值。
net.core.netdev_max_backlog = 8096
# 这个参数表示内核套接字接收缓存区默认的大小
net.core.rmem_default= = 262144
# 这个参数表示内核套接字发送缓存区默认的大小
net.core.wmem_default= = 262144
# 这个参数表示内核套接字接收缓存区的最大大小
net.core.rmem_max = 2097152
# 这个参数表示内核套接字发送缓存区的最大大小
net.core.wmem_max = 2097152

# 该参数与性能无关 用于解决TCP的SYN攻击
net.ipv4.tcp_syncookies = 1
# 这个参数表示TCP三次握手建立阶段接收SYN请求队列的最大长度,默认为1024,将其设置得大一些可以使出现Nginx繁忙来不及accept新连接的情况时,Linux不至于丢失客户端发起的连接请求。
net.ipv4.tcp_max_syn.backlog = 1024

# 编辑完成后执行sysctl -p使之失效

Nginx编译参数详解

  • 路径相关的参数
参数名称 含义 默认值
--prefix=PATH Nginx安装部署后的根目录 默认为/usr/local/nginx目录。注意: 这个目录的设置会影响其他参数重的相对目录。例如,如果设置了--sbin-path=sbin/nginx那么实际上可执行文件会被放到/usr/local/nginx/sbin/nginx
--sbin-path=PATH 可执行文件的 放置路径 <prefix>/sbin/nginx
--conf-path=PATH 配置文件的放置路径 <prefix>/conf/nginx.conf
--error-log-path=PATH error日志文件的放置路径。error日志用于定位问题,可输出多种级别(包括debug调试级别)的日志。它的配置非常灵活,可以在nginx.conf里面配置为不同请求的日志输出到不同的log文件中,这里是默认的Nginx核心日志路径 <prefix>/logs/error.log
--pid-path=PATH pid存放路径。这个文件里仅以ASCII存放着Nginx master的进程ID,有了这个进程ID,在使用命令行(如 nginx -s reload)通过读取master进程ID向master进程发送信号时,才能对运行中的Nginx服务产生作用 <prefix>/logs/nginx.pid
--lock-path=PATH lock文件的放置路径 <prefix>/logs/nginx.lock
--builddir=DIR configure执行时与编译期间产生的临时文件放置的目录,包括产生的Makefile,C源文件,目标文件,可执行文件 <nginx source path>/objs
--with-perl_modules_path=PATH perl module放置的路径,只有使用了第三方的perl module,才需要配置这个路径
--with-perl=PATH perl binary 放置的路径,如果配置的Nginx会执行Perl脚本,那么就必须要设置此路径
--http-log-path=PATH access日志放置的位置。每一个HTTP请求在结束时都会记录的访问日志 <prefix>/logs/access.log
--http-client-body-temp-path=PATH 处理HTTP请求时如果请求的包体需要暂时存放到临时磁盘文件中,则把这样的临时文件放置到该路径下 <prefix>/client_body_temp
--http-proxy-temp-path=PATH Nginx作为HTTP反向代理服务器时,上游服务器产生的HTTP包体在需要临时存放到磁盘文件时,这样的临时文件将放到该路径下 <prefix>/proxy_temp
--http-fastcgi-temp-path=PATH Fastcgi所使用临时文件放置目录 <prefix>/fastcgi_temp
--http-uwsgi-temp-path=PATH uWSGI所使用临时文件的放置目录 <prefix>/uwsgi_temp
--http-scgi-temp-path=PATH SCGI所使用临时文件的放置目录 <prefix>/scgi_temp
  • 编译相关的参数
编译参数 含义
--with-cc=PATH C编译器的路径
--with-cpp=PATH C预编译的路径
--with-cc-opt=OPTIONS 如果希望在Nginx编译期间指定加入一些编译选项,如指定宏或者使用-I加入某些需要包含的目录,这时可以使用该参数达成目的
--with-ID-opt=OPTIONS 最终的二进制可执行文件是由编译后生成的目标文件与一些第三方库链接生成的,在执行链接操作时可能会需要指定链接参数,–with-Id-opt就是用于加入链接时的参数。如要将某个库链接到Nginx程序中,需要在这里加入–with-Id-opt=librayName -LlibaryPath,其中libaryName是目标库的名称,libraryPath则是目标库所在的路径
--with-cpu-opt=CPU 指定CPU处理架构,只能从以下取值: pentium,pentiumpro,pentium3,pentium4,athlon,opteron,sparc32,sparc64,ppc64
  • 依赖软件的相关参数
PCRE库的设置参数 意义
--without-pcre 如果确认Nginx不用解析正则表达式,也就是说,nginx.conf配置文件中不会出现正则表达式,那么可以使用这个参数
--with-pcre 强制使用PCRE库
--with-pcre=DIR 指定PCRE库源码位置,在编译Nginx时会进入该目录编译PCRE源码
--with-pcre-opt=OPTIONS 编译PCRE源码时希望加入的编译选项
OpenSSL库的设置参数 意义
--with-openssl=DIR 指定OpenSSL库的源码位置,在编译Nginx时会进入该目录编译OpenSSL源码
--with-openssl=OPTIONS 编译OpenSSL源码时希望加入的编译选项
  • 其他参数

  • 其他参数 含义
    --with-debug 将Nginx需要打印debug调试级别日志的代码编译进Nginx
    --add-module=PATH
    --without-http
    --without-http-cache
    --with-file-aio
    --with-ipv6
    --user=USER
    --group=GROUP

Nginx配置语法

  • 配置文件由指令与指令块构成;

  • 每条指令以;分号结尾,指令与参数间以空格符号分隔;

  • 指令块以{}大括号将多条指令组织在一起;

  • include语法允许组合多个配置文件以提升可维护性;

  • 使用#符号添加注释,提高可读性;

  • 使用$符号使用变量;

  • 部分指令的参数支持正则表达式;

  • 配置参数: 时间单位

    • ms: milliseconds
    • s: seconds
    • m: minutes
    • h: hours
    • d: days
    • w: weeks
    • M: months,30days
    • y: years,365days
  • 配置参数: 空间单位

    • bytes
    • k/K: kilobytes
    • m/M: megabytes
    • g/G: gigabytes

Nginx命令行

  • 格式: nginx -s reload
    • 帮助: -? /-h
    • 使用指定的配置文件: -c
    • 指定配置指令: -g
    • 指定运行目录: -p
    • 发送信号: -s
    • 测试配置文件是否有语法: -t /-T
    • 打印nginx的版本信息,编译信息等: -v -V
  • 立即停止服务: nginx -s stop
  • 优雅的停止服务: nginx -s quit
  • 重载配置文件: nginx -s reload
  • 重新开始记录日志文件: nginx -s reopen

Nginx events常用配置

  • include

    1
    2
    include mime.types;
    include vhosts/*.conf;

Nginx http常用配置

Nginx server常用配置

Nginx location常用配置

  • 语法格式:location [=|~|~*|^~] /url/ {...}

    • =: 表示精确匹配,这个优先级最高;
    • ^~:表示uri以某个常规字符串开头,理解为匹配url路径即可。Nginx不对url做编码。因此请求为/static/20%/aa可以被规则^~/static/ /aa匹配到;
    • ~表示区分大小写的正则匹配;
    • ~*表示不区分大小写的正则匹配;
    • !~表示区分大小写不匹配的正则;
    • !~*表示不区分大小写不匹配的正则;
    • /通用匹配,任何请求都会匹配到,默认匹配;
  • 匹配优先级

    • 第一优先级: 等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。
    • 第二优先级: ^~类型表达式。一旦匹配成功,则不再查找其他匹配项。
    • 第三优先级: 正则表达式类型(~ ~*)的优先级次之。如果有多个location的正则能匹配的话,则使用正则表达式最长的那个。
    • 第四优先级: 常规字符串匹配类型。按前缀匹配。
    1
    (location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)
  • URL写法区别

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 首先将test作为目录来处理,查找时先根据{...}配置的路径找是否有test文件夹,
    # 若有文件夹也会去查找test是否有index.html文件
    # 若没有文件夹,则会找test文件,若有文件则将文件中的内容返回
    location /test {
    ...
    }
    # 首先将test作为目录来处理,查找时先根据{...}配置的路径找是否有test文件夹,
    # 若有文件夹也会去查找test是否有index.html文件
    # 若没有文件夹,则会找test文件也不会将文件内容返回,则是返回404
    location /test/{
    ...
    }

root和alias配置

  • root

    1
    2
    3
    4
    5
    6
    7
    8
    语法: root path 默认值: root html
    配置段: http、server、location、if

    示例
    location /root{
    root /data/www;
    }
    访问: base_url/root/data/www
  • alias

    1
    2
    3
    4
    5
    6
    7
    8
    语法: alias path 
    配置段: location

    location /alias {
    alias /data/www/;
    }

    访问: base_url/alias
    • 使用alias时,目录名后面一定要加上**“/”**;
    • alias可以指定任何名称。
    • alias在使用正则匹配时,必须捕捉匹配的内容并指定的内容处使用;
    • alias只能位于location块中;

stub_status模块配置

ngx_http_limit_conn_module

  • 语法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    # 设置共享内存
    Syntax: limit_conn_zone key zone=name:size;
    Default: —
    Context: http

    # 设置限速行为发生时的日志等级
    Syntax: limit_conn_log_level info | notice | warn | error;
    Default:
    limit_conn_log_level error;
    Context: http, server, location
    This directive appeared in version 0.8.18.

    # 限速行为发生时返回给客户端时的状态码
    Syntax: limit_conn_status code;
    Default:
    limit_conn_status 503;
    Context: http, server, location
    This directive appeared in version 1.3.15.

    # 真正设置限速值
    Syntax: limit_conn zone number;
    Default: —
    Context: http, server, location
  • 样例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    server {
    location /download/ {
    limit_conn_log_level warn;
    limit_conn_status 503;
    limit_conn addr 1;
    }
    }

ngx_http_limit_req_module

  • 语法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    Syntax: limit_req_zone key zone=name:size rate=rate [sync];
    Default: —
    Context: http

    Syntax: limit_req_log_level info | notice | warn | error;
    Default:
    limit_req_log_level error;
    Context: http, server, location
    This directive appeared in version 0.8.18.

    Syntax: limit_req_status code;
    Default:
    limit_req_status 503;
    Context: http, server, location
    This directive appeared in version 1.3.15.

    Syntax: limit_req zone=name [burst=number] [nodelay | delay=number];
    Default: —
    Context: http, server, location

限制特定IP或网段访问的access模块

  • 语法

    1
    2
    3
    4
    5
    6
    7
    Syntax:	allow address | CIDR | unix: | all;
    Default: —
    Context: http, server, location, limit_except

    Syntax: deny address | CIDR | unix: | all;
    Default: —
    Context: http, server, location, limit_except
  • 样例

    1
    2
    3
    4
    5
    6
    7
    8
    # 通常allow和deny配合使用
    location / {
    deny 192.168.1.1;
    allow 192.168.1.0/24;
    allow 10.1.1.0/16;
    allow 2001:0db8::/32;
    deny all;
    }

ngx_http_auth_basic_module

  • 语法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Syntax:	auth_basic string | off;
    Default:
    auth_basic off;
    Context: http, server, location, limit_except

    # 该配置文件内容,可以由可由httpd-tools工具包里面的htpasswd生成
    # 生成新的密码文件: htpasswd -bc `filename` `username` `password`
    # 添加新用户密码: htpasswd -b `filename` `username` `password`
    Syntax: auth_basic_user_file file;
    Default: —
    Context: http, server, location, limit_except

Nginx ngx_http_core_module变量说明

参数名称 说明
$arg_PARAMETER HTTP 请求中某个参数的值,如/index.php?site=www.ttlsa.com,可以用$arg_site取 得 www.ttlsa.com 这个值.
$args HTTP 请求中的完整参数。例如,在请求/index.php?width=400&height=200 中,$args表示 字符串 width=400&height=200.
$binary_remote_addr 二进制格式的客户端地址。例如: \x0A\xE0B\x0E
$body_bytes_sent 表示在向客户端发送的http响应中,包体部分的字节数
$content_length 表示客户端请求头部中的 Content-Length 字段
$content_type 表示客户端请求头部中的 Content-Type 字段
$cookie_COOKIE 表示在客户端请求头部中的 cookie 字段
$document_root 表示当前请求所使用的root 配置项的值
$uri 表示当前请求的 URI,不带任何参数
$document_uri 与$uri 含义相同
$request_uri 表示客户端发来的原始请求 URI,带完整的参数。uriuri和document_uri 未必是用户的 原始请求,在内部重定向后可能是重定向后的 URI,而$request_uri 永远不会改变,始终是客户端的原始 URI.
$host 表示客户端请求头部中的 Host字段。如果Host字段不存在,则以实际处理的 server(虚拟主机)名称代替。如果 Host 字段中带有端口,如 IP:PORT,那么host是去掉端口的,它的值为IPhost是去掉端口的,它的值为 IP。host 是全小写的。这些特性与http_HEADER 中的 http_host不同,http_host只取出Host头部对应的值.
$hostname 表示 Nginx 所在机器的名称,与 gethostbyname调用返回的值相同
$http_HEADER 表示当前 HTTP请求中相应头部的值。HEADER名称全小写。例如,示请求中 Host头部 对应的值 用 $http_host表
$sent_http_HEADER 表示返回客户端的 HTTP响应中相应头部的值。HEADER名称全小写。例如,用 $sent_ http_content_type表示响应中 Content-Type头部对应的值
$is_args 表示请求中的 URI是否带参数,如果带参数,$is_args值为 ?,如果不带参数,则是空字符串
$limit_rate 表示当前连接的限速是多少,0表示无限速
$nginx_version 表示当前 Nginx的版本号
$query_string 请求 URI中的参数,与 $args相同,然而 $query_string是只读的不会改变
$remote_addr 表示客户端的地址
$remote_port 表示客户端连接使用的端口
$remote_user 表示使用 Auth Basic Module时定义的用户名
$request_filename 表示用户请求中的 URI经过 root或 alias转换后的文件路径
$request_body 表示 HTTP 请求中的包体,该参数只在 proxy_pass或 fastcgi_pass中有意义
$request_body_file 表示 HTTP 请求中的包体存储的临时文件名
$request_completion 当请求已经全部完成时,其值为 “ok”。若没有完成,就要返回客户端,则其值为空字符串;或者在断点续传等情况下使用 HTTP range访问的并不是文件的最后一块,那么其值也是空字符串。
$request_method 表示 HTTP 请求的方法名,如 GET、PUT、POST等
$scheme 表示 HTTP scheme(协议),如在请求 https://nginx.com/中表示 https
$server_addr 表示服务器地址
$server_name 表示服务器名称
$server_port 表示服务器端口
$server_protocol 表示服务器向客户端发送响应的协议,如 HTTP/1.1或 HTTP/1.0

Nginx 日志配置

  • access_log指令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    access_log    <FILE>    <NAME>;
    关键字 日志文件 格式标签
    关键字: 其中关键字error_log不能改变
    日志文件: 可以指定任意存放日志的目录
    格式标签: 给日志文件套用指定的日志格式
    其他语法:
    access_log off; #关闭access_log,即不记录访问日志
    access_log path [format [buffer=size [flush=time]] [if=condition]];
    access_log path format gzip[=level] [buffer=size] [flush=time] [if=condition];
    access_log syslog:server=address[,parameter=value] [format [if=condition]];

    说明:
    buffer=size #为存放访问日志的缓冲区大小
    flush=time #为缓冲区的日志刷到磁盘的时间
    gzip[=level] #表示压缩级别
    [if = condition] #表示其他条件

    配置段: http, server, location, if in location, limit_except

隐藏Nginx版本号的安全性与方法

  • 编辑nginx.conf在http{…}中添加server_tokens off;

  • 编辑fastcgi.conffcgi.conf

    1
    2
    3
    4
    找到: 
    fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
    改为:
    fastcgi_param SERVER_SOFTWARE nginx;

热部署升级

  • 复制一份最新的nginx(/sbin/nginx);

    1
    cp nginx nginx.old
  • kill -USR2 原PID 平滑的启动新的进程(masterworker);

  • kill -WINCH 原PID 优雅的关闭老的worker进程;

  • 最终老的master进程会被保留,以备回滚版本时使用;

日志切割

  • 复制一份原有的日志文件 mv xxx.log back.log
  • ../sbin/nginx -s reopen
  • 使用编写脚本,通过定时任务来进行日志切割

配置静态服务器

  • gzip

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    gzip配置的常用参数

    gzip on|off; #是否开启gzip

    gzip_buffers 32 4K| 16 8K #缓冲(压缩在内存中缓冲几块? 每块多大?)

    gzip_comp_level [1-9] #推荐6 压缩级别(级别越高,压的越小,越浪费CPU计算资源)

    gzip_disable #正则匹配UA 什么样的Uri不进行gzip

    gzip_min_length 200 # 开始压缩的最小长度(再小就不要压缩了,意义不在)

    gzip_http_version 1.0|1.1 # 开始压缩的http协议版本(可以不设置,目前几乎全是1.1协议)

    gzip_proxied # 设置请求者代理服务器,该如何缓存内容

    gzip_types text/plain application/xml # 对哪些类型的文件用压缩 如txt,xml,html ,css

    gzip_vary on|off # 是否传输gzip压缩标志
  • access_log

    1
    2
    3
    4
    5
    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;
  • 配置上游服务

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    upstream local {
    server 127.0.0.1:8080;
    }
    server {
    server_name downstream_server;
    listen 80;

    location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forward_for;
    proxy_pass http://local;
    }
    }

日志查看

  • goaccess安装

    1
    2
    3
    4
    5
    6
    $ wget http://tar.goaccess.io/goaccess-1.2.tar.gz
    $ tar -xzvf goaccess-1.2.tar.gz
    $ cd goaccess-1.2/
    $ ./configure --enable-utf8 --enable-geoip=legacy
    $ make
    # make install
  • 出错一

    1
    2
    configure: error: 
    *** Missing development files for the GeoIP library
    • 解决方法: 安装GeoIP

      1
      2
      3
      4
      5
      6
      $ wget https://github.com/maxmind/geoip-api-c/releases/download/v1.6.11/GeoIP-1.6.11.tar.gz
      $ tar -xzvf GeoIP-1.6.11.tar.gz
      $ cd GeoIP-1.6.11
      $ ./configure
      $ make
      # make install
  • 出错二

    1
    ./bin2c: error while loading shared libraries: libGeoIP.so.1: cannot open shared object file: No such file or directory
    • 解决方法: ln -s /usr/local/lib/libGeoIP.so* /lib64/
  • 出错三

    1
    2
    3
    [root@holelin logs]# goaccess access.log  -o ../html/report.html --real-time-html --time-format='%H:%M:%S' --date-format='%d/%b/%Y' --log-format=COMBINED
    Error Opening file /usr/local/share/GeoIP/GeoIP.dat
    WebSocket server ready to accept new client connections

SSL协议

  • SSL(Secure Sockets Layer)

  • TLS(Transport Layer Security)

  • SSL3.0–>TLS1.0–>TLS1.1–>TLS1.2–>TLS1.3

  • ISO/OSI模型:表示层

  • TCP/IP模型:应用层

    • 握手
    • 交换密钥
    • 告警
    • 对称加密的应用数据
TLS安全密码套件
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    • ECDHE: 密钥交换
    • RSA: 身份验证
    • AES: 算法
    • 128: 强度
    • GCM: 模式
    • SHA256 : MACPRF
  • 密钥交换算法
  • 身份验证算法
  • 对称加密算法、强度、分组模式
  • 签名hash算法
证书类型
  • 域名验证(domain validated ,DV)证书
  • 组织验证(organization validated,OV)证书
  • 扩展验证(extended validation,EV)证书
给站点附加SSL证书实现HTTPS
  • yum install python2-cerbot-nginx

  • 修改nginx.conf文件的server_name域名

  • certbot --nginx --nginx-server-root=/usr/local/tengine/conf/ -d 域名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [root@holelin ~]# certbot --nginx --nginx-server-root=/usr/local/tengine/conf/ -d chenjunlin.vip
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    The nginx plugin is not working; there may be problems with your existing configuration.
    The error was: PluginError('Nginx build is missing SSL module (--with-http_ssl_module).',)
    [root@holelin ~]# nginx -V
    Tengine version: Tengine/2.3.2
    nginx version: nginx/1.17.3
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
    built with OpenSSL 1.0.2k-fips 26 Jan 2017
    TLS SNI support enabled
    configure arguments: --prefix=/usr/local/tengine
    • 缺少--with-http_ssl_module
      • 参考文献: https://www.cnblogs.com/NGames/p/12078503.html
      • 重新编译nginx服务器
      • ./configure --prefix=/usr/local/tengine/ --with-http_ssl_module
      • make
      • make install 此处因为我之前只是简单安装尚未指定任何模块,故而直接重新安装

Nginx进程结构

  • 一个Master进程
  • 多个Worker进程
  • 一个Cache Manager进程
  • 一个Cache Loader进程

Nginx信号量

  • Master进程
    • 监控Worker进程
      • CHLD
    • 管理Worker进程
    • 接受信号
      • TERM,INT
      • QUIT
      • HUP
      • USR1
      • USR2
      • WINCH
  • Worker进程
    • 接受信号
      • TERM,INT
      • QUIT
      • USR1
      • WINCH
  • Nginx命令行
    • nginx -s reload: kill -s SIGHUP <master pid>
    • nginx -s reopen: kill -s SIGUSR1 <master pid>
    • nginx -s stop: kill -s SIGTERM <master pid>
    • nginx -s quit: kill -s SIGQUIT <master pid>

Nginx reload 流程

  • master进程发送HUP(reload命令)
  • master进程校验配置语法是否正确
  • master进程打开新的监听端口
  • master进程用新的配置启动新的worker子进程
  • master进程向老worker子进程发送QUIT信号
  • worker进程关闭监听句柄,处理完当前连接后结束进程

Nginx热升级流程

  • 将旧Nginx文件换成新Nginx文件(注意备份)
  • master进程发送USR2信号
  • master进程修改pid文件名,加上.oldbin
  • master进程用新Nginx文件启动新master进程
  • 向老master进程发送QUIT信号,关闭老master进程
  • 回滚: 向老master发送HUP,向新master发送QUIT

Worker进程: 优雅的关闭适合HTTP请求

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

Nginx日志级别

  • 从上至下级别依次增大,当设定为一个级别时,大于或等于该级别的日志都会被输出到日志文件中,小于该级别的日志则不会输出。
    • debug
    • Info
    • notice
    • warn
    • error
    • crit
    • alert
    • emerg
  • 如果日志级别设定到debug,必须在configure时加入--with-debug配置项

分析Nginx日志常见场景

总访问量频繁的IP

1
2
3
4
cat access.log|awk '{print $1}'|sort |uniq -c |sort -n -k 1 -r|more

cut -d' ' -f 1 access.log | sort | uniq -c | sort -nr
cat access.log | grep '2021-03-23' | awk '{print $1}' | sort | uniq -c | sort -nr -k1 | head -n 10

查看某个 IP 访问量频繁 URL

1
cat access.log|grep 'xxx.xxx.xxx.xxx'|awk '{print $7}'|sort |uniq -c |sort -n -k 1 -r|more

查看爬虫、机器人访问

1
cat access.log|grep -iv "MSIE|Firefox|Chrome|Opera|Safari|Gecko|Mozilla|wordpress"

状态码统计

1
cat access.log|awk '{print $9}'|sort|uniq -c|more