Skip to content

nginx base

mo watermelon edited this page Jul 14, 2020 · 1 revision

nginx

官网

http://nginx.org/

中文文档

https://www.nginx.cn/doc/

官方下载地址

http://nginx.org/en/download.html

基础介绍

Nginx是俄罗斯人Igor Sysoev编写的轻量级Web服务器,它的发音为 [ˈendʒɪnks] ,它不仅是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器。

Nginx以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡服务器。在性能上,Nginx占用很少的系统资源,能支持更多的并发连接,达到更高的访问效率;在功能上,Nginx是优秀的代理服务器和负载均衡服务器;在安装配置上,Nginx安装简单、配置灵活。

Nginx支持热部署,启动速度特别快,还可以在不间断服务的情况下对软件版本或配置进行升级,即使运行数月也无需重新启动。

在微服务的体系之下,Nginx正在被越来越多的项目采用作为网关来使用,配合Lua做限流、熔断等控制。

对于Nginx的初学者可能不太容易理解web服务器究竟能做什么,特别是之前用过Apache服务器的,以为Nginx可以直接处理php、java,实际上并不能。

对于大多数使用者来说,Nginx只是一个静态文件服务器或者http请求转发器,它可以把静态文件的请求直接返回静态文件资源,把动态文件的请求转发给后台的处理程序,例如php-fpm、apache、tomcat、jetty等,这些后台服务,即使没有nginx的情况下也是可以直接访问的(有些时候这些服务器是放在防火墙的面,不是直接对外暴露,通过nginx做了转换)。


功能概述

  • HTTP基础功能:

    • 处理静态文件,索引文件以及自动索引;
      • 反向代理加速(无缓存),简单的负载均衡和容错;
      • FastCGI,简单的负载均衡和容错;
      • 模块化的结构。过滤器包括gzipping, byte ranges, chunked responses, 以及 - SSI-filter 。在SSI过滤器中,到同一个 proxy 或者 FastCGI 的多个子请求并发处理;
      • SSL 和 TLS SNI 支持;
  • IMAP/POP3 代理服务功能:

    • 使用外部 HTTP 认证服务器重定向用户到 IMAP/POP3 后端;
      • 使用外部 HTTP 认证服务器认证用户后连接重定向到内部的 SMTP 后端;
      • 认证方法:
      • POP3: POP3 USER/PASS, APOP, AUTH LOGIN PLAIN CRAM-MD5;
      • IMAP: IMAP LOGIN;
      • SMTP: AUTH LOGIN PLAIN CRAM-MD5;
      • SSL 支持;
      • 在 IMAP 和 POP3 模式下的 STARTTLS 和 STLS 支持;
  • 支持的操作系统:

    • FreeBSD 3.x, 4.x, 5.x, 6.x i386; FreeBSD 5.x, 6.x amd64;
      • Linux 2.2, 2.4, 2.6 i386; Linux 2.6 amd64;
      • Solaris 8 i386; Solaris 9 i386 and sun4u; Solaris 10 i386;
      • MacOS X (10.4) PPC;
  • 结构与扩展:

    • 一个主进程和多个工作进程。工作进程是单线程的,且不需要特殊授权即可运行;
      • kqueue (FreeBSD 4.1+), epoll (Linux 2.6+), rt signals (Linux 2.2.19+), /dev/poll (Solaris 7 11/99+), select, 以及 poll 支持;
      • kqueue支持的不同功能包括 EV_CLEAR, EV_DISABLE (临时禁止事件), NOTE_LOWAT, EV_EOF, 有效数据的数目,错误代码;
      • sendfile (FreeBSD 3.1+), sendfile (Linux 2.2+), sendfile64 (Linux 2.4.21+), 和 sendfilev (Solaris 8 7/01+) 支持;
      • 输入过滤 (FreeBSD 4.1+) 以及 TCP_DEFER_ACCEPT (Linux 2.4+) 支持;
      • 10,000 非活动的 HTTP keep-alive 连接仅需要 2.5M 内存。
      • 最小化的数据拷贝操作;
  • 其他HTTP功能:

    • 基于IP 和名称的虚拟主机服务;
      • Memcached 的 GET 接口;
      • 支持 keep-alive 和管道连接;
      • 灵活简单的配置;
      • 重新配置和在线升级而无须中断客户的工作进程;
      • 可定制的访问日志,日志写入缓存,以及快捷的日志回卷;
      • 4xx-5xx 错误代码重定向;
      • 基于 PCRE 的 rewrite 重写模块;
      • 基于客户端 IP 地址和 HTTP 基本认证的访问控制;
      • PUT, DELETE, 和 MKCOL 方法;
      • 支持 FLV (Flash 视频);
      • 带宽限制;

