前言
Nginx是一款高性能的HTTP和反向代理服务器。在互联网早期,很多公司使用的都是Apache的HTTPD服务器,可是随着互联网业务的逐渐发展,Apache服务器在很多情况下满足不了业务的需求。这时一直紧跟Apache脚步的Nginx逐渐发展了起来。Nginx以其卓越的性能,以及优秀的高并发量和反向代理,逐渐得到了越来越多互联网公司的使用。
在国内的很多互联网公司使用就是Nginx。其中还有很多像阿里这种大公司对Nginx进行了二次开发,使其更加适合自己的业务发展。
但是并不是说Nginx能够取代Apache,因为Apache也有其适用的场景。我们看下面一组调查数据,或许能够对互联网服务器的发展有一个清晰的了解。
以上数据参考自
https://news.netcraft.com/archives/2017/08/29/august-2017-web-server-survey.html
从上面的数据中可以了解到,互联网服务器还是有很多种类,Apache和Nginx只是在其中占了比较大的比例,并且正按照不同的趋势发展着。下面我们就来介绍一下Nginx的配置和使用。
安装
与Apache一样,Nginx也可以自己手动编译安装,并制定自己需要的各种功能选项,这一点我们留在以后再讲。
CentOS 的官方安装包中不包含Nginx的安装包,所以我们需要从EPEL源里面去安装。CentOS 7 EPEL源中Nginx的版本是1.10.2.
安装成功之后,我们执行
nginx -h
就可以查看基本的使用帮助。
[root@localhost ~]#nginx -h
nginx version: nginx/1.10.2
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/share/nginx/)
-c filename : set configuration file (default: /etc/nginx/nginx.conf)
-g directives : set global directives out of configuration file
Options:
-?,-h : 使用帮助
-v : 显示版本
-V : 显示版本和配置信息
-t : 检查配置文件是否错误
-T : 检查配置文件,并将服务发布
-q : suppress non-error messages during configuration testing
-s signal : 根据 stop, quit, reopen, reload 管理服务进程
-p prefix : 编译时可以指定安装路径 (default: /usr/share/nginx/)
-c filename : 指定配置文件路径 (default: /etc/nginx/nginx.conf)
-g directives : 设置全局配置文件路径
配置
学习一门技术最好的办法就是查看官方的文档,这一点有时会好过市面上的大部分数据。Nginx是一个庞大的工程,需要学习的知识点多,所以我们就参考官方文档,来进行学习。
官方文档地址 http://nginx.org/en/docs/
Nginx 配置结构
通过查看Nginx的默认配置文件,我们总结了下面这样一种文件结构。
... #全局块
events { #events块
...
}
http #http块
{
... #http全局块
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server # 多个server就构建了多个虚拟主机
{
... # 针对这个server的基本配置
}
... #http全局块
}
从结构中可以很清晰的看到,两个大的布局,分别是全局的主配置块以及Http配置块。这两个模块将会在日常的工作应用中进行大量的配置,接下来,我们也主要介绍这两个模块。
全局配置段常用的配置
全局段的配置文件,从功能上来分,大体上可以分为下面几种,正常运行必备的配置,优化性能需要的配置,事件驱动需要的配置,调试和定位的问题。接下来,从每个方面挑选一些比较重要的内容进行介绍。
一、正常运行必备的配置
1、进程运行时的用户
通过查看官方文档说明,管理user的语法结构如下。
Syntax: user user [group];
Default: user nobody nobody;
Context: main
- Synatx: 说明语法的使用
- Default: 如果没有指定的话,默认是nobody用户。如果没有明确地指定组,默认是与用户同名的组。
- Context: 指明该语法能够配置在哪里,这里只能是 主代码块。
2、指定存储nginx主进程PID的文件路径
Syntax: pid file; # 指定主进程文件路径
Default: pid nginx.pid;
Context: main
3、动态加载模块的配置文件
include /usr/share/nginx/modules/*.conf;
二、优化性能需要的配置
1、 woker进程的数量
Syntax: worker_processes number | auto;
Default: worker_processes 1;
Context: main
指定woker进程的数量,通常指定为当前CPU的物理核心数。但是如果不是很了解这其中的运行机制的话,设置为auto也是一个不错的选择,Nginx版本从1.3.8开始支持auto选项。
2、将woker进程与CPU进行绑定
Nginx 可以指定哪些CPU可以来处理worker进程。默认不指定。语法如下。
Syntax: worker_cpu_affinity cpumask ...;
worker_cpu_affinity auto [cpumask];
Default: —
Context: main
我们以下面的官方示例来进行介绍。
2进程,2核cpu
worker_processes 2; # 一共有2个work进程
worker_cpu_affinity 01 10;
01 表示启用第一个CPU内核,02表示开启第二个CPU内核。
4个进程,4核CPU
worker_processes 4; # 一共有四个work进程
worker_cpu_affinity 0001 0010 0100 1000;
0001表示启用第一个内核,0010表示启用第二个内核,以此类推。
如果只开启了两个进程,想要平分4核CPU,该怎么做
worker_processes 2; # 一共有2个work进程
worker_cpu_affinity 0101 1010;
0101 表示开启第一个和第三个CPU内核,1010表示第二个和第四个CPU内核。通过上面的几个示例,我们大体上应该明白,有几个CPU核心就有几位二进制数,每一位二进制数在对应的位置上分别表示相应CPU核心的开关。 2核是01,10,4核是0001,0010… 8核是 00000001,00000010 …. 所谓的开关也是相对的概念,CPU核心关闭了,只是不再处理Nginx的进程,系统的其他进程还是会去处理。
实现后的效果如下图所示。从图中可以看到,两个worker进程的CPU在不断的切换。
3、指定worker进程优先级
Syntax: worker_priority number;
Default: worker_priority 0;
Context: main
设定worker进程的优先级。进程优先级的范围是[-20,20].
4、woker进程可以打开的最大的文件数量
Syntax: worker_rlimit_nofile number;
Default: —
Context: main
直接修改配置文件,就可以指定worker进程能够打开的最大的文件数量。不用重新启动主进程。
三、事件驱动相关的配置
事件驱动的相关配置都是写在
event{ .... }
代码块中的,很容易区分。接下来介绍几个常用的配置。
1、每个worker进程所能够打开的最大并发连接数数量
Syntax: worker_connections number;
Default: worker_connections 512;
Context: events
可以指定每个worker进程的的最大并发连接数。当然,在指定数量的时候应该根据实际情况来指定,因为操作系统的Socket数量一共就65536个。
2、指明并发链接请求的方法
Syntax: use method;
Default: —
Context: events
并发链接的请求的方法有很多种。例如poll,epoll,select,等等很多种形式。Nginx模式使用最有效的方式。
3、是否让每个进程轮流处理请求
Syntax: accept_mutex on | off;
Default: accept_mutex off;
Context: events
处理新的连接请求的方法;on指由各个worker轮流处理新请求,Off指每个新请求的到达都会通知(唤醒)所有的worker进程,但只有一个进程可获得连接,但是会影响性能,默认on
四、调试和定位的问题
1、是否以守护进程的方式运行Nginx
Syntax: daemon on | off;
Default: daemon on;
Context: main
守护进程指的是,进程默认在后台运行。Nginx默认是以守护进程的形式运行程序。一般用户开发调试等应用场景中。
2、是否以master/worker模型运行nginx
Syntax: master_process on | off;
Default: master_process on;
Context: main
Nginx默认启动worker进程。如果master_process 开启,则进程列表中将不会有worker进程。
3、指定默认的日志级别
Syntax: error_log file [level];
Default: error_log logs/error.log error;
Context: main, http, mail, stream, server, location
在实际的使用中,可以根据自己的实际情况进行相应的级别调整。
关于全局配置段的相关配置还可以参考官方文档http://nginx.org/en/docs/ngx_core_module.html#example
http的配置结构
在前的介绍中,我们已经介绍过,关于httpd的配置都必须写在
server{....}
代码块中。
Nginx的Http配置主要位于ngx_http_core_module
模块中。
一、设置监听端口以及相关属性
1、监听端口
通常,我们知道TCP默认访问的是80端口,但是我们也可以手动指定核配置这个端口,并指定以什么样的形式来监听。
Syntax: listen address[:port] [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
listen port [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
listen unix:path [default_server] [ssl] [http2 | spdy] [proxy_protocol] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
Default:
listen *:80 | *:8000;
Context: server
这条命令太酸爽,我们主要介绍其中几个比较重要的几个配置。
- default_server 设定为默认虚拟主机
- ssl 限制仅能够通过ssl连接提供服务
- backlog=number 超过并发连接数后,新请求进入后援队列的长度,超出限制就加入等待队列。
- rcvbuf=size 接收缓冲区大小
- sndbuf=size 发送缓冲区大小
2、ServerName
ServerName 指的是我们通过域名来访问的时候的地址。而且还可以设置为泛域名解析。
Syntax: server_name name ...; Default: server_name ""; Context: server
虚拟主机后面的主机名称可以跟多个由空白字符分隔的字符串
支持*通配任意长度的任意字符。例如server_name *.taobao.com www.taobao.*
3、设置TCP是否延迟发送
Syntax: tcp_nodelay on | off;
Default: tcp_nodelay on;
Context: http, server, location
在keepalived模式下的连接是否启用TCP_NODELAY选项,当为off时,延迟发送,合并多个请求后再发送默认On时,不延迟发送
4、是否显示服务器版本
当用户访问web服务时,是否在响应报文的首部显示Nginx的版本。 默认是ON。
Syntax: server_tokens on | off | build | string;
Default: server_tokens on;
Context: http, server, location
二、定义路径相关的配置
5、Location配置
我们先来看一下官方网站给出的示例。
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}
location代码块的语法可以归结为
location [ = | ~ | ~* | ^~ ] uri { ... }
,在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有 location,并找出一个最佳匹配,而后应用其配置。
在指定location的过程中,使用了不同的符号,是具有不同的匹配规则的。
= : 表示对 uri 精确匹配。
^~:对URI的最左边部分做匹配检查,不区分字符大小写
~:对URI做正则表达式模式匹配,区分字符大小写
~*
:对URI做正则表达式模式匹配,不区分字符大小写
不带符号:匹配起始于此uri的所有的uri
匹配优先级从高到低:=, ^~, ~/~*
, 不带符号
6、alias path 别名路径
通过定义一个别名路径来替换特定的目录。
Syntax: alias path;
Default: —
Context: location
下面来看一个例子。
server { # 基于ip的虚拟主机配置
listen 172.18.2.77:81;
root /app/site2;
location /images {
root /app/website; #当我们访问 http://172.18.2.77:81/images的时候实际上
#访问的却是 /app/website/images/ 路径
}
location /blog {
alias /app/website1 ; # 当我们访问 http://172.18.2.77:81/blog 的时候
# 实际上访问的内容 却变成了/app/website1路径下的资源
}
}
从上面的例子中,可以看出,alias是将uri全部替换掉,而root也只替换了uri的部分内容,二者还是有所区别的。
7、指定错误页面
在访问互联网资源的过程中,很容易遇见404页面,而一些成熟的web服务会将错误页面重定向到指定的页面上,接下来来配置一下这个页面。
Syntax: error_page code ... [=[response]] uri;
Default: —
Context: http, server, location, if in location
error_page 404 /404.html;
# 当出现错误的时候,直接跳转到404页面,但是返回给客户端的是200状态码。
error_page 404 =200 /404.html;
error_page 500 502 503 504 /50x.html;
顺序检查文件是否存在
按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有的文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内部500错误。
Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location
可以参考下面的示例,其中$uri表示系统中的变量,可以查看官方文档了解。
location /images/ {
try_files $uri /images/default.gif;
}
location / {
try_files $uri $uri/index.html $uri.html =404;
}
三、定义客户端请求的相关配置
1、设置keepalive超时时间
客户端访问web服务的时候,可以允许客户端以长链接的形式访问资源,定义超时时间。设置为0表示,禁止长链接。
Syntax: keepalive_timeout timeout [header_timeout];
Default: keepalive_timeout 75s;
Context: http, server, location
2、长连接上资源的请求数量
在一次长连接上所允许请求的资源的最大数量。默认的大小是100
Syntax: keepalive_requests number;
Default: keepalive_requests 100;
Context: http, server, location
3、限制响应给客户端的传输速率
限制响应给客户端的传输速率,单位是bytes/second,默认值为0表示不限制。
Syntax: limit_rate rate;
Default: limit_rate 0;
Context: http, server, location, if in location
4、限制客户端使用除了指定的请求方法之外的其它方法
limit_except method ... { ... }
,仅用于location,可以限制客户端使用除了指定的请求方法之外的其它方法,常见的method:GET, HEAD, POST, PUT, DELETE,MKCOL, COPY, MOVE, OPTIONS, PROPFIND,PROPPATCH, LOCK, UNLOCK, PATCH。
Syntax: limit_except method ... { ... }
Default: —
Context: location
看一下下面的这个例子
limit_except GET {
allow 192.168.1.0/24;
deny all;
}
这里的作用是除了GET和HEAD 之外其它方法仅允许192.168.1.0/24网段主机使用。
总结
截止此处,我们已经介绍了Nginx的一些基本配置,这些配置都是基于
ngx_http_core_module
中的配置,还可以查看官方文档了解,http://nginx.org/en/docs/http/ngx_http_core_module.html 。
同时,在接下来的其他模块中,我们再接着介绍Nginx其他模块的配置和使用。
下面将学习过程中的示例配置文件附于下图,可右键点击在新的标签页中查看大图。