# nginx 模块学习

# 一、通过源码构建 nginx

使用该 configure 命令配置构建。它定义了系统的各个方面,包括允许 nginx 用于连接处理的方法。最后它创建了一个 Makefile

configure 命令支持以下参数:

  • --help 打印帮助信息
  • --prefix=path 定义了一个存储 nginx 服务文件的目录。默认/usr/local/nginx
  • --sbin-path=path 指定了 nginx 可执行文件的名字,该名字通常在安装的时候被使用,默认名是:prefix/sbin/nginx
  • --modules-path=path 定义了 nginx 动态模块安装的目录,默认是 :prefix/modules
  • --conf-path=path 设置 nginx.conf 配置文件的名字,如果需要,nginx 可以指定不同的配置文件启动,默认是 prefix/conf/nginx.conf
  • --error-log-path=path 设置错误、警告的日志文件路径,安装之后可以在 nginx.conf 配置文件中 error_log 指令可以指定错误日志路径。默认的文件是:prefix/logs/nginx.pid
  • --pid-path=path 设置 nginx.pid 文件的路径,该文件将用来存储主进程的进程 id。默认prefix/logs/nginx.pid
  • --lock-path=path 设置 lock 文件的路径,安装完成之后也可以在 nginx.conf中直接通过 lock_file 改变 lock 文件指向的路径。默认 prefix/logs/nginx.pid
  • --user=name 设置未授权用户的名字,这些用户可以被 worker 进程所使用。安装之后,这个名字可以被 nginx.conf 配置文件中 user 所改变。
  • --group=name 设置组的名字,这些组的权限将会被 worker 进程所使用。安装之后,这个名字可以被 nginx.conf 配置文件中 user 所改变。默认情况下,组名被设置为未授权用户的名字。
  • --build=name 设置一个可选的 nginx build 名称。
  • --builddir=path 设置一个构建目录。
  • --with-select_module
  • --without-select_module 模块(使服务以 select() 方法启动)有效或无效。如果 nginx 运行没有出现合适的方法,诸如:kquene,epull,or /dev/poll。
  • --with-poll_module
  • --without-poll_module 模块(使服务以 poll() 方法启动)有效或无效。如果 nginx 运行没有出现合适的方法,诸如:kquene,epull。
  • --with-threads 使线程池的使用生效
  • --with-file-aio 基于 FreeBSD and Linux 的异步 IO 生效或失效。
  • --with-http_ssl_module 构建支持 https 的服务模块。这个模块不是默认的。运行该模块OpenSSL 库是必须的。
  • --with-http_image_filter_module
  • --with-http*image_filter_module=dynamic 允许构建以 jpeg、gif、png 和 webp 格式转换图像的 ngx*-http*-image*-filter_module 。默认情况下不生成此模块。
  • --with-http_geoip_module
  • --with-http_geoip_module=dynamic 可以构建ngx_http_geoip_module 根据客户端 ip 地址来创建创建变量,并且重新编译MaxMind ,这个模块默认是不被创建的。
  • --with-http_sub_module 可以构建ngx_http_sub_module 模块,该模块可以将响应中指定的字符串被另一个替换,该模块默认是不被创建的。
  • --with-http_dav_module 构建该模块提供通过WebDAV 协议实现文件自动管理,该模块默认是不被创建的。
  • --with-http_flv_module 构建该模块对服务端的 Flash Video (FLV)提供伪视频流技术,该模块默认是不会被构建的。
  • --with-http_mp4_module 构建该模块对服务端的 MP4 文件提供伪视频流技术,该模块默认不被构建。
  • --with-http_gunzip_module 构建该模块可以让解压响应头带有“Content-Encoding: gzip”的文件,而不需要客户端支持“gzip”编码方法。
  • --with-http_gzip_static_module 构建该模块能够发送“.gz”后缀的预压缩文件取代常规文件。该模块默认不被构建。
  • --with-http_auth_request_module 支持客户端依据之前请求结果授权,该模块默认不被构建。
  • --with-http_random_index_module enables building the ngx_http_random_index_module module that processes requests ending with the slash character (‘/’) and picks a random file in a directory to serve as an index file. This module is not built by default.
  • --with-http_secure_link_module
  • --with-http_degradation_module 构建ngx_http_degradation_module 模块,该模块默认未被构建。
  • --with-http_slice_module 将一个请求分为若干子请求,每个子请求返回确定范围的响应。该模块实现针对响应数据较大数据的缓存。该模块默认是不被构建的。
  • --with-http_stub_status_module 访问基础的状态信息,默认不被构建
  • --without-http_charset_module 使ngx_http_charset_module 失效,上述模块将指定字符集添加到“Content-Type”响应头当中,可以将响应的字符集转换成另一个字符集。
  • --with-stream
  • --with-stream=dynamic 构建该模块可以普通的 TCP/UDP 代理和负载均衡,该模块默认不被构建。
  • --with-stream_ssl_module 添加 SSL/TLS protocol support 协议支持,默认不被构建。
  • --with-stream_geoip_module
  • --with-stream_geoip_module=dynamic