mac 安装

安装依赖包

$ brew install nginx
Updating Homebrew...
==> Downloading https://mirrors.ustc.edu.cn/homebrew-bottles/bottles/pcre-8.44.catalina.bottle.tar.gz
Already downloaded: /Users/eva/Library/Caches/Homebrew/downloads/8a66be89ef090bca54158fd5c428f9ed215132e0449358859b9372a50dc3a283--pcre-8.44.catalina.bottle.tar.gz
==> Downloading https://mirrors.ustc.edu.cn/homebrew-bottles/bottles/nginx-1.17.10.catalina.bottle.tar.gz
######################################################################## 100.0%
==> Installing dependencies for nginx: pcre
==> Installing nginx dependency: pcre
==> Pouring pcre-8.44.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/pcre/8.44: 204 files, 5.5MB
==> Installing nginx
==> Pouring nginx-1.17.10.catalina.bottle.tar.gz
==> Caveats
Docroot is: /usr/local/var/www

The default port has been set in /usr/local/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.

nginx will load all files in /usr/local/etc/nginx/servers/.

To have launchd start nginx now and restart at login:
  brew services start nginx
Or, if you don't want/need a background service you can just run:
  nginx
==> Summary
🍺  /usr/local/Cellar/nginx/1.17.10: 25 files, 2.1MB
==> `brew cleanup` has not been run in 30 days, running now...
Removing: /Users/eva/Library/Logs/Homebrew/wget... (64B)
Removing: /Users/eva/Library/Logs/Homebrew/libidn2... (64B)
Removing: /Users/eva/Library/Logs/Homebrew/pandoc... (64B)
Removing: /Users/eva/Library/Logs/Homebrew/redis... (64B)
Removing: /Users/eva/Library/Logs/Homebrew/libunistring... (64B)
Removing: /Users/eva/Library/Logs/Homebrew/gettext... (64B)
Removing: /Users/eva/Library/Logs/Homebrew/openssl@1.1... (64B)
Pruned 0 symbolic links and 3 directories from /usr/local
==> Caveats
==> nginx
Docroot is: /usr/local/var/www

The default port has been set in /usr/local/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.

nginx will load all files in /usr/local/etc/nginx/servers/.

To have launchd start nginx now and restart at login:
  brew services start nginx
Or, if you don't want/need a background service you can just run:
  nginx

测试安装

$ % nginx -v
nginx version: nginx/1.17.10

修改配置

编辑指令

% vim /usr/local/etc/nginx/nginx.conf

初始内容

