3.Nginx高级配置

本文最后更新于:2023年12月5日 晚上

状态页

状态页用于输出 nginx 的基本状态信息

基于 ngx_http_stub_status_module 模块实现,编译安装时需要添加 –with-http_stub_status_module 编译参数

注意:状态页显示的是整个服务器的状态,而非单独某个虚拟机的状态

输出信息示例:

Active connections: 2
server accepts handled requests
 35836 35836 27001
Reading: 0 Writing: 1 Waiting: 1
  • Active connections:当前处于活动状态的客户端连接数,reading + writing + waiting
    • Reading:正在读取客户端请求报文首部的连接的连接数,数值越大,说明排队现象严重,性能不足
    • Writing:正在向客户端发送响应报文过程中的连接数,数值越大,说明访问量很大
    • Waiting:正在等待客户端发出请求的空闲连接数,如果开启 keep-alive,这个值等于 active – (reading+writing)
  • server accepts handled requests:三个值分别对应 accepts、handled、requests
    • accepts:Nginx 自启动后已经接受的客户端请求的总数
    • handled:Nginx 自启动后已经处理完成的客户端请求总数,通常等于 accepts,除非有因
      worker_connections 限制等被拒绝的连接
    • requests:Nginx 自启动后客户端发来的总的请求数

第三方模块

第三模块是对 nginx 的功能扩展,第三方模块需要在编译安装 Nginx 的时候使用参数–add-module=PATH 指定路径添加,nginx 支持第三方模块需要从源码重新编译支持

范例:支持开源的 echo 模块 https://github.com/openresty/echo-nginx-module

[root@centos8 src]$ git clone https://github.com/openresty/echo-nginx-module.git
[root@centos8 src]$ ./configure \
--prefix=/user/local/nginx \
...
--add-module=/usr/local/src/echo-nginx-module # 指定模块源代码路径
[root@centos8 src]# make && make install
[root@centos8 ~]# /apps/nginx/sbin/nginx -t
[root@centos8 ~]# systemctl restart nginx
[root@centos8 ~]#nginx -V

变量使用

nginx 的变量可以在配置文件中引用,作为功能判断或者日志等场景使用

变量可以分为内置变量和自定义变量

内置变量是由 nginx 模块自带,通过变量可以获取到众多的与客户端访问相关的值

内置变量

http://nginx.org/en/docs/varindex.html

http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_core_module.html#variables

常用内置变量:

  • $remote_addr:客户端的公网 IP

  • $proxy_add_x_forwarded_for

    X-Forwarded-For:简称 XFF,只有在通过 http 代理或者负载均衡服务器时才会添加该项

    如果请求头中有 XFF,$proxy_add_x_forwarded_for 就是XXF头的值追加$remote_addr,所以,如果请求头中没有 XFF,$proxy_add_x_forwarded_for 就等于 $remote_addr

    # client1是真实的客户端ip,后面的是经过的代理或者负载均衡的ip,经过几个就会出现几个
    X-Forwarded-For: client, proxy1, proxy2
    # 范例:
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 实现ip透传
        proxy_pass http://36.10.10.118:9015;
    }
  • $args:url 中的 get 参数

    例如 http://ljk.cn/main/index.do?id=1&partner=search,$args就是id=1&partner=search

  • $document_root:当前请求的root指令或alias指令的配置

  • $document_uri:和$uri 相同,当前请求中不包含参数的 URI

    例如 http://ljk.cn/main/index.do?id=1&partner=search,$document_uri就是/main/index.do

  • $host:请求的 host 名称

  • $limit_rate:limit_rate 项配置的网络速率,默认为 0

  • $remote_port:客户端请求 Nginx 服务器时随机打开的端口,这是每个客户端自己的端口

  • $remote_user:已经经过 Auth Basic Module 验证的用户名

  • $request_body_file:做反向代理时发给后端服务器的本地资源的名称

  • $request_method:请求资源的方式,GET/PUT/DELETE 等

  • $request_filename:当前请求的资源文件的磁盘路径,由 root 或 alias 指令与 URI 请求生成的文件绝对路径,如:/apps/nginx/html/main/index.html

  • $request_uri:包含请求参数的原始 URI,不包含主机名,相当于:$document_uri?$args,例如如:/main/index.do?id=20190221&partner=search

  • $scheme:请求的协议,例如:http、https、ftp 等

  • $server_protocol:保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0 等

  • $server_addr:保存了服务器的 IP 地址

  • $server_name:请求的服务器的主机名

  • $server_port:请求的服务器的端口号

  • $http_<name>:name 为任意请求报文首部字段,表示记录请求报文的首部字段,用下划线代替横线

    示例:echo $http_User_Agent

  • $http_user_agent:客户端浏览器的详细信息

  • $http_cookie:客户端的 cookie 信息

  • $cookie_<name>:name 为任意请求报文首部字部 cookie 的 key 名

