一、nginx监控
- 进程监控
- 端口监控
nginx提供了ngx_http_stub_status_module,ngx_http_requstat_module模块,这两个模块提供了基本的监控功能
- 这个模块计算定义的变量,根据变量值分别统计 nginx 的运行状况。
- 可以监视的运行状况有:连接数、请求数、各种响应码范围的请求数、输入输出流量、rt、upstream访问等。
- 可以指定获取所有监控结果或者一部分监控结果。
- 利用变量添加自定义监控状态。总的监控状态最大个数为50个。
- 回收过期的监控数据。
- 设置输出格式- 跟踪请求,不受内部跳转的影响
- 不要使用与响应相关的变量作为条件,比如"$status"
1、监控的主要指标
1、基本活跃指标
Accepts(接受)、Handled(已处理)、Requests(请求数)、Active(活跃)、Waiting(等待)、Reading(读)、Writing(写)
名称 | 描述 | 指标类型 |
---|---|---|
Accepts(接受) | NGINX 所接受的客户端连接数 | 资源: 功能 |
Handled(已处理) | 成功的客户端连接数 | 资源: 功能 |
Dropped(已丢弃,计算得出) | 丢弃的连接数(接受 - 已处理) | 工作:错误* |
Requests(请求数) | 客户端请求数 | 工作:吞吐量 |
2、每秒请求数 – QPS
按照固定时间间隔采样请求数据,计算出单位时间的请求量可以看到你的 web 服务器的请求情况
通过持续的 QPS 监控,可以立刻发现是否被恶意攻击或对服务的可用性进行评估
虽然当问题发生时,通过 QPS 不能定位到确切问题的位置,但是他却可以在第一时间提醒你环境可能出问题了
3、服务器错误率
通过监控固定时间间隔内的错误代码(4XX代码表示客户端错误,5XX代码表示服务器端错误),可以了解到客户端收到的结果是否是正确的错误率突然的飙升很可能是你的网站漏洞发出的信号
如果你希望通过 access log 分析错误率,那么你需要配置 nginx 的日志模块,让 nginx 将响应码写入访问日志
4、请求处理时间
请求处理时间也可以被记录在 access log 中,通过分析 access log,统计请求的平均响应时间,通过持续观察,可以发现上游服务器的问题
2、stub status模块使用
配置etc/nginx/nginx.conf
server {
listen 80;
server_name cosion;
location /nginx-status {
stub_status on;
access_log on;
allow 113.88.66.7; #允许本地电脑访问
deny all;
}
}
#此处默认只有本地访问,如果远程查看需要加相关的IP或者干脆去掉Deny all即可。加密文件可以使用#htpasswd -c /usr/nginx/conf hxb 命令来创建。配置完成后需要重启Nginx服务。状态配置只能是针对某个Nginx服务。目前Nginx还无法做到针对单个站点进行监控。
nginx 状态查看
3、stub status 参数说明
active connections – 活跃的连接数量
server accepts handled requests — 总共处理了1075个连接 , 成功创建1064次握手, 总共处理了6253个请求
每个连接有三种状态waiting、reading、writing
reading —读取客户端的Header信息数.这个操作只是读取头部信息,读取完后马上进入writing状态,因此时间很短。
writing — 响应数据到客户端的Header信息数.这个操作不仅读取头部,还要等待服务响应,因此时间比较长。
waiting — 开启keep-alive后等候下一次请求指令的驻留连接.
正常情况下waiting数量是比较多的,并不能说明性能差。反而如果reading+writing数量比较多说明服务并发有问题。
4、Reqstat模块监控
- 这个模块计算定义的变量,根据变量值分别统计 nginx 的运行状况。
- 可以监视的运行状况有:连接数、请求数、各种响应码范围的请求数、输入输出流量、rt、upstream访问等。
- 可以指定获取所有监控结果或者一部分监控结果。
- 利用变量添加自定义监控状态。总的监控状态最大个数为50个。
- 回收过期的监控数据。
- 设置输出格式
- 跟踪请求,不受内部跳转的影响
- 不要使用与响应相关的变量作为条件,比如"$status"
tengine官方说req-statu模块默认安装。但是并没有。而且tengine的req-status模块不能分upstream监控,从github引入第三方模块解决该问题
yum与编译安装的nginx扩展模块安装:
[root@cosion ~]# yum install -y unzip
1. 安装,先查看一下当前编译安装nginx的版本
[root@cosion nginx-1.16.0]# nginx -V
下载或者上传一个和当前的nginx版本一样的nginx的tar包。
[root@cosion ~]# tar xzf nginx-1.16.0.tar.gz -C /usr/local/
2.下载ngx_req_status_module 模块, 这是第三方模块需要添加
[root@cosion ~]# wget https://github.com/zls0424/ngx_req_status/archive/master.zip -O ngx_req_status.zip
[root@cosion ~]# unzip ngx_req_status.zip
[root@cosion ~]# cp -r ngx_req_status-master/ /usr/local/ #与解压的nginx在同一级目录下
[root@cosion ~]# cd /usr/local/nginx-1.16.0/
[root@cosion nginx-1.16.0]# yum -y install pcre pcre-devel openssl openssl-devel gcc gcc-c++ zlib zlib-devel
[root@cosion nginx-1.16.0]# yum -y install patch.x86_64
[root@cosion nginx-1.16.0]# patch -p1 < ../ngx_req_status-master/write_filter-1.7.11.patch
[root@cosion nginx-1.16.0]# ./configure 添加上原来的参数 --add-module=/usr/local/ngx_req_status-master
[root@cosion nginx-1.16.0]# make -j2
由于原先已有nginx,所以不能执行make install,否则会覆盖掉以前的配置文件及内容
[root@cosion nginx-1.16.0]# mv /usr/sbin/nginx /usr/sbin/nginx_bak
[root@cosion nginx-1.16.0]# cp objs/nginx /usr/sbin/
[root@cosion nginx-1.16.0]# systemctl restart nginx
[root@cosion nginx-1.16.0]# nginx -V
如果发现编译的配置文件有变化就成功了!
配置如下: 需要在http里面配置。
!!注意,添加了此配置,只有重启nginx才能生效。
[root@cosion ~]# vim /etc/nginx/nginx.conf
req_status_zone server_name $server_name 256k;
req_status_zone server_addr $server_addr 256k;
req_status_zone server_url $server_name$uri 256k;
req_status server_name server_addr server_url;
server {
server_name cosion;
location /req-status {
req_status_show on;
}
}
5、reqstat指令
req_status_zone
语法: req_status_zone name string size
默认值: None
配置块: http
定义请求状态ZONE,请求按照string分组来排列,例如:
req_status_zone server_url $server_name$uri 256k;
域名+uri将会形成一条数据,可以看到所有url的带宽,流量,访问数
req_status
语法: req_status zone1[ zone2]
默认值: None
配置块: http, server, location
在location中启用请求状态,你可以指定更多zones。
req_status_show
语法: req_status_show on
默认值: None
配置块: location
在当前位置启用请求状态处理程序
请求状态信息包括以下字段:
- zone_name - 利用req_status_zone定义的分组标准。例如,按照服务器名称对请求进行分组后;
- key - 请求按分组标准分组后的分组标识(即组名)。例如按服务器名称分组时,组名可能是10.0.105.196;
- max_active - 该组的最大并发连接数;
- max_bw - 该组的最大带宽;
- traffic - 该组的总流量;
- requests - 该组的总请求数;
- active - 该组当前的并发连接数;
- bandwidth - 该组当前带宽。
二、rewite地址重写
1、什么是Rewrite
Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程。
- URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。比如
http://www.123.com/news/index.php?id=123 使用URLRewrite 转换后可以显示为 http://www.123 .com/news/123.html对于追求完美主义的网站设计师,就算是网页的地址也希望看起来尽量简洁明快。
理论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页面的评分一般要高于动态页面。所以,UrlRewrite可以让我们网站的网页更容易被搜索引擎所收录。
伪静态化优点
1.搜索引擎更倾向
2.能够让整个url看上去更加简洁,用户体验最佳
3.让url变得更加安全
-
从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客
利用,对你的系统造成一定的破坏,所以静态化的URL地址可以给我们带来更高的安全性。 -
实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问tianyun.com的
80端口时,将其跳转到443端口。
2、Rewrite 相关指令
- Nginx Rewrite 相关指令有 if 、rewrite、set、return
2.1、if 语句
- 应用环境
server,location
语法:
if (condition) { … }
if 可以支持如下条件判断匹配符号
~ 正则匹配 (区分大小写)
~* 正则匹配 (不区分大小写)
!~ 正则不匹配 (区分大小写)
!~* 正则不匹配 (不区分大小写)
-f 和!-f 用来判断是否存在文件
-d 和!-d 用来判断是否存在目录
-e 和!-e 用来判断是否存在文件或目录
-x 和!-x 用来判断文件是否可执行
在匹配过程中可以引用一些Nginx的全局变量
$args 请求中的参数;
$document_root 针对当前请求的根路径设置值;
$host 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$limit_rate 对连接速率的限制;
$request_method 请求的方法,比如"GET"、"POST"等;
$remote_addr 客户端地址;
$remote_port 客户端端口号;
$remote_user 客户端用户名,认证用;
$request_filename 当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images/a.jpg)
$request_uri 当前请求的文件路径名(不带网站的主目录/images/a.jpg)
$query_string 与$args相同;
$scheme 用的协议,比如http或者是https
$server_protocol 请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
$server_name 请求到达的服务器名;
$document_uri 与$uri一样,URI地址;
$server_port 请求到达的服务器端口号;
2.2、Rewrite flag
rewrite 指令根据表达式来重定向URI,或者修改字符串。可以应用于server,location, if环境下每行rewrite指令最后跟一个flag标记,支持的flag标记有:
last 相当于Apache里的[L]标记,表示完成rewrite。默认为last。
break 本条规则匹配完成后,终止匹配,不再匹配后面的规则
redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent 返回301永久重定向,浏览器地址会显示跳转后URL地址
redirect 和 permanent区别则是返回的不同方式的重定向,对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。使用302重定向时,搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,也许地址栏不会更改,那么很有可能出现URL劫持的现像。在做URI重写时,有时会发现URI中含有相关参数,如果需要将这些参数保存下来,并且在重写过程中重新引用,可以用到 () 和 $N 的方式来解决。
注意:
-
last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求;
-
break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配;
-
使用 alias 指令时,必须使用 last;
-
使用 proxy_pass 指令时,则必须使用break。
三、location指令详解
Nginx 的 HTTP 配置主要包括三个区块,结构如下:
http { # 这个是协议级别
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
gzip on;
server { # 这个是服务器级别
listen 80;
server_name localhost;
location / { # 这个是请求级别
root html;
index index.html index.htm;
}
}
}
1、location 区段
-
location 是在 server 块中配置,根据不同的 URI 使用不同的配置,来处理不同的请求。
-
location 是有顺序的,会被第一个匹配的location 处理。
-
基本语法如下:
location [=|~|~*|^~|@] pattern{……}
2、location 前缀含义
= 表示精确匹配,优先级也是最高的
^~ 表示uri以某个常规字符串开头,理解为匹配url路径即可
~ 表示区分大小写的正则匹配
~* 表示不区分大小写的正则匹配
!~ 表示区分大小写不匹配的正则
!~* 表示不区分大小写不匹配的正则
/ 通用匹配,任何请求都会匹配到
@ 内部服务跳转
3、location 配置示例
本地解析域名host
1、没有修饰符 表示:必须以指定模式开始
server {
listen 80;
server_name test.com;
location /abc {
root /home/www/nginx;
index 2.html;
}
那么,如下是对的:
http://test.com/abc
http://test.com/abc?p1
http://test.com/abc/
http://test.com/abcde
2、=表示:必须与指定的模式精确匹配
server {
listen 80;
server_name www.testpm.cn;
access_log /var/log/nginx/http_access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location = /abc {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
那么,如下是对的:
http://test.com/abc
http://test.com/abc?p1
http://test.com/abc/
如下是错的
http://test.com/abcde
3、~ 表示:指定的正则表达式要区分大小写
server {
server_name test.com;
location ~ ^/abc$ {
……
}
}
那么,如下是对的:
http://test.com/abc
http://test.com/abc?p1=11&p2=22
如下是错的
http://test.com/ABC
http://test.com/abc/
http://test.com/abcde
4、~* 表示:指定的正则表达式不区分大小写
server {
server_name test.com;
location ~* ^/abc$ {
……
}
}
那么,如下是对的:
http://test.com/abc
http://test.com/ABC
http://test.com/abc?p1=11&p2=22
如下是错的:
http://test.com/abc/
http://test.com/abcde
5、^~ :类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,那么就停止搜索其他模式了。
6、@ :定义命名 location 区段,这些区段客户段不能访问,只可以由内部产生的请求来访问,如try_files或error_page等
查找顺序和优先级
1:带有“=“的精确匹配优先
2:没有修饰符的精确匹配
3:正则表达式按照他们在配置文件中定义的顺序
4:带有“^~”修饰符的,开头匹配
5:带有“~” 或“~*” 修饰符的,如果正则表达式与URI匹配
6:没有修饰符的,如果指定字符串与URI开头匹配
= 大于 ^~ 大于 ~|~*|!~|!~* 大于 /
多个location配置的情况下匹配顺序为:首先匹配 =,其次匹配^~, 其次是按正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
================================================
(1) =:表示完全匹配;
(2) ^~:匹配URI的前缀,并且后面的正则表达式不再匹配,如果一个URI同时满足两个规则的话,匹配最长的规则;
(3) ~:匹配正则表达式,大小写敏感;
(4) ~*:匹配正则表达式,大小写不敏感;
优先级:(1)> (2) > (3) = (4)
location 区段匹配示例
location = / {
# 只匹配 / 的查询.
[ configuration A ]
}
location / {
# 匹配任何以 / 开始的查询,但是正则表达式与一些较长的字符串将被首先匹配。
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开始的查询并且停止搜索,不检查正则表达式。
[ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配任何以gif, jpg, or jpeg结尾的文件,但是所有 /images/ 目录的请求将在Configuration C中处理。
[ configuration D ]
}
各请求的处理如下例:
/ → configuration A
/documents/document.html → configuration B
/images/1.gif → configuration C
/documents/1.jpg → configuration D
4、root 、alias 指令区别
location /img/ {
alias /var/www/image/;
}
#若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/var/www/image/目录找文件
location /img/ {
root /var/www/image;
}
#若按照这种配置的话,则访问/img/目录下的文件时,nginx会去/var/www/image/img/目录下找文件。]
- alias 是一个目录别名的定义,
- root 则是最上层目录的定义。
- 还有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的,而root则可有可无