Nginx进阶-配置提升(上)

Nginx进阶-配置提升(上)_第1张图片

Nginx预定义变量

1、配置位置

无所谓配置位置,七层代理层和业务逻辑层上都可以配置使用。

2、已定义的变量

Nginx 本身提供了很多变量,这些变量可供我们在日志记录、rewrite规则编写、及更高级的LUA脚 本中去使用。

这些Nginx 本身已定义的变量,来自于Nginx的各个模块。比如我们在"防盗链"中提到的变量 $invalid_referer

就来自于ngx_http_referer_module 模块提供。但更多的变量的定义还是来自于 ngx_http_core_module 这个模块。今天我们简单的列举一些常用的变量:

$args : 这个变量等于请求行中的参数,同$query_string
$content_length : 请求头中的Content-length字段。
$content_type : 请求头中的Content-Type字段。
$document_root : 当前请求在root指令中指定的值。
$host : 请求主机头字段,否则为服务器名称。
$http_user_agent : 客户端agent信息
$http_cookie : 客户端cookie信息
$limit_rate : 这个变量可以限制连接速率。
$request_method : 客户端请求的动作,通常为GET或POST。
$remote_addr : 客户端的IP地址。
$remote_port : 客户端的端口。
$remote_user : 已经经过Auth Basic Module验证的用户名。
$request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme :HTTP方法(如http,https)。
$server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name : 服务器名称。
$server_port : 请求到达服务器的端口号。
$request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri : 与$uri相同。
...
...
更多的变量,我们可以通过产线官网:
http://nginx.org/en/docs/http/ngx_http_core_module.html#variables

3、如何使用已定义变量

那么多变量,有一些变量解释的甚至模棱两可。能否通过变量里具体的值去揣摩学习?
两种方法获取到变量的值:
1、将变量写到log_format 中,在下次访问的时候获取到变量里的值。
2、将变量写到add_header 中, 在下次访问的响应头中获取到变量的值。
比如:
add_header Test $uri;
这一就可以在下一次请求的响应头中看到Test头域。

4、如何获取到任意一个HTTP 头域

在Nginx中,定义了快速获取到请求头任何域的方式。方式如下:
$http_name,其中的name 为HTTP 的头域名。但头域中若包含"-", 则应该替换成"_"。 将所有大写转
换成小写。

获取 User-Agent, 那么应该写成:
$http_user_agent , 注意将"-" 变成"_" 的形式。
比如获取 Referer,应该写成:
$http_referer
同样,若有自定义头部 TEST ,怎么获取呢?
$http_test 即可

5、何获取到 cookie 值

Cookie信息,在HTTP字段中算是一个比较特殊的字段。 按照上面获取任何一个头域的方式,我们可以轻
易的通过$http_cookie获取到整个cookie 信息, 那要获取到cookie 中一个key 的值呢?
同样Nginx 也提供了类似于获取任意HTTP头域的方式。我们可以通过此方式可以获取到任意cookie中的
key值。
方式如下:
$cookie_name ,其中name 为cookie中的key值,这里的key值按照原先书写就可以了。不需要像获取
HTTP头域
那么复杂。

Nginx 日志详解

1、配置位置

无所谓配置位置了,七层代理层和业务逻辑层的Nginx都会遇到这样的问题。

2、日志问题

Nginx 本身有一套友好的记录访问日志功能。但默认的日志格式依然不是很理想,需要运维人员根 据自己的运维习惯,或者根据数据分析部门的要求对日志格式进行定义。

3、定义日志格式

如果浏览器访问虚机可以正常访问,日志状态码为404 ,可能是系统时间问题导致

# Nginx 的ngx_http_log_module 模块中log_format 指令,可以帮我们去完成自定义日志的格式。
log_format main '$http_x_real_ip $http_host [$time_local] "$request"
$request_length '
'$status $body_bytes_sent $request_time "$http_referer" '
'"$http_user_agent" $remote_addr ';

4、日志中每个字段的具体含义

$http_x_real_ip 记录客户端IP地址,通常使用$remote_addr, 这里结合负载均衡的配置获取真是的
客户端IP
$http_host 请求的域名
$time_local 通用日志格式下的本地时间。
$request 记录请求的URL和HTTP协议版本,及请求方式。 格式为"METHOD URL VERSION"
$request_length 请求的长度(包括请求行,请求头和请求正文)。
$status 记录请求状态,HTTP状态码。
$body_bytes_sent 发送给客户端的响应体大小,不包括响应头。
$http_referer 记录从哪个页面链接访问过来的
$http_user_agent 记录客户端浏览器相关信息
$remote_addr 远端服务器,到底是哪台代理服务器来的请求。

