5.1 网页的状态页
基于nginx 模块 ngx_http_stub_status_module 实现,在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module,否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态
server{
listen 80;
server_name www.lucky.com;
root /data/html/;
location /admin {
auth_basic "welcome cxk";
#提示信息,不是所有浏览器都有用
auth_basic_user_file /mnt/.nginxuser;
#密码文件存放位置
}
location /status{
stub_status;
}
}
真机访问
#状态页用于输出nginx的基本状态信息:
#输出信息示例:
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
上面三个数字分别对应accepts,handled,requests三个值
Reading: 6 Writing: 179 Waiting: 106
Active connections:
#当前处于活动状态的客户端连接数,包括连接等待空闲连接数=reading+writing+waiting
accepts:
#统计总值,Nginx自启动后已经接受的客户端请求的总数。
handled:
#统计总值,Nginx自启动后已经处理完成的客户端请求总数,通常等于accepts,除非有因worker_connections限制等被拒绝的连接
requests:
#统计总值,Nginx自启动后客户端发来的总的请求数。
Reading:
#当前状态,正在读取客户端请求报文首部的连接的连接数,数值越大,说明排队现象严重,性能不足
Writing:
#当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明访问量很大
Waiting:
#当前状态,正在等待客户端发出请求的空闲连接数,开启 keep-alive的情况下,这个值等于active – (reading+writing)
提取数字学习下
还没有结束,报错
配置文件
验证
5.2 Nginx 第三方模块
5.2.1 ehco 模块
开源的echo模块 GitHub - openresty/echo-nginx-module: An Nginx module for bringing the power of "echo", "sleep", "time" and more to Nginx's config file
[root@mcb-11-9 conf.d]#vim pc.conf
server{
listen 80;
server_name www.mcb.com;
root /data/;
location /ip {
echo "welcome your ip addr: ";
echo $remote_addr;
}
}
①修改子配置文件
②依赖nginx编译echo模块
[root@mcb-11-9 conf.d]#cd /opt/
[root@mvb-11-9 opt]#unzip echo-nginx-module-master.zip
[root@mcb-11-9 opt]#cd nginx-1.18.0/
[root@mcb-11-9 nginx-1.18.0]#systemctl stop nginx
[root@mcb-11-9 nginx-1.18.0]#./configure --help | grep add
[root@mcb-11-9 nginx-1.18.0]#nginx -V
[root@mcb-11-9 nginx-1.18.0]#./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/opt/echo-nginx-module-master
[root@mcb-11-9 nginx-1.18.0]#make && make install
[root@mcb-11-9 nginx-1.18.0]# systemctl start nginx
③添加echo模块后检查语法会不会报错
④浏览页面
5.3 变量
官方文档 http://nginx.org/en/docs/varindex.html
5.3.1 常用内置变量
$remote_addr;
#存放了客户端的地址,注意是客户端的公网IP
$proxy_add_x_forwarded_for
#此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔,如果请求中没有X-Forwarded-For,就使用$remote_addrthe “X-Forwarded-For” client request header field with the $remote_addr variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable.
客户机 代理1 代理2 nginx服务器
$proxy_add_x_forwarded_for: 在代理1 上存的是 客户机的ip
$proxy_add_x_forwarded_for: 在代理2 上存的是 客户机的ip,代理1的ip 用逗号隔开
$proxy_add_x_forwarded_for: nginx 上存的是 客户机的ip,代理1的ip,代理2的ip
$args;
#变量中存放了URL中的参数,例如:http://www.kgc.org/main/index.do?id=20190221&partner=search
#返回结果为: id=20190221&partner=search 存放的就是这个
select * from table where id=20190221
$document_root;
#保存了针对当前资源的请求的系统根目录,例如:/apps/nginx/html
$document_uri;
#保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比
如:http://www.kgc.org/main/index.do?id=20190221&partner=search会被定义为/main/index.do
#返回结果为:/main/index.do
$host;
#存放了请求的host名称
limit_rate 10240;
echo $limit_rate;
#如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
$remote_port;
#客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
$remote_user;
#已经经过Auth Basic Module验证的用户名
$request_body_file;
#做反向代理时发给后端服务器的本地资源的名称
$request_method;
#请求资源的方式,GET/PUT/DELETE等
$request_filename;
#当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径,如:/apps/nginx/html/main/index.html
$request_uri; https:// www.baidu.com/main/index.do?id=20190221&partner=search
#包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args,例如:/main/index.do?id=20190221&partner=search
$scheme;
#请求的协议,例如:http,https,ftp等
$server_protocol;
#保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr;
#保存了服务器的IP地址
$server_name;
#请求的服务器的主机名
$server_port; 443 https
#请求的服务器的端口号
$http_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段
arbitrary request header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores
#用下划线代替横线
#示例: echo $http_User_Agent;
$http_user_agent;
#客户端浏览器的详细信息
$http_cookie;
#客户端的cookie信息
$cookie_<name>
#name为任意请求报文首部字部cookie的key名
$http_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有
横线需要替换为下划线
arbitrary request header field; the last part of a variable name is the field
name converted to lower case with dashes replaced by underscores #用下划线代替横线
#示例:
echo $http_user_agent;
echo $http_host;
$sent_http_<name>
#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有问题
echo $sent_http_server;
$arg_<name>
#此变量存放了URL中的指定参数,name为请求url中指定的参数
#对比 变量 $arg 是全部, 如果 要id 如下
echo $arg_id;
实验:变量
server{
listen 80;
server_name www.lucky.com;
root /data/;
location /ip {
echo "welcome,your ip addr: ";
echo $remote_addr;
}
location /main {
index index.html;
default_type text/html;
echo "hello world,main-->";
echo $remote_addr;
echo $args;
echo $arg_user;
echo $document_root;
echo $document_uri;
echo $host;
echo $http_user_agent;
echo $http_cookie;
echo $request_filename;
echo $scheme;
echo $scheme://$host$document_uri?$args;
}
}
① 修改配置文件
②测试验证
正向代理:代理的是客户端
反向代理:代理的是服务端
反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。
总结
$proxy_add_x_forwarded_for 实现ip 透传,记录每一个地址
#此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔,如果请求中没有X-Forwarded-For,就使用$remote_addrthe “X-Forwarded-For” client request header field with the $remote_addr variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable.
客户机 代理1 代理2 nginx服务器
$proxy_add_x_forwarded_for: 在代理1 上存的是 客户机的ip
$proxy_add_x_forwarded_for: 在代理2 上存的是 客户机的ip,代理1的ip 用逗号隔开
$proxy_add_x_forwarded_for: nginx 上存的是 客户机的ip,代理1的ip,代理2的ip
$http_user_agent; 客户端浏览器的详细信息
$server_addr; 服务器的IP地址
$scheme; 请求的协议 例如:http,https,ftp等
$http_cookie; 客户端的缓存信息 缓存:cookie和session
$server_protocol; 你使用的协议的版本
$document_root; 指明了主站点目录的位置
#保存了针对当前资源的请求的系统根目录, 例如:/apps/nginx/html
5.3.2自定义变量
假如需要自定义变量名称和值,使用指令set $variable value;
语法格式:
Syntax: set $variable value;
Default: —
Context: server, location, if #可以放置的位置
修改配置文本
server {
listen 80;
location /test {
set $name Coco;
echo $name;
set $my_port $server_port;
echo $my_port;
}
}
另一台虚拟机访问
5.3.3自定义图标
favicon.ico 文件是浏览器收藏网址时显示的图标,当客户端使用浏览器问页面时,浏览器会自己主动发起请求获取页面的favicon.ico文件,但是当浏览器请求的favicon.ico文件不存在时,服务器会记录404日志,而且浏览器也会显示404报错
【自定义小图标】
wget www.baidu.com/favicon.ico
放到主目录就可以了,不生效可以重新打开浏览器
实验前
先确保下载位置一致
实验:定义百度图表
[root@mcb-11-9 conf.d]#weget www.baidu.com/favicon.ico
[root@mcb-11-9 conf.d]#ls
favicon.ico pc.conf
[root@mcb-11-9 conf.d]#cd /data
[root@mcb-11-9 data]#ls
ABC about error.log favicon.ico html
[root@mcb-11-9 conf.d]#cp favicon.ico /data/
检验
实验:定义京东图标
注意:要把百度logo删除,影响结果
[root@mcb-11-9 data]#rm -rf favicon.ico
[root@mcb-11-9 data]#wget www.jd.com/favicon.ico
[root@mcb-11-9 data]#ls
ABC about error.log favicon.ico html
5.4 自定义访问日志
如果访问出错---404,可以去看日志信息#cat /apps/nginx/logs/error.log
5.4.1日志的格式 可以自由指定
访问日志是记录客户端即用户的具体请求内容信息,而在全局配置模块中的error_log是记录nginx服务器运行时的日志保存路径和记录日志的level,因此两者是不同的,而且Nginx的错误日志一般只有一个,但是访问日志可以在不同server中定义多个,定义一个日志需要使用access_log指定日志的保存路径,使用log_format指定日志的格式,格式中定义要保存的具体日志内容
Syntax: access_log path [format [buffer=size] [gzip[=level]] (flush=time] [if=condition]];access_log off;
Defau1t:
access_log 1ogs/access.1og combined;
Context: http,server, location,if in location,limit_except
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$server_name:$server_port';
log_format test '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$server_name:$server_port';
格式可以定义多个
###注意如果开启 include 注意定义自配置文件与 日志格式的上下关系 , 日志格式一定要在 include 之前 否则会不生效。
注意nginx子配置文件开启 include 注意定义子配置文件与 日志格式的上下关系 ,日志格式一定要在 include 之前 否则会不生效。
修改主配置文件,添加自定义格式
查看日志内容变化
此时可以看到最后多了服务端的ip地址
[root@mcb-11-9 ~]# vim /apps/nginx/conf/nginx.conf
log_format mcb '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$host"';
access_log logs/access.log mcb; #可以定义多个变量,最后指定使用
#复制模板,最后添加新调用变量
5.4.2自定义 json 格式日志
方便ELK收集日志
log_format access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';
①配置文件
②浏览器访问一下
③看日志 tailf /apps/nginx/logs/access.log
③日志分割
nginx的日志是生成在安装目录下/usr/local/nginx/logs中,大量的日志如果不做良好的管理,长此以往会造成日志文件过大且日志分析困难
vim /opt/fenge.sh
#!/bin/bash
# Filename: fenge.sh
day=$(date -d "-1 day" "+%Y%m%d") #显示前一天的时间
logs_path="/var/log/nginx"
pid_path="/usr/local/nginx/logs/nginx.pid"
[ -d $logs_path ] || mkdir -p $logs_path #创建日志文件目录
mv /usr/local/nginx/logs/access.log ${logs_path}/kgc.com-access.log-$day #移动并重命名日志文件
kill -USR1 $(cat $pid_path) #重建新日志文件
find $logs_path -mtime +30 -exec rm -rf {} \; #删除30天之前的日志文件
#find $logs_path -mtime +30 | xargs rm -rf
chmod +x /opt/fenge.sh
/opt/fenge.sh
ls /var/log/nginx
ls /usr/local/nginx/logs/access.log
#设置周期计划任务
crontab -e
0 1 * * * /opt/fenge.sh
编写日志分割的脚本
#!/bin/bash
#this is used for cutting nginx logs
##定义日志收集的目录
newlogpath=/var/log/nginx
##定义区分日志的标识,采用时间标记,计划每天一次日志分割
lastday=`date -d "-1 day" +%Y%m%d`
##找到应用程序生成日志的源路径
oldlogpath=/usr/local/nginx/logs
##定义应用程序的pid号 也就是nginx的master进程号
pid=`cat ${oldlogpath}/nginx.pid`
##先判断收集日志的目录是否存在,没有则创建,有则进行下一步
[ -d $newlogpath ]||mkdir $newlogpath
##使用mv命令进行日志分割,将生成的访问日志和错误日志都移动到收集日志的目录下,并添加时间标记
mv $oldlogpath/access.log $newlogpath/access.log.$lastday
mv $oldlogpath/error.log $newlogpath/error.log.$lastday
##重新生成新的日志,便于nginx记录后续访问事务
kill -USR1 $pid
##删除大于30天的日志,释放磁盘空间
find $newlogpath -mtime +30 -exec rm -rf {} \;
chmod +x ~/nginx_log.sh
crontab -e
0 0 * * * ~/nginx_log.sh
面试题?
一键安装及脚本
日志分割
系统调优
自动检测系统性能
5.5 Nginx压缩功能
支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相应的CPU资源。
gzip不支持压缩图片
Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module,允许Nginx服务器将输出内容在发送客户端之前进行压缩,以节约网站带宽,提升用户的访问体验,默认已经安装,可在配置文件中加入相应的压缩功能参数对压缩性能进行优化
官方文档: Module ngx_http_gzip_module
配置指令如下:
#启用或禁用gzip压缩,默认关闭
gzip on | off;
#压缩比由低到高从1到9,默认为1
gzip_comp_level level;
#禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
#gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
#启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
#指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
#如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”,一般建议打开
gzip_vary on | off;
#预压缩,先压缩好,不用临时压缩,消耗cpu
gzip_static on | off;
实验1: gzip压缩
gzip on;
gzip_comp_level 9;
gzip_min_length 1k;
gzip_vary on;
gzip_static on;
注意:gzip压缩主文件必须添加access_json,否则日志不显示size
①拷贝大文件
②写配置文件
④curl 是文字浏览器不压缩,检测日志
③去浏览器访问:
点到空白处,鼠标右击,检查 或者按F12
304这里是缓存,再次强刷按ctrl进行出现 200就好了
favicon.ico表示的是网站的小图标,是不压缩的
实验2:开启预压缩
gzip on;
gzip_comp_level 9;
gzip_min_length 1k;
gzip_vary on;
gzip_static on;
[root@mcb-11-9 conf.d]#cat pc.conf
server {
listen 80;
root /data/;
gzip on; #开启gzip压缩
gzip_comp_level 9; #压缩级别为9
gzip_min_length 1k; #小于1k不压缩
gzip_static on; #添加首部信息
location / {
root /data;
}
}
google访问
笔记:gzip不支持压缩图片,curl不支持压缩
5.6 https 功能
Web网站的登录页面都是使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议,HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
过程:
1 客户端发起HTTPS请求
用户在浏览器里输入一个 https 网址,然后连接到服务器的 443 端口
2 服务端的配置
采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥
3 传送服务器的证书给客户端
证书里其实就是公钥,并且还包含了很多信息,如证书的颁发机构,过期时间等等
4 客户端解析验证服务器证书
这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如:颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框提示证书存在问题。如果证书没有问题,那么就生成一个随机值,然后用证书中公钥对该随机值进行非对称加密
5 客户端将加密信息传送服务器
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加感解密了
6 服务端解密信息
服务端将客户端发送过来的加密信息用服务器私钥解密后,得到了客户端传过来的随机值
7 服务器加密信息并发送信息
服务器将数据利用随机值进行对称加密,再发送给客户端
8 客户端接收并解密信息
客户端用之前生成的随机值解密服务段传过来的数据,于是获取了解密后的内容
nginx 的https 功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数--with-http_ssl_module开启
官方文档:
https://nginx.org/en/docs/http/ngx_http_ssl_module.html
ssl on | off;
#为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代
listen 443 ssl;
ssl_certificate /path/to/file;
#指向包含当前虚拟主机和CA的两个证书信息的文件,一般是crt文件
ssl_certificate_key /path/to/file;
#当前虚拟主机使用的私钥文件,一般是key文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
#支持ssl协议版本,早期为ssl现在是TLS,默认为后三个
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
#配置ssl缓存
off: #关闭缓存
none: #通知客户端支持ssl session cache,但实际不支持
builtin[:size]:#使用OpenSSL内建缓存,为每worker进程私有
[shared:name:size]:#在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称
ssl_session_timeout time;
#客户端连接可以复用ssl session cache中缓存的有效时长,默认5m
因为http是用明文传输的,只要抓包,直接获取你的用户名和密码,所以ssl很重要
没有结束,要动手做一些
自签名证书
#所有的证书需要放在一起不能移开
bash certificate.sh
cat kgc.com.crt ca.crt > www.kgc.com.crt
#kgc.com.crt(购买者)
#ca.crt(颁发者)
mv kgc.com.key www.kgc.com.key
#www.kgc.com.key(验证钥匙)
生成密钥的工具
证书查看 查看下京东的证书