基础
控制命令
信号量
Nginx启动后会产生一个master进程和多个worker进程,可以通过对master进行发送信号量实现对nginx进行控制与管理。
kill -信号量 pid
kill -信号量 `cat logs\nginx.pid` //日志目录下的nginx.pid记录了nginx master进程的pid
信号量 | 功能 |
---|---|
TERM,INT | 强制快速关闭,不建议使用 |
QUIT | 优雅的关闭进程,即等请求结束后再关闭 |
HUP | 改变配置文件,平滑的重读配置文件 |
USR1 | 重读日志,在日志按月/日分割时有用 |
USR2 | 平滑的升级 |
WINCH | 优雅关闭旧的进程(配合USR2来进行升级) |
nginx命令控制
在nginx目录下的sbin中有个nginx是命令控制入口;
nginx //启动nginx
nginx -h //帮助
nginx -s singal //类似信号量,XX包括stop, quit, reopen, reload
nginx -t //测试配置是否正确
日志管理
access日志
- server段中配置
access_log logs/host.access.log main;
这说明 该server, 它的访问日志的文件是logs/host.access.log
,使用的格式main
格式。 - http段中定义日志格式,定义好格式后可在配置日志的时候选择日志格式。
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
日志切割
- 采用cron与nginx的信号量(USR1)实现对日志的定时切割.
#!/bin/bash
base_path='/usr/local/nginx/logs'
log_path=$(date -d yesterday +"%Y%m")
day=$(date -d yesterday +"%d")
mkdir -p $base_path/$log_path
mv $base_path/access.log $base_path/$log_path/access_$day.log
#echo $base_path/$log_path/access_$day.log
kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
location
location用于根据URI来进行不同的定位,在server中必须配置location来使URI定位到不同位置上。
- 精准匹配,必须完全匹配patt
location = patt{
}
- 一般匹配,根据URI的字符串进行匹配patt
location patt{
}
- 正则匹配
location ^~ patt{} //表示URI以patt开头
location ~ patt{} //表示区分大小写的正则匹配patt
location ~* patt{} //表示不区分大小写的正则匹配patt
location !~ patt{} //区分大小写不匹配的正则匹配patt
location !~* patt{} //表示不区分大小写的不匹配正则匹配patt
匹配流程
- URI解析,进行精准匹配,匹配成功则返回,否则进入步骤2.
- 进行一般匹配,如果匹配成功则记录最长的那个匹配结果。进入步骤3.
- 进行正则匹配,先匹配^~的匹配,而后再按顺序匹配,当匹配到一个后马上返回结果,都没匹配上则返回2中的结果。
访问文件夹问题
- 当URI为文件夹时,nginx会进行两次匹配。
- 首先根据原始URI匹配到location,而后将原始URI加上location中index中设置的文件形成新的URI。
- 根据新的URI再次进行location匹配最终将结果呈现到浏览器。
rewrite
- if (条件) {} 设定条件,再进行重写
if 空格 (条件){}
条件可以:
1: “=”来判断相等, 用于字符串比较
2: “~” 用正则来匹配(此处的正则区分大小写)
~* 不区分大小写的正则
3: -f -d -e来判断是否为文件,为目录,是否存在.
-
set #设置变量
-
return #返回状态码
-
break #跳出rewrite
-
rewrite #重写
-
服务器内部的rewrite和302跳转不一样.
跳转的话URL都变了,内部rewrite, 上下文所有nginx可以引用到的变量都没变。
location /ecshop {
index index.php;
rewrite goods-([\d]+)\.html$ /ecshop/goods.php?id=$1;
rewrite article-([\d]+)\.html$ /ecshop/article.php?id=$1;
rewrite category-(\d+)-b(\d+)\.html /ecshop/category.php?id=$1&brand=$2;
rewrite category-(\d+)-b(\d+)-min(\d+)-max(\d+)-attr([\d\.]+)\.html /ecshop/category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5;
rewrite category-(\d+)-b(\d+)-min(\d+)-max(\d+)-attr([\d+\.])-(\d+)-([^-]+)-([^-]+)\.html /ecshop/category.php?id=$1&brand=$2&price_min=$3&price_max=$4&filter_attr=$5&page=$6&sort=$7&order=$8;
}
gzip
- http协议的请求头中
Accept-Encoding:gzip,deflate,sdch
,必须包含gzip表示浏览器支持gzip压缩。 - 响应时如果返回gizp时需要设置
Content-Encoding:gzip
- Context: http, server, location, if in location 表示可以配置的位置。
gzip配置的常用参数
gzip on|off; #是否开启gzip
gzip_buffers 32 4K| 16 8K #缓冲(压缩在内存中缓冲几块? 每块多大?)
gzip_comp_level [1-9] #推荐6 压缩级别(级别越高,压的越小,越浪费CPU计算资源)
gzip_disable #正则匹配UA 什么样的Uri不进行gzip
gzip_min_length 200 # 开始压缩的最小长度(再小就不要压缩了,意义不在)
gzip_http_version 1.0|1.1 # 开始压缩的http协议版本(可以不设置,目前几乎全是1.1协议)
gzip_proxied # 设置请求者代理服务器,该如何缓存内容
gzip_types text/plain application/xml # 对哪些类型的文件用压缩 如txt,xml,html ,css
gzip_vary on|off # 是否传输gzip压缩标志
- 图片/mp3这样的二进制文件,不必压缩.
- 比较小的文件不必压缩.
expires
- 设置文件缓存在用户的浏览器端,且时间比较长的缓存.
- 在location或if段里,来写。
- 格式expires 30s/m/h/d,分别表示缓存秒/分/小时/天.
- 304 也是一种很好的缓存手段
原理:服务器响应文件内容是,同时响应etag标签(内容的签名,内容一变,他也变), 和 last_modified_since 2个标签值
浏览器下次去请求时,头信息发送这两个标签, 服务器检测文件有没有发生变化,如无,直接头信息返回 etag,last_modified_since
浏览器知道内容无改变,于是直接调用本地缓存.
这个过程,也请求了服务器,但是传着的内容极少.
反向代理与负载均衡
- 在location中设置proxy_pass即可实现反向代理。
- 多台服务器通过upstream绑定在一起并取一个组名,upstream写在http段中。
- 负载均衡则通过proxy_pass指向upstream的组名即可。
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
server {
location / {
proxy_pass http://backend;
}
}