范例:

location /main {
    default_type text/html;
    echo "hello world,main-->";
    echo $remote_addr ;
    echo $args ;
    echo $document_root;
    echo $document_uri;
    echo $host;
    echo $http_user_agent;
    echo $http_cookie;
    echo $request_filename;
    echo $scheme;
    echo $scheme://$host$document_uri?$args;
}

自定义变量

语法: set variable value;
默认值: —
上下文: server, location, if

范例:

set $name magedu;
set $my_port $server_port;

自定义访问日志

错误日志(error_log)一般只有一个,但是访问日志可以在不同的 server 中定义多个,access_log 指定日志的保存路径,log_format 指定日志的格式,格式中定义要保存的具体日志内容

访问日志由 ngx_http_log_module 模块实现

自定义访问日志的格式:

语法: log_format name [escape=default|json|none] string …;
默认值: log_format combined “…”;
上下文: http

支持三种转义方式:

  1. default:,\ 以及小于 32 或大于 126 的字符被转义为\xXX
  2. json:所有 json 中不被允许的字符都进行转义,被转义成 \\被转义成\\,值小于 32 的字符转义成\n\r\tbf\u00XX
  3. none:禁止转义

combined 是内置的默认格式,以空格分割字符串形式记录日志

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

自定义访问日志的路径以及其他配置:

语法: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
默认值: access_log logs/access.log combined;
上下文: http, server, location, if in location, limit_except

format:默认 combined
buffer=size:缓冲区大小,默认 64K
gzip=level:压缩等级,1-9,数值越大,压缩率最高,压缩最慢,默认为 1,可以使用zcat解压缩
flush=time:缓冲区的数据写入磁盘的间隔时间,必须搭配 buffer=size 一起使用,时间到了,即使缓冲区还没满,也得写入磁盘
if=condition:其他条件

范例:

access_log /path/to/log.gz combined gzip flush=5m;
map $status $loggable {
    ~^[23]  0;
    default 1;
}
access_log /path/to/access.log combined if=$loggable;

自定义 json 格式日志

Nginx 的默认访问日志记录内容相对比较单一,默认的格式也不方便后期做日志统计分析,生产环境中通常将 nginx 日志转换为 json 日志,然后配合使用 ELK 做日志收集-统计-分析

log_format access_json '{"@timestamp":"$time_iso8601",'
                        '"host":"$server_addr",'
                        '"clientip":"$remote_addr",'
                        '"size":$body_bytes_sent,'
                        '"responsetime":$request_time,' # 总的处理时间
                        '"upstreamtime":"$upstream_response_time",'
                        '"upstreamhost":"$upstream_addr",' # 后端应用服务器处理时间
                        '"http_host":"$host",'
                        '"uri":"$uri",'
                        '"xff":"$http_x_forwarded_for",'
                        '"referer":"$http_referer",'
                        '"tcp_xff":"$proxy_protocol_addr",'
                        '"http_user_agent":"$http_user_agent",'
                        '"status":"$status"}';
access_log /apps/nginx/logs/access_json.log access_json;

json 格式的日志访问统计

#!/usr/bin/env python3
#coding:utf-8
status_200= []
status_404= []
with open("access_json.log") as f:
    for line in f.readlines():
        line = eval(line)
        if line.get("status") == "200":
            status_200.append(line.get)
        elif line.get("status") == "404":
            status_404.append(line.get)
        else:
            print("状态码 ERROR")
        print((line.get("clientip")))
f.close()

print("状态码200的有--:",len(status_200))
print("状态码404的有--:",len(status_404))

Nginx 压缩功能

Nginx 支持对指定类型的文件进行压缩然后再传输给客户端,有助于降低出口带宽的利用率,降低企业的 IT 支出,不过会占用相应的 CPU 资源

依赖于模块 ngx_http_gzip_module