#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;

    server {
        listen       8080;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            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;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
    include servers/*;
}

检查配置文件nginx.conf的正确性命令

#user  nobody;

注意设置访问权限( user root owner; ),不然等会访问网站会出现403错误

#user root owner;

修改服务器文件默认配置文件地址,如相关日志地址等

#user root owner;
worker_processes  1;

error_log  /Volumes/软件盘/frontEnd/nginx/logs/error.log;
error_log  /Volumes/软件盘/frontEnd/nginx/logs/error.log  notice;
error_log  /Volumes/软件盘/frontEnd/nginx/logs/error.log  info;

pid        /Volumes/软件盘/frontEnd/nginx/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  /Volumes/软件盘/frontEnd/nginx/logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip  on;

    server {
        listen      9050;
        server_name  localhost;

        #charset koi8-r;

        #access_log  /Volumes/软件盘/frontEnd/nginx/logs/host.access.log  main;

        location / {
            root   /Volumes/文件盘/documentBak/learn/learn-elk/;
            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;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
    include servers/*;
}

初始内容

~ % nginx -t
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful

指令速览

nginx -s reload            # 重新载入配置文件
nginx -s reopen            # 重启 Nginx
nginx -s stop              # 停止 Nginx

完整指令

~ % nginx -h
nginx version: nginx/1.17.10
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -T            : test configuration, dump it and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload
  -p prefix     : set prefix path (default: /usr/local/Cellar/nginx/1.17.10/)
  -c filename   : set configuration file (default: /usr/local/etc/nginx/nginx.conf)
  -g directives : set global directives out of configuration file

启动服务器

nginx -s reload -c /Volumes/软件盘/frontEnd/nginx/nginx.conf

nginx access日志配置

access_log日志配置

access_log用来定义日志级别,日志位置。语法如下:

日志级别: debug > info > notice > warn > error > crit > alert > emerg

语法格式:

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

实例一:

access_log /spool/logs/nginx-access.log compression buffer=32k;

log_format 定义日志格式

语法格式:

log_format name [escape=default|json] string ...;

默认值 : log_format combined "..."; 作用域 : http

实例一:

log_format compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';
access_log /spool/logs/nginx-access.log compression buffer=32k;

常见的日志变量

• $remote_addr, $http_x_forwarded_for 记录客户端IP地址 • $remote_user记录客户端用户名称 • $request记录请求的URL和HTTP协议(GET,POST,DEL,等) • $status记录请求状态 • $body_bytes_sent发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。 • $bytes_sent发送给客户端的总字节数。 • $connection连接的序列号。 • $connection_requests 当前通过一个连接获得的请求数量。 • $msec 日志写入时间。单位为秒,精度是毫秒。 • $pipe如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”。 • $http_referer 记录从哪个页面链接访问过来的 • $http_user_agent记录客户端浏览器相关信息 • $request_length请求的长度(包括请求行,请求头和请求正文)。 • $request_time 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。 • $time_iso8601 ISO8601标准格式下的本地时间。 • $time_local通用日志格式下的本地时间。


open_log_file_cache

使用open_log_file_cache来设置日志文件缓存(默认是off)。

• max:设置缓存中的最大文件描述符数量,如果缓存被占满,采用LRU算法将描述符关闭。 • inactive:设置存活时间,默认是10s • min_uses:设置在inactive时间段内,日志文件最少使用多少次后,该日志文件描述符记入缓存中,默认是1次 • valid:设置检查频率,默认60s • off:禁用缓存

语法格式:

open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
                     open_log_file_cache off;

默认值: open_log_file_cache off; 作用域: http, server, location

实例一

open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;

nginx日志调试技巧

设置 Nginx 仅记录来自于你的 IP 的错误

当你设置日志级别成 debug,如果你在调试一个在线的高流量网站的话,你的错误日志可能会记录每个请求的很多消息,这样会变得毫无意义。 在events{...}中配置如下内容,可以使 Nginx 记录仅仅来自于你的 IP 的错误日志。

events {
        debug_connection 1.2.3.4;
}

调试 nginx rewrite 规则

调试rewrite规则时,如果规则写错只会看见一个404页面,可以在配置文件中开启nginx rewrite日志,进行调试。

server {
        error_log    /var/logs/nginx/example.com.error.log;
        rewrite_log on;
}

rewrite_log on;开启后,它将发送所有的 rewrite 相关的日志信息到 error_log 文件中,使用 [notice] 级别。随后就可以在error_log 查看rewrite信息了。

使用location记录指定URL的日志

server {
        error_log    /var/logs/nginx/example.com.error.log;
        location /static/ { 
        error_log /var/logs/nginx/static-error.log debug;
    }
}

配置以上配置后,/static/ 相关的日志会被单独记录在static-error.log文件中。

nginx日志共三个参数

  • access_log: 定义日志的路径及格式。
  • log_format: 定义日志的模板。
  • open_log_file_cache: 定义日志文件缓存。
  • proxy_set_header X-Forwarded-For :如果后端Web服务器上的程序需要获取用户IP,从该Header头获取。proxy_set_header X-Forwarded-For $remote_addr;

常用例子

main格式

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"'
                       '$upstream_addr $upstream_response_time $request_time ';
access_log  logs/access.log  main;

json格式

log_format logstash_json '{"@timestamp":"$time_iso8601",'
       '"host": "$server_addr",'
       '"client": "$remote_addr",'
       '"size": $body_bytes_sent,'
       '"responsetime": $request_time,'
       '"domain": "$host",'
       '"url":"$request_uri",'
       '"referer": "$http_referer",'
       '"agent": "$http_user_agent",'
       '"status":"$status",'
       '"x_forwarded_for":"$http_x_forwarded_for"}';

解释:

$uri请求中的当前URI(不带请求参数,参数位于$args),不同于浏览器传递的$request_uri的值,它可以通过内部重定向,或者使用index指令进行修改。不包括协议和主机名,例如/foo/bar.html。

$request_uri 这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI。

也就是说:$request_uri是原始请求URL,$uri则是经过nginx处理请求后剔除参数的URL,所以会将汉字表现为union。

坑点:

使用$uri 可以在nginx对URL进行更改或重写,但是用于日志输出可以使用$request_uri代替,如无特殊业务需求,完全可以替换。

压缩格式

日志中增加了压缩的信息。

http {
    log_format compression '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio"';
server {
        gzip on;
        access_log /spool/logs/nginx-access.log compression;
        ...
    }
}

upstream格式

增加upstream消耗的时间。

http {
    log_format upstream_time '$remote_addr - $remote_user [$time_local] '
                             '"$request" $status $body_bytes_sent '
                             '"$http_referer" "$http_user_agent"'
                             'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"';
server {
        access_log /spool/logs/nginx-access.log upstream_time;
        ...
    }
}

相关网站