Nginx配置详解

自己一直没有信心手撸nginx配置,总结原因是不够了解其架构、设计思想,导致配置参数的时候存在试一试的心态,不能像写代码一样有预期的执行过程。

所以决定从了解其设计,到掌握常见配置,知道常见配置为什么,梳理一遍nginx配置使用。

Nginx设计理解

nginx的功能组织是模块化的,特定模块解决特定的问题,读文档了解这个设计的时候第一个感觉是模块有点“松散”,一下子梳理不出来一个思路。比如“如果我要实现这样一个功能,应该超什么方向,深入那个相关模块”?

所以按照一个常见配置,提出问题,到文档里面去寻找答案,来梳理思路。

worker_processes  1;

error_log logs/error.log debug;

events {
    worker_connections 1024;
}

daemon off;

http {

    server {
        listen 8080;
        server_name static.demo.com;

        location / {
             root /tmp/nginx/data/html ;
        }
    }

}

提出问题:

  • events、http、server、location这些block怎么解释,那些配置算block?
  • 每一个block里面可写什么?
  • 每个block和里面的配置会影响到nginx的那方面?
  • 假设从零开始写一个配置文件,得按照什么思路写起?

基于自己的网络编程经验,一边推测,一边读文档证实,整理如下:

  • 配置中不在block中的配置,影响的是nginx进程行为,如work_processes配置进程数量,daemon配置是否守护运行。
  • nginx基于事件实现网络请求处理,所以events配置是影响核心事件机制的配置。
  • 在事件机制基础上,模块化的实现网络协议,所以http是配置http协议模块行为的地方。
  • http中我们可以配置如何处理请求,其中的serverlocation是在其基础上由相关模块实现的常用功能。

总结思路,要setup一个nginx服务器,流程大概就这样子:

配置进程行为 -> 配置事件机制 -> 配置协议模块 -> 配置协议请求行为

其中目前nginx协议模块有http、mail、stream,分别对应作为http服务器、邮件服务器、四层服务器。

Nginx配置结构

在nginx中配置属性(关键字)称作指令,指令分两种:

  • 简单指令:名字加参数以;结尾,名字和参数之间用空格分隔。
  • 块指令: 在简单指令基础上,以{}结尾,其中{}定义了一个context,context里面可以写合法的简单指令或块指令。

所有的指令都可以认为在context中,没有被任何块指令包括的指令,可以认为在全局的main context中。

指令是可以被扩展的、通过编写扩展模块。常用的基础指令nginx本身也是通过模块实现的,所以配置一个目标功能,查阅对应模块文档,了解其指令参数便有头绪。

access模块为例

Syntax:	allow address | CIDR | unix: | all;
Default:	—
Context:	http, server, location, limit_except

Allows access for the specified network or address. If the special value unix: is specified (1.5.1), allows access for all UNIX-domain sockets.

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

Denies access for the specified network or address. If the special value unix: is specified (1.5.1), denies access for all UNIX-domain sockets.

文档中详细介绍了accessdeny两个指令的语法、合法参数、默认值、以及合法的作用context。

Nginx常用核心模块

ngx_http_core_module

http核心模块,是httpserverlocation等指令的来源。

ngx_http_rewrite_module

url重写模块,是ifrewrite指令的来源。

ngx_http_access_module

访问控制模块,是accessdeny指令的来源。

ngx_http_proxy_module

反向代理模块,非常重要的模块之一,作为反向代理服务器使用proxy_pass指令的来源。

ngx_http_log_module

日志模块,基本模块之一access_loglog_format指令的来源。

ngx_http_fastcgi_module

fastcgi协议模块,是常用nginx+php(fastcgi应用)架构应用的重要支持模块,fastcgi_pass指令的来源。

ngx_http_uwsgi_module

wsgi协议,是常用nginx+python(wsgi应用)架构应用的重要支持模块,wsgi_pass指令的来源。

ngx_http_upstream_module

作为负载均衡服务器的重要模块,upstream指令的来源。

ngx_stream_core_module

作为四层协议TCP、UDP代理服务的核心模块,stream指令的来源。

阅读全文

Nginx编译安装

编译安装

nginx编译还是非常简单的,首先保证机器具备编译环境安装好了gcc,make,automake等工具。CentOS可以用如下命令,一键安装。

yum group install "Development Tools"

然后安装相关依赖库,这点要夸夸nginx了,读文档提到nginx源码里面几乎已经包含了相关依赖代码,数据结构大部分自己实现不依赖系统C库,所以依赖非常少。但是还是依赖zlib、pcre、openssl开发库,文档里面说因为license原因不能放到源码包中,所要自己装。

 yum -y install pcre pcre-devel zlib zlib-devel openssl openssl-devel

然后是编译安装,configure阶段主要有三个参数:--prefix指定安装目录,这个目录之后也会是服务放置配置等文件的前缀目录、--with-<module-name>指定编译添加模块、--without-<module-name指定不编译模块。

nginx的模块是提前编译进去的,所以如果需要或者不需要某模块都要在编译阶段指定好,官方默认配置模块已经覆盖大部分场景了,显示的--with--without也很友好。

新版本nginx在逐渐支持动态链接库,所以以后添加模块也许不需要重新编译了。

# 进入源码目录
./configure --prefix=/tmp/nginx \
--with-http_ssl_module \
--with-http_v2_module

make && make install

tree -d /tmp/nginx

├── conf
│   ├── fastcgi.conf
│   ├── fastcgi.conf.default
│   ├── fastcgi_params
│   ├── fastcgi_params.default
│   ├── koi-utf
│   ├── koi-win
│   ├── mime.types
│   ├── mime.types.default
│   ├── nginx.conf
│   ├── nginx.conf.default
│   ├── scgi_params
│   ├── scgi_params.default
│   ├── uwsgi_params
│   ├── uwsgi_params.default
│   └── win-utf
├── html
│   ├── 50x.html
│   └── index.html
├── logs
└── sbin
    └── nginx

命令参数

nginx version: nginx/1.20.1
Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]
             [-e filename] [-c filename] [-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: /tmp/nginx/)
  -e filename   : set error log file (default: logs/error.log)
  -c filename   : set configuration file (default: conf/nginx.conf)
  -g directives : set global directives out of configuration file

常用参数:

  • -v 显示版本
  • -V 显示版本和编译时参数,需要查已经支持的module可以用这个参数
  • -t -T 测试配置文件可用
  • -p 这个参数需要留意,设置工作目录前缀,配置文件里面写没有/的相对路径,会从这个目录开始如logs/error.log,这个参数的默认参数和我们编译时的--prefix一致
  • -c 指定配置文件,如果仅指定文件名如-c nginx.conf,那么需要的路径就是从-p参数开始
  • -s 发送信号,操作服务,stop停止服务,reopen重新打开日志,reload重新加载配置。

启动服务

编译安装好后使用默认配置文件启动

sudo /tmp/nginx/sbin/nginx -c conf/nginx.conf

测试

curl  http://127.0.0.1

停止

sudo /tmp/nginx/sbin/nginx -c conf/nginx.conf -s stop
阅读全文