#启用或禁用gzip压缩,默认关闭
gzip on | off;
#压缩比由低到高从1到9,默认为1
gzip_comp_level level;
#禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
#gzip压缩的最小文件,小于设置值的文件将不会压缩,默认单位为字节 1K=1024
gzip_min_length 1k;
#启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
#指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
#如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”,一般建议打开
gzip_vary on | off;

# Nginx作为反向代理的时候启用,开启或者关闭后端服务器返回的结果,匹配的前提是后端服务器必须要返回包含”Via”的 header头。
gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;
# off – 关闭所有的代理结果数据的压缩
# expired – 启用压缩,如果header头中包含 “Expires” 头信息
# no-cache – 启用压缩,如果header头中包含 “Cache-Control:no-cache” 头信息
# no-store – 启用压缩,如果header头中包含 “Cache-Control:no-store” 头信息
# private – 启用压缩,如果header头中包含 “Cache-Control:private” 头信息
# no_last_modified – 启用压缩,如果header头中不包含 “Last-Modified” 头信息
# no_etag – 启用压缩 ,如果header头中不包含 “ETag” 头信息
# auth – 启用压缩 , 如果header头中包含 “Authorization” 头信息
# any – 无条件启用压缩

范例:

gzip on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
  text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
  text/javascript application/javascript application/x-javascript
  text/x-json application/json application/x-web-app-manifest+json
  text/css text/plain text/x-component
  font/opentype application/x-font-ttf application/vnd.ms-fontobject
  image/x-icon;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";

https

https = http + ssl / tls

https 的实现过程可以参考前面的关于“安全和加密”部分的笔记

基于模块 ngx_http_ssl_module 实现,yum 安装默认开启,编译安装则需要指定编译参数 –with-http_ssl_module

ssl on | off; # 开启ssl功能,这个参数1.15版本已经废除了,应该使用 listen ssl 替代
listen 443 ssl; # 替代ssl指令,同时指定端口
ssl_certificate /path/to/file; # 证书文件,一般是crt或者pem文件
ssl_certificate_key /path/to/file; # 私钥文件,一般是key文件
# 支持ssl协议版本,早期为ssl现在是TLS,默认为后三个
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
ssl_session_timeout time; # 客户端连接可以复用ssl session cache中缓存的有效时长,默认5m
# 配置ssl缓存
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
 # off:关闭缓存
 # none:通知客户端支持ssl session cache,但实际不支持
 # builtin[:size]:使用OpenSSL内建缓存,为每worker进程私有
 # [shared:name:size]:在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称

范例:实现 hsts https://www.cnblogs.com/sunsky303/p/8862600.html

server {
    listen 80;
    listen 443 ssl http2;
    ssl_certificate /usr/local/nginx/conf/ssl/xcx.to2b.cn.pem;
    ssl_certificate_key /usr/local/nginx/conf/ssl/xcx.to2b.cn.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_timeout 10m;
    ssl_session_cache builtin:1000 shared:SSL:10m;
    ssl_buffer_size 1400;
    # Strict-Transport-Security, 即hsts,强制https的意思
    # 一年内,浏览器自动将http请求转成https
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    ssl_stapling on;
    ssl_stapling_verify on;
    server_name xcx.to2b.cn;
    access_log /data/wwwlogs/xcx.to2b.cn_nginx.log combined;
    index index.html index.htm index.php;
    root /data/wwwroot/xcx.to2b.cn/public;
    # 第一次http请求,需要重定向到https
    if ( $scheme = http ) {rewrite ^/(.*)$ https://www.magedu.org/$1 redirect;}
    ...
    ...
}

关于 favicon.ico

favicon.ico 文件是浏览器收藏网址时显示的图标,当客户端使用浏览器问页面时,浏览器会自己主动发起请求获取页面的 favicon.ico 文件,但是当浏览器请求的 favicon.ico 文件不存在时,服务器会记录 404 日志,而且浏览器也会显示 404 报错

location = /favicon.ico {
 log_not_found off;
 access_log off;
    root /data/nginx/html/pc/images;
 expires 365d; #设置文件过期时间
}

3.Nginx高级配置
http://blog.lujinkai.cn/运维/Nginx/3.Nginx高级配置/
作者
像方便面一样的男子
发布于
2020年12月25日
更新于
2023年12月5日
许可协议