demo:

./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module --with-pcre=../pcre-8.43 --with-zlib=../zlib-1.2.11 --with-openssl=../openssl-1.1.1b
1

编译实战: 1、下载 nginx 源码 nginx-release-1.16.0.tar.gz downloadUrl: wget http://nginx.org/download/nginx-1.16.0.tar.gz 2、下载 zlib 源码 zlib-1.2.11.tar.gz downloadUrl: http://www.zlib.net/ 3、下载 pcre 源码 pcre-8.43.tar.gz downloadUrl: https://ftp.pcre.org/pub/pcre/ 3、下载 opensll 源码 openssl-OpenSSL_1_1_1-stable.zip downloadUrl: https://github.com/openssl/openssl/tree/OpenSSL_1_1_1-stable 4、解压各文件,和 nginx 同级目录,执行下列命令:

./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module --with-pcre=../pcre-8.42 --with-zlib=../zlib-1.2.11 --with-openssl=../openssl-1.1.1b
make && make install
1
2

附 nginx 目录: . ├── client_body_temp [error opening dir] ├── fastcgi.conf ├── fastcgi.conf.default ├── fastcgi_params ├── fastcgi_params.default ├── fastcgi_temp [error opening dir] ├── html │ ├── 50x.html │ └── index.html ├── koi-utf ├── koi-win ├── logs │ ├── access.log │ └── error.log ├── mime.types ├── mime.types.default ├── nginx ├── nginx.conf ├── nginx.conf.default ├── nginx.pid ├── proxy_temp [error opening dir] ├── scgi_params ├── scgi_params.default ├── scgi_temp [error opening dir] ├── uwsgi_params ├── uwsgi_params.default ├── uwsgi_temp [error opening dir] └── win-utf

# 一、使用者手册

该手册对 nginx 作简要介绍,并描述了 nginx 可以做的任务,使用该手册的前提是读者已在 pc 安装了 nginx。如果没有,请查看安装 nginx 页面。这个手册描述了如何启动和关闭 nginx、如何重新加载配置、描述其配置文件的配置文件架构、描述设置静态服务器的配置、如何配置代理服务、如何用FastCGI application 来连接。 nginx 有一个 master 集成和多个 worker 进程。master 主要作用是读取和解析配置以及维持worker 进程。worker 进程是处理真实的请求进程。nginx 依赖事件驱动模型(event-based)和操作系统来高效地分发请求到worker 进程中。worker 进程地数量被定义在配置文件中,可以通过调整 cpu 核心的数量来修改(详见worker_processes)。 默认,配置文件名nginx.conf ,被放置在 /usr/local/nginx/conf, /etc/nginx, or /usr/local/etc/nginx

# 启动、关闭、重新加载配置

直接通过可执行文件启动 nginx。一旦启动,就可以通过可执行文件传参 -s 的方式来控制 nginx。使用语法如下:

nginx -s signal

signal,有如下参数:

  • stop - 快速关闭
  • quit - 优雅关闭
  • reload - 加载配置文件
  • reopen - 重新打开日志文件 例如,停止 nginx 进程,要等待worker 进程完成当前的请求,可以使用如下命令:

nginx -s quit 注意:该命令执行应该使用开启该 nginx 的用户。

配置文件的改变只能通过 nginx 重新加载配置或重启 nginx 生效。重新加载配置,执行如下:

nginx -s reload

一旦master 进程接收到了重新加载配置的信号,它会校验配置文件语法,并尝试去应用配置。如果配置成功,master 会创建新的worker 并通知旧的worker 进程去关闭。否则,master 进程会回滚当前的改变到历史配置,继续使用旧的配置。旧worker 进程接收到命令去关闭,会停止接收新的请求并将现有的请求处理完成后,才完成退出动作。

使用 Unix 的工具 kill 工具信号也可以发给 nginx 进程。这种情况,带有进程 id 的信号直接发送给一个进程。这个进程 id 是被 nginx master进程所重写,默认情况下 nginx.pid 在目录 /usr/local/nginx/logs 或者 /var/run。例如,如果 master 进程 id 是 1628,发送退出信号去优雅地关闭 nginx,可执行:

kill -s QUIT 1628

为了获取 nginx 进程 id 地列表,ps 工具被使用,例如:

ps -ax | grep nginx

更多信号发送到 nginx,详看Controlling nginx

# 配置文件结构

nginx 包含很多模块,而这些模块是在配置文件中被特定地指令所控制。指令包括简单指令和指令块。一个简单地指令包含被空格分隔的名字和参数,以分号(;)结尾。指令块有和简单指令一样的结构,除了没有分号结尾以及额外的指令被花括号所包括({ and })。如果指令块在指令中有其他指令,则称之为上下文(例如 events, http, server, 和 location)。 指令被放置到所有 context 是被当作在main 上下文中。eventshttp 指令是在main 上下文中,server 指令在http 上下文中,locationserver 上下文中。剩下的一行# 注释。

# 静态资源服务

