# 4 Nginx相关配置
### 4.1 重启Nginx
```bash
#sudo /usr/local/sbin/nginx -s reload
```
### 4.2 关闭Nginx
```bash
快速停止服务
#sudo /usr/local/sbin/nginx -s stop

优雅停止服务
#sudo /usr/local/sbin/nginx -s quit #kill -s SIGQUIT pid_master
#kill -s SIGWINCH pid_master
```
###4.3 Nginx进程之间关系
一个master进程来管理多个work进程.
work进程数量和CPU的核数相同(进程间切换的代价最小)
### 4.4 Nginx配置通用语法
**块配置项**
```bash
块配置项由一个块配置项名和一对大括号组成. 比如
events {
use epoll;
}
nginx.conf中的events,http,server,location,upstream等都是块配置项 块配置项可以嵌套,内嵌块直接继承外层块.
```
**块配置项的语法格式**
```bash
基本格式:
配置项名 配置项值1 配置项值2 ...;
配置项目必须是nginx的某一模块想要处理的,否则判定为非法配置项名. 配置项值可以是数字,字符串包括正则表达式,可能有多个值. 每行配置的末尾以分好';'结束
```
**配置项的单位**
```bash
以'#'字符开始 的一行视为注释
#pid logs/nginx.pid
指定空间大小 单位包括 K k 千字节(KB),M m 兆字节(MB)
gzip_buffers 4 8k;
client_max_body_size 64M;
指定时间大小 单位包括 ms,s,s,m,h,d,w,M,y; expires 10m;#有效期为10s
```
**配置项中使用变量**
```bash
$varname 比如:
log_format main '$remote_addr - $remote_user'
```
### 4.5 Nginx服务基本配置
```bash
Nginx服务在运行时,至少需要加载几个核心模块和一个事件类模块. 这些模块所支持的配置统称为基本配置.
主要分为4大类:
1用于调试定位为题的配置项
2正常运行的必备配置项
3优化性能的配置项
4事件类配置项
```
### **用以调试和定位问题的配置块 **
是否以守护进程方式运行
```bash
daemon on|off;
默认为on
如果调试阶段 可以设置为off 以 前台进程方式运行 这样便于跟踪调试Nginx
```
是否以master/worker方式工作
```bash
master_process on | off;
默认为on
如果调试阶段 可以设置为off 以 master进程自身来响应请求 这样便于跟踪调试Nginx
```
**errorr日志的设置**
```bash
error_log /path/file level;
#第一个项为设置为error日志的路径和文件名
#第二项为等级 有debug,info,notice,warn,error,crit,alert,emerg 默认为 logs/error.log error;
当第一项设置为 /dev/null 表示忽略任何日志
当设置为 stderr 这样错误日志会输出到标准错误文件中.
第二项的等级 自左向右依次增加.
最后应该保证输出日志的硬盘空间应当足够使用
**设置成debug模式的时候,需要在configure时 加上--with-debug 参数
```
**仅对指定的客户端输出debug级别的日志**
```bash
debug_connection IP[/port]
由于该配置属于事件类配置,需要放置在events{...}才有效 例如:
events{
debug_connection 192.168.1.100;
debug_connection 192.168.1.100/24;
}
仅对以上设置的IP才设置成debug级别的日志,其他请求沿用error_log 配置的级别
```
**限制coredump核心转储文件的大小**
```bash
worker_rlimit_core_size size;
以size来限制coredump文件的大小.
```
**指定coredump文件的位置**
```bash
working_directory path;
path指定coredump文件的位置
需要保证path路径有足够的写入权限和足够的使用空间.
```
###正常运行配置项
**引入其他配置文件**
```php
include /path/file;
include配置项可以将其他配置文件引入到当前的nginx.conf文件中,参数可以是绝对路径和相对(conf/)路径
include mine.types;
include vhost/*.conf
```
**pid文件的位置**
```bash
pid path/file
logs/nginx/pid
保存master进程ID的pid文件夹的存放路径
应该确保nginx在相应的目录中有创建pid文件的权限.
```
**Nginx worker进程运行的用户和用户组
**
```bash
user username [groupname];
user nobody nobody;
user用于设置master进程启动后,fork出的worker子进程运行在哪个用户和用户组下.
当设置username没有设置groupname,则默认username与groupname相同.
```
**指定worker进程可以打开的最大文件句柄描述符个数**
```bash
worker_rlimit_nofile limit_num;
设置一个worker进程可以打开的最大文件句柄数.(应该大于最大连接数)
```
**限制信号队列长度**
```bash
worker_rlimit_sigpending limit_num;
设置每个用户发往Nginx信号队列的大小.多的将丢弃
```
### 优化性能配置项
**Nginx worker进程的个数**
```bash
worker_process number;
默认为1
worker进程的数量直接影响性能.合适的worker进程数量和业务息息相关.
worker进程是单线程的进程,如果确认各模块中不会出现阻塞调用那么number设置为cpu的核数
如果有可能出现阻塞调用,number设置的比cpu核数大一点.
多worker进程可以充分利用多核系统架构,如果worker进程相比CPU数量太多会增加进程间切换的消耗.
```
**绑定Nginx worker进程到指定的CPU内核**
```bash
**仅对Linux有效
worker_cpu_affinity cpumask[cpumask...]
可防止多个进程抢占同一核心
worker_processes 4;
worker_cpu_affinity 1000 0100 0010 0001;
worker_processes 2;
worker_cpu_affinity 10 01;
```
**系统调用getimeofday()的执行频率**
```bash
默认 timer_resolution t;
例如 timer_resolution 100ms;表示至少每100ms才调用一次gettimeofday()
目前大多数内核中,花销只是一次vsyscall()仅对共享内存页中的数据做访问.一般可以不适用这个配置
```
### 事件类配置项
**是否打开accept锁**
```bash
accept是Nginx负载均衡锁.这把锁可以让多个work进程轮流,有序的与新的客户端建立TCP连接.
默认是打开的.
如果配置关闭,建立TCP连接耗时会更短.但是多个worker之间负载不会均衡.
```
**lock文件的路径**
```bash
lock_file path/file
默认 logs/nginx.lock
accept锁可能需要这个lock文件,如果accept锁配置关闭那么lock_file配置无效
如果accept锁配置打开且由于操作系统和编译器等因素导致Nginx不支持原子锁,将利用文件锁实现accept.
```
**使用accept锁后到真正建立连接之间的延迟时间**
```bash
accept_mutex_delay numberms;
默认500ms;
一个worker进程试图获取到accept锁失败,经过number ms时间再次试图获取accept锁.
```
**批量建立连接**
```bash
multi_accept [on|off]
默认off
当时间模型通知有新连接时,尽量对本次调度中客户端发起的TCP请求都建立连接.
```
**选择事件模型**
```bash
use [kqueue | rtsig epoll | /dev/poll | select |poll |eventport]
默认 Nginx会自动选择最适合的事件模型.
对于Linux来说,可以供选择的时间驱动模型有select,poll,epoll的三种.
```
**每个worker的最大连接数**
```bash
worker_connection number;
定义每个worker进程可以同时处理的最大连接数
```
### 使用HTTP核心模块配置一个静态WEB服务器
```bash
所有的HTTP配置项都必须直属于http块,server块,location块,upstream块,if块.
直属于指的是配置项直接所属的大括号对应的设置块
```
**虚拟主机与请求的分发**
```bash
由于IP有限,存在多个主机域名对应同一个IP地址的情况.在nginx.conf中可以通过server块 来设置server_name定义虚拟主机.
每个server块就是一个虚拟主机,只处理与之相应的主机域名请求,
这样一套服务器上的Nginx就能以不同的方式处理不同的域名的HTTP请求了.
```
**监听端口**
```bash
listen address:port[default | default_server |[backlog=num |revbuf=size
| sndbuf=size| accept_filter=filter |deferred|bind|ipv6only=[on|off] |ssl]]
```
默认listen 80
在listen之后可以只加IP地址,端口,或者主机名
```bash
isten 127.0.0.1:8000;
listen localhost;
listen 8000;
listen *:8000;
listen 443 default_server ssl;
```
```bash
default 将所在的server块作为整个WEB服务的默认server块;如果所有的server都没设置这个参数, nginx.conf第一个server作为默认块.
当一个请求无法匹配配置文件的任一主机名就会选用默认虚拟主机. default_server 同上
backlog=num 表示TCP中backlog队列的大小,默认为-1表示不设置. TCP三次握手过程中进程还没有处理监听句柄,backlog用以放置这个新连接, 如果队列已满,新客户端3次握手建立连接失败
deferred 设置这个参数后,通过三次握手之后内核不会在建立连接时处理,而是等发来数据的时候处理连接.
bind 绑定当前地址:端口
ssl 在当前监听的端口上建立的连接必须给予SSL协议
```
**主机名称**
```bash
server_name name[...];
默认 server_name "";
server_name之后可以跟多个主机名称
eg: server_name www.wowpai.top download.wowpai.top;
在开始处理HTTP请求时,Nginx会取出header头中的host,与server中每个server_name进行比较, 如果多个server块都匹配需要按照优先级来选择处理的server块.
首先选择所有字符完全匹配的server_name www.wowpai.top
其次选择通配符在前面的server_name *.wowpai.top
其次选择通配符在后面的server_name www.wowpai.*
最后选择使用正则匹配的server_name ~^\.wowpai\.top$
如果以上都不能匹配将按照以下的server块:
优先选择在listen配置项后加入[default |default_server]的server块 找到匹配listen端口的第一个server块
如果server_name后面跟着字符串 server_name ""表示匹配没有Host这个HTTP头部的请求
Nginx使用server_name配置项针对特定Host域名的请求提供不同的服务以实现虚拟主机的功能.
```
**server_names_hash_bucket_size**
```bash
server_names_hash_bucket_size size;
默认 server_names_hash_bucket_size 32|64|128;
可配置块 http server location
为提高查找相应的server_name的能力,Nginx使用散列表来存储. size设置了每个散列块占用的字节数.
```
**server_names_hash_max_size**
```bash
server_names_hash_max_size size;
默认 server_names_hash_max_size 512;
可配置块 http serverlocation
server_names_hash_max_size 影响散列表的冲突率,server_names_hash_max_size越大,冲突率越低,检索速度越快.
```
**重定向主机名称的处理**
```bash
server_name_in_redirect on|off;
默认 on
该配置需要配合server_name 使用.在使用on打开的时候,表示在重定向请求时会使用server_name里面配置的
第一个主机名代替原来的请求中的Host头部.
当使用off关闭时,表示在重定向请求时使用请求本身的Host头部.
```
### **location**
```bash
location [=|~|~* |^~| @ ] | /uri/ {}
可配置块 server
location会尝试根据用户请求中的URI来匹配上面的/uri表达式,如果可以[匹配就选择location{}块中的配置来处理用户请求.
location的匹配规则:
= 表示把URI作为字符 以便与参数中的uri做完全匹配
location = /{
#只有当用户请求/时 才会调用该location下的配置
}
~ 表示匹配URI时字母大小写敏感的
~* 表示匹配URI时忽略字母大小写 后面可以跟上正则表达式
location ~* \.(gif|jpg|jpeg){
#匹配这三种图片的资源请求
}
^~ 表示匹配URI只需要前半部分uri参数匹配即可
location ^~ /images/{
#以/images/开始的请求都会匹配上
}
@ 表示仅用于Nginx服务内部请求之间的重定向,带有@的location不直接处理用户请求
没有匹配的URI应该得到一个响应,
location /{
#前面所有的匹配都未成功就意味着会被这个location 匹配-----捕获
}
**location匹配的存在一定的优先级:先精确匹配然后模糊匹配,最后匹配/
```
**文件路径定义**
**1 以root设置资源路径
**
```bash
root path;
默认 root html;
配置项: http server location if
location /download/ {
root /opt/web/html/;
}
如果请求的URI是/download/index/test.html,那么WEB服务器应该返回的是服务器上
/opt/web/html/download/index/test.html
```
**2 以alias设置资源路径
**
```bash
alias path;
配置块:location
alias也是用来设置资源路径的.与root的不同点在于如何解读紧跟location后面的参数. 这将会致使alias与root以不同的方式将用户的请求映射到真正的磁盘文件上.
如果请求的URI是 /conf/nginx.conf,实际上访问文件在/usr/local/nginx/conf/nginx.conf
location /conf{
alias /usr/local/nginx/conf/;
}
location /conf{
root /usr/local/nginx/;
}
使用alias时在URI向实际文件映射的过程中,已经把location后配置的/conf这部分字符串丢弃掉. 最终映射成path/nginx.conf文件
而root则不一样 最终直接映射成 path/conf/nginx.conf
```
**3 设置首页**
```bash
index file ...;
默认 index index.html;
配置块 http server
location location /{
root html;
index index.html index.htm index.php;
}
优先返回index.php,没有的话返回index.htm,如果还没有,再尝试放回index.html
```
**4 根据HTTP返回码重定向**
```bash
rror_page code[code ...] [= | = answer-code] uri|@name_location
配置块 http server location if
如果某个请求返回错误码时匹配上了error_page中设置的code,则重定向到新的URI中. 虽然重定向了URI,但返回的错误码还是和原来的相同.可以通过'='来改变返回的错误码
error_page 404 =200 /empty.html
如果不修改 URI,只是想让这样的请求重定向到另一个location中处理
location /{
error_page 404 @failback;
}
location @failback{
proxy_pass http://127.0.0.1:8081;
}
```
**5 是否允许定义error_page
**
```bash
recursive_error_pages [on|off];
默认recursive_error_pages off;
配置块 http server location
确定是否允许定义error_page
```
**try_files**
```bash
try_files path1 [path2] uri;
配置块 server location
try_files 后面可以跟上多个path,且最后一定要跟上uri
按照顺序遍历每个path,如果可以有效的读取就直接返回这个path并结束请求. 否则继续向后遍历,最后就重定向到uri上
location /{
#try_files $uri $uri/ /$uri.html $uri/index.html @other;
try_files $uri $uri/ /error/php?c=404 =404;
}
location @other{
proxy_pass http://backend;
}
```
** 对客户端请求的限制 **
按HTTP方法名限制用户请求
```bash
limit_execpt method ...{
...
}
配置块 location
方法名有 PUT HEAD POST DELETE MKCOL COPY MOVE OPTIONS PROPFIND PROPPATCH LOCK UNLOCK PATCH
limit GET{
allow 192.168.1.110/32;
deny all;
}
禁止GET 和HEAD方法,其他方法允许
```
HTTP请求包体的最大值
```bash
client_max_body_size size;
默认 client_max_body_size 1m;
配置块 http server location
用户打算上传一个超过10G的文件,发超过定义client_max_size的值,回复错误
```
对请求的限速
```bash
imit_rate speed;
limit_rate 0;
配置块 http server location if 限制客户端请求限制每秒的传输的字节数.0表示不限制
server{
if ( $slow)
{
set $limit_rate 4k;
}
}
```