5、使用自定义日志格式

# 通过使用access_log 指令去指定访问日志时,指定使用的日志格式
access_log /var/log/access.log main;

6、Nginx 日志切割

若记录了Nginx 的access Log,最好能够按天对日志进行切割、压缩。这样做的好处有:

日志归档清晰

大量的日志也不会导致磁盘空间占满

若当天业务有问题,查询日志时不必从历史日志出发

Nginx 切割日志实例

#!/bin/bash
# 脚本功能
# 定期删除30天一天的归档日志。
# 可以通过crontab 在每天凌晨后执行, 执行后会将前一天的日志归档到 $LOGARCHIVE 变量指定的目
录中
# 可以留作业, 让学生改进成,每天归档后对日志进行压缩。以减少日志对磁盘的使用情况。
# 日志被 mv 走后, 对 Nginx 发送了 -USR1 信号, 重新打开日志文件。 这个在第一章中有介绍
# Nginx 日志存放目录
LOGDIR="/data0/www/logs"
# 一定要设置Nginx 的 access log 日志文件后缀名都为 -access_log
LOGSUFFIXA="*-access_log"
# 归档日志存放的目录
LOGARCHIVE="/data0/www/logs/archives"
# Nginx 的Pid 文件
PID="/usr/local/nginx/logs/nginx.pid"
# 删除 30天以前的日志
find $LOGARCHIVE -type f -atime +30 -exec rm -f {} \; > /dev/null 2>&1
# 删除空目录
find $LOGARCHIVE -type d -empty -exec rmdir {} \; >/dev/null 2>&1
# 获取前一天的时间
DATE=`date --date="LAST DAY" "+%y%m%d"`
# 创建前一天归档日志目录
LOGARCHIVE="$LOGARCHIVE/$DATE"
test -d $LOGARCHIVE || mkdir -p $LOGARCHIVE
cd $LOGDIR
for FILE in *$LOGSUFFIXA*; do
mv $FILE $LOGARCHIVE
done
# 发送 USR1 信号给Nginx, 让Nginx 重新打开日志文件。
kill -USR1 `cat ${PI

Nginx 升级

当我们使用的Nginx 版本存在BUG,亦或希望使用更高级的功能时。就有可能需要对我们目前使用 的Nginx 版本进行升级。那如何升级呢? 我们这里分为理想情况的升级,和实际工作中的升级去分析。

1、理想情况的升级

有可能你真的没有什么运维经验,将实际情况想象的过于复杂。网上看到的一切有关平滑升级的情 况没有问题,但基本上都是针对单点Nginx 去做的升级。而实际运维工作中,我们不可能让单点Nginx 服务存在。如果逼不得已真的存在,请按照下面的升级方案升级吧。

1)具体升级步骤

# 检查当前Nginx 版本
[[email protected] ~]# /usr/local/nginx/sbin/nginx -V
# 确保当前版本的nginx 是存活的
[[email protected] ~]# ps -ef |grep nginx
# 编译安装高版本Nginx
[[email protected] ~]# wget http://nginx.org/download/nginx-1.9.9.tar.gz
[[email protected] ~]# tar xf nginx-1.9.6.tar.gz
[[email protected] ~]# cd nginx-1.9.6
[[email protected] nginx-1.9.6]# ./configure --prefix=/usr/local/nginx/
[[email protected] nginx-1.9.6]# make
# 备份旧的nginx,一方面是等一下需要把新的nginx复制过来,另一方面的如果新的nginx有问题还可以
进行恢复
[[email protected] mv /usr/local/nginx/sbin/nginx{,.bak}
#把编译好的新的nginx文件服务到指定的安装目录中
[[email protected] nginx-1.9.6]# cp objs/nginx /usr/local/nginx/sbin/
# 检查高版本Nginx 对原有配置文件是否兼容
[[email protected] sbin]# /usr/local/nginx/sbin/nginx -t
#使用新版本的Nginx文件启动服务,之后平缓停止原有Nginx进程
[[email protected] nginx-1.9.6]# kill -USR2 `cat /nginx/logs/nginx.pid`
# 可以看到这里自动把之前的nginx.pid命名为nginx.pid.oldbin,并为新的nginx生成nginx.pid
[[email protected] nginx-1.9.6]# cd /nginx/logs/
nginx.pid nginx.pid.oldbin
#平缓停止旧服务的worker process
[[email protected] logs]# kill -WINCH `cat /nginx/logs/nginx.pid.oldbin`
# 检查是否升级成功
[[email protected] logs]# /usr/local/nginx/sbin/nginx -V
# 检查Nginx 进程是否存在
[[email protected] logs]# ps -aux |grep ngi

2、实际工作中的升级

在实际工作中,Nginx 服务不可能单点部署。我们往往面临的是一个Nginx 服务集群。再按照理想 的情况进行升级,就有些得不偿失了。那如何操作才能保证整个Nginx服务集群都升级OK呢? 可想而知,服务器集群的前端必有反向代理,反向代理对整个服务器集群是有健康检查的。如果健康检 查发现了某台服务器已经DOWN机,就会将机器从反向代理中摘除。这样就不会有生产环境的流量引 入。当健康检查检测到服务器UP后,会再将这台服务器添加到反向代理上,这之后生产流量才会引 入。因此在实际工作场景中,我们只需要关闭Nginx 服务、升级Nginx 软件包、启动Nginx服务即可。

1)具体升级步骤

关闭 Nginx 服务 /usr/local/nginx/sbin/nginx -s stop 或者 kill QUIT PID

升级 Nginx 二进制文件

启动Nginx 服务 /usr/local/nginx/sbin/nginx

注意,请将Nginx 的路径替换成真是的路径

Nginx 错误页个性化

当一个HTTP请求返回的状态码是404 、500、502 、504 等等错误的情况下,若没有做特殊配置, Nginx返回的是本身的默认错误页面。这样默认的错误页,对大众体验有可能是一个严重的耻辱。如果 我们能够针对这些状态码制定不同的友好提示页面那效果就理想多了。那如何配置这样的友好提示页面 呢?

1、本地配置个性化错误页面
修改自己的错误页面
2、当访问错误页面时由后端web服务器提供错误页面
实例:
192.168.28.129 web服务提供
修改错误页面:
vi /usr/share/nginx/html/50x.html
cuolecuole
vi /usr/share/nginx/html/404.html
我飞走了
192.168.28.128 proxy端
修改配置文件
server {
listen 80;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://192.168.28.129:80;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 256k;
}
########################
proxy_intercept_errors on;
error_page 500 502 503 504 404 = http://192.168.28.129:80/;
}
测试访问:
curl localhost/50x.html
curl localhost/404.html

访问控制

是否允许访问服务器资源, 这里提供三种方式: 针对IP的访问控制、使用访问控制模块进行访问控 制、使用用户名和密码进行访问控制。下面将分别进行介绍。

1、针对IP进行访问控制

# 当发现某个IP地址有恶意的访问行为时,我么可以针对这个IP地址进行封禁。 以达到访问控制。
# 但是要注意,你封禁的IP地址一定要是真是的客户端IP地址
if( $remote_addr = "1.1.1.1" ) {
return 403
}
if( $http_x_real_ip = "1.1.1.1" ) {
return 403
}
if( $http_x_forwarded_for = "1.1.1.1" ) {
return 403
}

2、使用访问控制模块进行访问控制

这是基于IP地址访问控制的另一种方式,使用Nginx 提供的访问控制模块 http_access_module 中 的功能

此模块本身支持IP地址,或者CIDR 网段形式的访问

# 黑名单的形式, 拒绝某个IP地址,允许其他所有访问
location = /admin.html {
deny 8.8.8.8;
allow all;
index index.html index.htm;
}
# 白名单的形式,运行某些访问,拒绝其他所有访问
location = /admin.html {
allow 192.168.100.0/24;
deny all;
index index.html index.htm;
}
# 注
# 使用 http_access_module 的局限性, http_access_module 模块获取客户端的IP地址是通过
# $remote_addr 去获取的。此时若我们的Nginx不能通过$remote_addr 获取真正的客户端IP地址,此
方法将失效。
# 我们可以在能够获取到真正客户端IP地址的负载均衡上进行配置。

3、使用用户名和密码进行访问控制

这是基于用户名和密码访问的一种方式, 使用Nginx 提供的访问控制模块 http_auth_basic_module 中的功能

1) 生产要访问的用户名和密码

[[email protected] ~]# yum -y install httpd-tools
[[email protected] ~]# htpasswd -c /data0/auth_conf testuser
New password:
Re-type new password:
Adding password for user testuser

2)配置认证信息

location = /admin.html {
auth_basic "Auth access test! input your password!";
auth_basic_user_file /data0/auth_conf;
index index.html index.htm;
}
# auth_basic 是提示信息指令
# auth_basic_user_file 对应的文件里存储用户名和密码信息

以上与大家分享的内容,如果需要学习教程、源码笔记的或者想学习交流,扫码加我拉你进群

Nginx进阶-配置提升(上)_第2张图片

你可能感兴趣的:(程序员,linux云计算,Nginx,云计算)