web 服务器最重要的一个任务就是发布一个文件服务(像图片或者静态 html 文件)。你能够实现将本地文件映射到网络 url,可以直接通过请求访问文件。下面的示例是要实现/data/www (存放 html 静态资源) 和 /data/images (包含图片),这需要编辑配置文件,在 http 指令块下 server 指令块下 添加两个 location 指令块。。 首先创建 /data/www 目录,然后放一个 html 文件,然后再在/data/images 文件夹下放置些图片供测试。 接下来,打开配置文件,默认的配置已经包含了几个 server 块的示例,将注释打开创建一个新的server 指令块。

http {
    server {
    }
}
1
2
3
4

通常这个配置文件会包含多个server 块,而这些server 是通过它们监听的端口和服务名称来加以区分。一旦 nginx 确定哪一个server 处理请求,它会测试请求头中的参数和location 中配置的server 中定义是否匹配。 添加location块到server 块当中。

location / {
    root /data/www;
}
1
2
3

这个locaiton 块定义了“/”前缀和请求的 URI 做匹配。对于匹配的请求,这个 URI 将会被添加到root指令中重定向路径的后面,上述 demo 即是转向 /data/www ,以形成本地文件系统上所请求的路径。如果匹配多个 location 块,则 nginx 选择具有最长前缀的块。location 上面提供长度为 1 的最短前缀,因此只有当所有其他 location 块都无法提供匹配时,才会使用此块。

接下来添加第二个 location

location /images/ {
    root /data;
}
1
2
3

它将会匹配以/images/ 开头的请求路径(location/ 也能匹配上,但是匹配前缀更短)。

而最终的server 块的配置如下:

server {
    location / {
        root /data/www;
    }

    location /images/ {
        root /data;
    }
}
1
2
3
4
5
6
7
8
9

上述已经运行的配置监听 80 端口,可以铜鼓http://localhost/加以访问。为了响应 url 以/images/ 开头的请求,nginx 服务端将会发送/data/images 目录下的文件。例如为了响应http://localhost/images/example.png,nginx 会发送/data/images/example.png文件。如果这个文件不存在,就会返回 404 错误。以/images/ 开头的 URIs 路径将会映射到/data/www目录下。为了响应请求http://localhost/some/example.html, nginx 将会发送/data/www/some/example.html文件。为了使新的配置生效,需要发送reload信号到 nginx 的 master 进程。通过执行:

nginx -s reload
1

如果加载出现了问题,你可以在access.logerror.log中查找问题。文件路径/usr/local/nginx/logs/var/log/nginx

# 设置一个简单的代理服务

代理服务是 nginx 最常使用的一个功能,就是意味着 nginx 作为一个服务器接收请求,让他们去访问被代理的服务器,从被代理的服务器检索响应,并将他们转发到客户端。 我们将会配置一个基础的代理服务,请求的图片文件都来自于本地目录,其他请求发送到一个被代理的服务器。在这个例子中,两个服务都会被定义到一个简单的 nginx 实例中。 首先,通过添加一个或多个server块来定义被代理的服务。

server {
    listen 8080;
    root /data/up1;

    location / {
    }
}
1
2
3
4
5
6
7

上述配置监听 8080 端口,并且映射所有请求到/data/up1目录。创建这个目录,并把index.html文件放进去。注意root 指令需要放置到location块中。这个root生效要求location块被选择,并且location块中没有root指令。

接下来使用来自现在的配置,修改它作为一个代理服务器。在第一个 location 块,配置proxy_pass指令,参数配置协议、名称、端口以及被代理的服务。

server {
    location / {
        proxy_pass http://localhost:8080;
    }

    location /images/ {
        root /data;
    }
}
1
2
3
4
5
6
7
8
9

我们将修改第二个location块,它将会映射请求以/images/开头的请求到本地磁盘/data/images 目录下,为了使之匹配图片资源,可配置如下:

location ~ \.(gif|jpg|png)$ {
    root /data/images;
}
1
2
3

这个参数正则匹配所有以.gif.jpg或者 .png结尾的URIs。一个正则表达式应该以~开头,该请求将会被映射到目录/data/images下。 当 nginx 选择了一个location块来服务一个请求,首先它会校验location指令指定的前缀,记住location指令匹配最长路径,然后校验正则。如果匹配到了正则,nginx 将会挑选该location块,否则会选择之前记下来的模块。 最终的配置如下:

server {
    location / {
        proxy_pass http://localhost:8080/;
    }

    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }
}
1
2
3
4
5
6
7
8
9

启动 FastCGI 代理 nginx 也经常被使用路由请求到FastCGI服务器,FastCGI服务器可以运行多种框架和编程语言,比如PHP。 最基础简单的配置,使用fastcgi_pass取代proxy_pass,改变参数到 9000。在 php 中,SCRIPT_FILENAME被使用决定脚本名称,QUERY_STRING设置请求参数,结果配置如下:

server {
    location / {
        fastcgi_pass  localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param QUERY_STRING    $query_string;
    }

    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }
}
1
2
3
4
5
6
7
8
9
10
11