Nginx
功能
反向代理
负载均衡
Nginx是一款性能优异且被当前社会企业广泛使用的网站服务器,它可以用来做网站服务器,也可以用来做服务的反向代理也能做邮箱服务器
优势
高并发,支持50K的并发数
IO多路复用
epoll模型
异步
非阻塞
Nginx安装
在官网http://nginx.org/中找到如下地址
进入documentation 文档链接,找到安装nginx的文档
我们要安装在linux上,点击linux下的packages
找到安装介绍下的安装在红帽/centos的介绍
如下就是文档中介绍的内容
Install the prerequisites: (安装前提,下载yum-utils工具)
sudo yum install yum-utils
To set up the yum repository, create the file named /etc/yum.repos.d/nginx.repo
with the following contents: (去设置yum的仓库,创建一个文件名称为“/etc/yum.repos.d/nginx.repo
” 的文件,文件内容如下:)
如下参数介绍
[xxx] :被中括号包裹的是源的名称,这个名称是这个源的标识
name:软件仓库的名称,一般是用于阅读配置文件时使用,一般无作用。
baseurl:配置的镜像服务器地址,可以设置较快的服务器下载地址,可配置多个地址
enabled:表示在这个 repo 定义的源是否使用,0表示禁用;1表示使用。
在如下配置用
nginx-stable(稳定版)是处于使用状态的
nginx-mainline(主线版/开发版)是处于禁用状态的
gpgcheck :用于下载时的安全校验,保证下载的rpm源是安全有效的,1为开启
gpgkey : 校验用的公钥来源地址
module_hotfixes:模块的热修复
[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
By default, the repository for stable nginx packages is used. If you would like to use mainline nginx packages, run the following command: (默认的,将会下载仓库中稳定版本的nginx,如果你想要使用开发版本的nginx包,你可以运行如下命令:)
其实,这个命令就是将上面配置的nginx-mainline repo 的enable属性改为一,你也可以直接修改配置文件做到。如果你没有安装yum-utils这个工具包,如下命令是不能执行的。
sudo yum-config-manager --enable nginx-mainline
To install nginx, run the following command: (安装nginx,运行如下命令)
sudo yum install nginx
如此,nginx就安装成功了,你可以将其运行起来并且设置为开机自启动
systemctl start nginx systemctl enable nginx #查看nginx版本 nginx -v
nginx的配置文件
可以通过如下命令查看nginx的配置文件列表
常见的rpm -ql /qa/qi/qf XX 的使用
rpm -ql 包名:查看一个包下安装了哪些文件(用此查看nginx安装的文件)
rpm -qf 文件 : 查看一个文件是由那个包安装的
rpm -qi 包名 : 查看一个包的详细信息
rpm -qa: 查看系统安装了哪些包
rpm -ql nginx
所有配置信息
/etc/logrotate.d/nginx #做日志轮转 /etc/nginx/nginx.conf #总配置文件 /etc/nginx #配置文件目录 /etc/nginx/conf.d #子配置文件目录 /etc/nginx/conf.d/default.conf #nginx默认网站配置文件 /etc/nginx/fastcgi_params #动态网站模块文件-python \php所需要的相关变量 /etc/nginx/scgi_params #动态网站模块文件 /etc/nginx/uwsgi_params #动态网站模块文件 /etc/nginx/mime.types # 文件关联程序 ; 网站文件类型和相关处理程序 /etc/nginx/modules # 模块文件夹,主要用于放置下载的第三方nginx模块 /usr/lib/.build-id /usr/lib/.build-id/67 /usr/lib/.build-id/67/c8f0b978321a26716c8f572e1f56996c0193d7 /usr/lib/.build-id/d9 /usr/lib/.build-id/d9/ee5f1926ae5bc2e397d6ae6f2aac082b5350ea /usr/lib/systemd/system/nginx-debug.service #nginx调式程序启动 /usr/lib/systemd/system/nginx.service #服务脚本 /usr/lib64/nginx #nginx系统模块目录 /usr/lib64/nginx/modules /usr/libexec/initscripts/legacy-actions/nginx /usr/libexec/initscripts/legacy-actions/nginx/check-reload /usr/libexec/initscripts/legacy-actions/nginx/upgrade /usr/sbin/nginx #主程序 /usr/sbin/nginx-debug #调试文件 #帮助文档文件 /usr/share/doc/nginx-1.20.2 /usr/share/doc/nginx-1.20.2/COPYRIGHT /usr/share/man/man8/nginx.8.gz /usr/share/nginx /usr/share/nginx/html /usr/share/nginx/html/50x.html /usr/share/nginx/html/index.html /var/cache/nginx #缓存 /var/log/nginx #日志文件夹
🐤 /etc/logrotate.d/nginx #做日志轮转
🐤 /etc/nginx/nginx.conf #nginx的总配置文件
🐤 /etc/nginx/conf.d #子配置文件夹(一般配网站信息,配子配置文件即可)
🐤 /etc/nginx/conf.d/default.conf # nginx默认网站配置文件
✒️ /etc/logrotate.d/nginx
/etc/logrotate.d 目录是包安装之后创建的日志轮转文件,例如docker、nginx等都会在这个文件夹下创建自身的日志轮转文件。
查看该文件下的信息
>ls /etc/logrotate.d/
bootlog chrony firewalld nginx samba syslog
btmp dnf kvm_stat psacct sssd wtmp
内容详解
daily : 以天为时间单位
。。。。。之后会讲
[root@iZbp16o0v29fi6s8yin962Z ~]# vim /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
✒️ /etc/nginx/mime.types 文件关联程序映射文件
网站文件类型和相关处理程序之间的映射
内容如下
左边程序,右边后缀名
[root@iZbp16o0v29fi6s8yin962Z ~]# cat /etc/nginx/mime.types
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
。。。。。。
}
编译参数
查看编译参数
nginx -V
content:
# nginx -V
nginx version: nginx/1.20.2
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: #配置参数 ./configuration -help查看帮助
--prefix=/etc/nginx #安装路径
--sbin-path=/usr/sbin/nginx #指定执行程序存放的位置
--modules-path=/usr/lib64/nginx/modules #模块路径
--conf-path=/etc/nginx/nginx.conf #主程序位置
--error-log-path=/var/log/nginx/error.log #错误文件位置
--http-log-path=/var/log/nginx/access.log #访问记录文件位置
--pid-path=/var/run/nginx.pid #程序PID
--lock-path=/var/run/nginx.lock #锁路径,防止重复启动nginx
--http-client-body-temp-path=/var/cache/nginx/client_temp #用户代理缓存位置
--http-proxy-temp-path=/var/cache/nginx/proxy_temp #代理缓存
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp #php缓存
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp #python缓存
--http-scgi-temp-path=/var/cache/nginx/scgi_temp
--user= nginx #linux用户
--group=nginx #用户组
--with-compat #启动动态模块兼容性
--with-file-aio #aio,提高性能
--with-threads #多线程模块
--with-http_addition_module #响应之前或之后追加的文本内容,例如想在站点底部追加信息等等
--with-http_auth_request_module #认证模块,用于访问控制
--with-http_dav_module #增加上传下载等,默认关闭
--with-http_flv_module #田间MP3、4 flv支持模块
--with-http_gunzip_module #压缩模块
--with-http_gzip_static_module #另一种压缩模块
--with-http_mp4_module #多媒体模块
--with-http_random_index_module #随机主页模块
--with-http_realip_module #获取真实ip模块
--with-http_secure_link_module #安全连接模块,提供安全下载
--with-http_slice_module #中文文档
--with-http_ssl_module #网站加密模块,安全模块
--with-http_stub_status_module #访问状态
--with-http_sub_module #替换网站响应内容
--with-http_v2_module #web2.0技术模块
--with-mail #邮件客户端
--wimail_ssl_module
--with-stream #负载均衡模块
--with-stream_realip_module
--with-stream_ssl_module
--with-stream_ssl_preread_module
#cpu的优化参数
--with-cc-opt='-O2 -g -pipe -Wall -Werror =format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat -hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fPIC'
--with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
补充:nginx的aio
例如图片网站的特点是大量的读io操作,aio不用等待每一次io的结果,可以处理其他io的请求操作,这样可以大大的提高nginx性能与并发数。
aio的特点是能够提交多个io请求给内核,然会交由内核的io调度算法处理这些请求。内核就有可能执行一些合并,节约读取文件的处理时间。
aio是异步非阻塞io
nginx基本配置
主配置文件
🐤 分类
- CoreMudule核心模块(进程数等)
- EventsMudule 事件驱动模块(工作模式等)
- HTTPCoreModule (http内核模块)【文档程序类型,配置文件等】
🐤 特点
🌵 全局/核心模块
该模块下的配置信息将影响nginx下的所有指令。
🌵事件驱动模块
配置影响nginx的服务器与用户网络的连接数。主要可以配置,每个进程的最大连接数,选择哪种事件驱动模型处理连接请求;是否允许同时接收多个网络连接;开启多个网络连接序列化等。
🌵http内核模块
可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。
server模块
配置虚主机的相关参数,一个http可以有多个server
location模块
配置请求的路由,以及各种页面的处理情况
🐤 content介绍
#核心模块,全局配置
user nginx; #使用linux用户账户
worker_processes auto; #进程数,可以设置为与cpu的数量相同
error_log /var/log/nginx/error.log notice; #错误日志位置
pid /var/run/nginx.pid; #nginx的进程PID ,可以查看/var/run/nginx.pid查看,nginx启动时创建文件
events {
worker_connections 1024; #同时为1024个用户服务
}
http {
include /etc/nginx/mime.types; #应用程序与文件的映射文件
default_type application/octet-stream; #应用程序流,默认以字节流方式处理
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; #日志格式 main
access_log /var/log/nginx/access.log main; #访问记录日志位置以及日志格式
sendfile on; #加速nginx访问
#tcp_nopush on; #优化nginx方法
keepalive_timeout 65; #连接超时时间
#gzip on; #是否压缩
include /etc/nginx/conf.d/*.conf; #子配置文件
}
默认子配置文件
/etc/nginx/conf.d目录是用来存放服务的配置文件,只要在这个目录下,且文件名以**.conf**结尾的文件都能被nginx识别并加载
🚫 在老版本中,是没有默认配置文件的,而是将默认子配置文件中的数据存放在主配置文件的http中。
🐤 文件位置与名称
/etc/nginx/conf.d/default.conf
🐤 文件内容
server { #虚拟主机配置
listen 80; #服务的端口
server_name localhost; #服务域名
#access_log /var/log/nginx/host.access.log main; #网站日志存放位置,不指定默认存放位置
location / { #网站的网页根目录映射的本地目录以及文件
root /usr/share/nginx/html; #网站根
index index.html index.htm; #网站首页文件名
}
#error_page 404 /404.html; #错误
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html; #错误页面,500系列的
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
🐤 创建一个网站
🌵 在/etc/nginx/conf.d下创建一个虚拟主机配置
vim /etc/nginx/conf.d/Jankin.conf
🌵 内容如下
server{
listen 8001;
server_name Jankin.com;
location / {
root /Jankin_web;
index index.html;
}
}
🌵 创建/Jankin_web目录
mkdir /Jankin_web
🌵 随便创建一个index
echo "welcome to jankin web" > /Jankin_web/index.html
🌵 重启nginx
systemctl restart nginx
🌵开放linux 8001端口,访问测试。
日志
日志配置
日志模块的名称
ngx_http_log_module
🐤相关的指令
🌵 log_format(日志格式)
🌾 nginx的主配置文件中就定义了nginx的日志记录格式,内容如下:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
🌾 默认的访问日志记录位置与文件
access_log /var/log/nginx/access.log main; #使用的是main格式
113.68.48.228 - - [17/Dec/2021:15:36:59 +0800] "GET /1.html HTTP/1.1" 404 153 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0" "-"
113.68.48.228 - - [17/Dec/2021:15:37:03 +0800] "GET /1.html HTTP/1.1" 200 4 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0" "-"
文件内容
🌾 nginx有灵活的日志记录模式
🌾 日志记录中允许的配置变量
$remote_addr #远程地址,用于记录客户端ip地址 113.68.48.228
$remote_user #远程用户 ,匿名访问(用户身份认证)
$time_local #本地时间 ,[17/Dec/2021:15:36:59 +0800]
$request #请求信息 ,GET /1.html HTTP/1.1 记录请求的url和HTTP协议,当前访问的根页面 /1.html
$status #请求状态码 404 200
$body_bytes_sent #响应的文件大小,字节数 153 4
$http_referer #记录从哪一个页面中链接访问过来的 "-" 来源,当直接访问的为 -
$http_user_agent # 记录客户端浏览器相关信息 "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0"
$http_x_forwarded_for # 代理IP
#补充
$request_length #请求的长度(行、头、体)
$request_time #请求处理的时间,单位秒,精度毫秒。从读取请求的第一个字节开始,开响应最后一个字节结束
$time_iso8601 #iso8601标准下的本地时间
$bytes_send #发送给客户端的总字节数
$mssec #日志写入时间,单位秒
扩展:HTTP状态码
🌵 error_log
给自定义网站自定义404页面
server{
listen 8001;
server_name Jankin.com;
location / {
root /Jankin_web;
index index.html;
}
error_page 404 /404.html;
location = /404.html {
root /Jankin_web;
}
}
🐤 日志缓存
用户每访问一次网站,就要执行打开日志文件 - 输入日志信息 - 关闭日志信息 ,而这操作是很消耗的且与业务无关。
可以使用open_log_file_cache来设置.默认禁用,不建议开,占内存。
可以通过一个命令来开启
open_log_file_cache max=1000 inactive=20s min_uses=3 valid=1m;
#max 1000 指的是日志的FD , 最大的缓存数量为1000.
#min_usrs=3 20秒内少于三次的FD,就进行清除,结合inactive 20s的时间
#valid=1m 检查周期为1分钟
#总结,缓存最多1000 FD,到了极限,每分钟进行清除(20秒访问小于3次)的fd
日志轮转
nginx默认安装并开启了日志轮转
使用命令查看
rpm -ql nginx | grep log
content:
[root@iZbp16o0v29fi6s8yin962Z Jankin_web]# rpm -ql nginx | grep log
/etc/logrotate.d/nginx #日志轮转配置文件
/var/log/nginx #日志记录文件目录
/etc/logrotate.d/nginx 文件内容
/var/log/nginx/*.log { #此次轮转针对的日志文件, 只要是以.log结尾的文件都进行切换
daily # 以天为单位
missingok # 丢失不提示
rotate 52 #保留52天的数据
compress #压缩
delaycompress #延迟压缩
notifempty #空文件不轮转
create 640 nginx adm #nginx 在切割之后创建的新的日志文件的权限为640
sharedscripts #
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid` #切割后重启nginx服务
fi
endscript
}
日志分析
🐤 使用awk分析日志文件信息
🌵 前置知识
⏰ 什么是AWK?
AWK是一种处理文本文件的语言,主要用于文本的分析。其名称是由三位缔造者的首字母拼接。
⏰ AWK中有几个比较常用点分别为
$0表示整行
$n 表示一行中的某一列(列按空格区分,也可以指定分隔符)
FS : 列的分割符,默认为空格
BEGIN{。。。} 执行前的语句
{。。。}执行时的语句
END {。。。}执行后的语句
awk -v # 设置变量
awk -v jankin = "aaa"
⏰ 以下是一些例子
awk正则
# 输出第二列包含 "th",并打印第二列与第四列
$ awk '$2 ~ /th/ {print $2,$4}' log.txt
# 输出包含 "re" 的行
$ awk '/re/ ' log.txt
cat test.txt #这是一个文本文件,每个字段用空格隔开
this is my test dome
1 2 3 4 5
a b s d f g
cat test2.txt #这是一个文本文件,每个字段用-隔开
this-is-my-test-demo
1-2-3-4-5
a--b-x-c-s
awk '{print $1,$4}' test.txt #获取每一行的第一个与第4个字段,默认以空格分割字段
this test
1 4
a d
awk -F- '{print $1,$4}' test2.txt #获取每一行的第一个与第4个字段,默认以"-"分割字段
this test
1 4
a x
⏰ 编写awk脚本,文件以.awk为后缀名
脚本内容
#执行前调用
BEGIN{
print "------------BEFORE-----------"
}
#执行时,文件有多少行循环多少次
{
print "-------------print-----------"
print "当前行的第一个字段($1):"$1 ;
print "命令行中当前文件的位置:" ARGIND;
print "当前文件名(FILENAME):" FILENAME;
print "文件计数的行号(FNR):" FNR;
print "字段分隔符(FS):" FS;
print "一条记录的字段数目(NF):" NF;
print "已经读出的记录数,就是行号,从一开始(NR)" NR;
print "-------------------------------\n\n"
}
#执行结束调用
END{
print "------------END---------------"
}
⏰使用test2.txt测试
测试命令
# -f 脚本文件名
#-F 字段分隔符使用 “-”
#将被分析的文件test2.txt
awk -F- -f myAWKDemo.awk test2.txt
输出
------------BEFORE-----------
-------------print-----------
当前行的第一个字段($1):this
命令行中当前文件的位置:1
当前文件名(FILENAME):test.txt
文件计数的行号(FNR):1
字段分隔符(FS):
一条记录的字段数目(NF):5
已经读出的记录数,就是行号,从一开始(NR)1
-------------------------------
-------------print-----------
当前行的第一个字段($1):1
命令行中当前文件的位置:1
当前文件名(FILENAME):test.txt
文件计数的行号(FNR):2
字段分隔符(FS):
一条记录的字段数目(NF):5
已经读出的记录数,就是行号,从一开始(NR)2
-------------------------------
-------------print-----------
当前行的第一个字段($1):a
命令行中当前文件的位置:1
当前文件名(FILENAME):test.txt
文件计数的行号(FNR):3
字段分隔符(FS):
一条记录的字段数目(NF):6
已经读出的记录数,就是行号,从一开始(NR)3
-------------------------------
------------END---------------
⏰ linux相关命令
wc #统计
grep #过滤
cat #查看文件
sort -kn -rn #排序 -kn 表示第几列 例如 -k1为第一列 -rn表示倒叙,不写默认升序
head -n 10 #获取前10行
date #调用系统时间
date -d '-1 minute' +%Y:%H:%M #当前时间的前一分钟
🌵 开始分析日志
nginx的网站日志信息是放在/var/log/nginx/下,且默认使用的访问日志文件名为access.log,默认使用的错误访问日志文件名为error.log ,且每天都会进行日志轮转创建新的日志文件,文件名为xxx.log-YYYYMMDD
通过上面的日志字段的介绍,我们可以对日志的信息进行相应的分析
eg:分析指定时间段网站的PV量
注:PV 、UV 、IP均是网站统计专业名词
PV (page view) 访问量 一天内页面被访问的次数
UP(Unique visitor)用户访问数 一天内用户访问的数量(一个用户被记录一次)
IP 独立IP数 一天内独立IP访问网站的数量(一个IP被记录一次)
分析:我们知道默认访问日志的第四个字段为用户访问网站时的系统时间
awk '{print $4}' access.log
#output
[18/Dec/2021:03:33:10
[18/Dec/2021:03:35:41
[18/Dec/2021:03:37:31
[18/Dec/2021:04:18:09
#...
此时,我们可以通过awk运算符来过滤我们需要的时间段信息
在通过wc -l 统计条数
eg :统计当天在15点到17点的用户访问PV
awk '$4 >= "[18/Dec/2021:15:00:00" && $4 <= "[18/Dec/2021:17:00:00" {print $0} ' access.log | wc -l
统计各客户端ip在15到17点之间访问网站的次数并倒叙排序
注:ips为数组变量
awk '$4 >= "[18/Dec/2021:15:00:00" && $4 <= "[18/Dec/2021:17:00:00" {print $0} ' access.log | awk '{ips[$1]++} END{for(i in ips){print "ip: " i " 次数: " ips[i]}}' | sort -k4 -rn
统计各客户端ip在15到17点之间访问网站的次数大于等于2次的ip并倒叙排序
awk '$4 >= "[18/Dec/2021:15:00:00" && $4 <= "[18/Dec/2021:17:00:00" {print $0} ' access.log | awk '{ips[$1]++} END{for(i in ips){if(ips[i] >=2 )print "ip: " i " 次数: " ips[i]}}' | sort -k4 -rn
分析当天被用户访问最多的页面
#先获取每行日志中被访问的地址
#默认日志格式中,一行第七个字段为被访问的url
>awk '{print $7 }' access.log | head -n3
http://azenv.net/
/
/actuator/health
统计命令
awk '{size[$7]++} END{for(i in size){print "被访问页面: "i" 访问次数: "size[i]}}' access.log | sort -k4 -rn
连接状态
nginx提供查看实时的连接数的状态模块:http_stub_status_module
查看是否安装了该模块
nginx -V 2>&1 | grep stub_status
给服务开启该模块
打开网站子配置文件Jankin.conf
vim /etc/nginx/conf.d/Jankin.conf
#content
server{
listen 8001;
server_name Jankin.com;
location / {
root /Jankin_web;
index index.html;
}
location /stub_stataus { #连接路径
stub_status; #开启连接状态监控模块
allow all; #允许访问的权限,在此允许所有
}
error_page 404 /404.html;
location = /404.html {
root /Jankin_web;
}
}
修改了配置文件,重启nginx服务
systemctl restart nginx
查看效果
Active connections :当前连接数(TCP 三次握手 ,四次挥手为一次连接)
accepts 连接数 handled 处理数 request 请求数
请求是相对于http讲的,而连接是相对于传输层而言的。
什么是Keepalived?
一般请求来说,只要请求到的资源客户端已经接收或者是服务器端已经处理,那么就进行4次挥手断开连接,但是长连接通信是“三次握手处理请求后并不挥手,而是一直建立着连接。保留着连接。”
但是,长连接对服务器的压力较大。连接一直保持着,数量堆积,消耗资源。
nginx的keepalived长连接设置
一般http守护进程都可以设置http-alived-timeout超时参数,例如nginx的keepalived_timeout 和apache的keepAliveTimeout。即服务器处理完客户机发送过的请求后等待执行时间,在指定时间过去后没有请求过来,就进行4次挥手断开连接。而这个指定时间就是keepalivedtimeout
nginx设置的长连接超时时间在nginx的主配置文件中设置的时间是65秒,我们可以自己设置,单位秒。
配置信息如下:
随机主页模块
网站的不停机更新。微更新模块:random_index_module
random_index_module的目的是为了为网站提供一种微调更新机制,将页面设置为随机页面。
使用方法:
创建多个版本的页面。给页面添加一些内容。
touch /Jankin_web/{a.html,b.html,c.html,d.html,.f.html}
设置随机主页,在网站配置信息中,设置如下配置:
location / {
root /Jankin_web/index_page;
#index index.html;
random_index on;
}
替换模块
sub_module的目的是为了提供一种快速替换服务器内容的一种实现。
一个网站的网页若用模板来生成的,例如使用freemaker生成的静态页面,而若是生成后的页面的效果不如意,但因为文件数量庞大,不方便全部重新生成。就可以使用此模块来实现暂时的纠错,除此之外,还可以使用这个模块来实现文字的过滤功能。
文件正常情况
文件非正常情况,使用替换模块进行临时的处理
缺点
- 客户每请求一次错误文件,服务器就要修改一次,服务器压力增大。
- 临时改动,错误的页面并没被修改。也可以认为是临时的遮掩。
使用
模拟,将默认首页的nginx的词换成Jankin
修改默认网站的子配置文件,内容:
server {
listen 80;
server_name localhost;
#将网站中的存在nginx单词替换成Jankin
sub_filter nginx "Jankin";
#是否只换一次,关闭
sub_filter_once off;
#...
因为修改了配置,需要重启nginx服务
systemctl restart nginx
访问测试(可能存在浏览器缓存页面)
文件读取模块
ngx_http_core_module
该模块下相关的命令
sendfile on/off --> default = on :
作用:加速系统内核传输或拷贝文件过程。
传统的文件传输过程:
硬盘 > 内核空间(buffer) > 用户空间 > 内核 socket 空间 > 协议栈
未开启sendFile的传统文件传输过程
开启了sendfile的文件传输过程
磁盘 > 内核空间 > socket
减少了系统状态切换的次数,也减少了文件拷贝的次数
sendfile默认是开启的,在nginx.conf中
[root@iZbp16o0v29fi6s8yin962Z index_page]# cat /etc/nginx/nginx.conf | grep "sendfile"
sendfile on;
**tcp_nopush on/off --> default = off
tcp_nopush默认关闭,在nginx.conf中查看
[root@iZbp16o0v29fi6s8yin962Z index_page]# cat /etc/nginx/nginx.conf | grep "tcp_nopush "
#tcp_nopush on;
一个数据的发送,需要经过 应用层 > 传输层 > 网络层 > 数据链路层 > 物理层 的成层封装之后才能进行发送。
应用程序每产生一次数据发送操作就会产生一个发送数据包(数据通过iso模型封装),而典型的情况是,数据量才1byte,而封装的包信息却有40byte,这就产生了4000%的过载,很容易就令网络发生拥堵,同时浪费支援。
过载:数据量远远大于实际可操作量。
网络拥堵: 因某种原因使网络中的通信量超过了它的传送能力时出现的状态。为了避免拥挤,要对网络的信息流量进行控制,否则容易造成网络信息吞吐能力下降,甚至导致网络瘫痪
tcp_nopush目的是当数据量达到一定大小后再发送,即延迟(等待)一定时间后再发送。
**tcp_nodelay on/off --> default = off **
该选项只在将连接转变为长连接时才会被启用。
禁用Nagle算法,即将数据包立即发送出去
当收到信息后,会给发送方发送一个ACK(确认包),当发送方再等待时间内收到ACK后将不会触发重传,若没有收到则,发送方会认为接收方没有收到数据,将会触发重传机制。
而我们开启onpush之后,因为延迟了发送,当然也延迟了ack包的发送,这样,就很有可能在发送时已经超过了发送方的重传检测时间。
所以,若开启了onpush ,一般打开nodelay ,使得ack的确认包立即发出,避免发送方重传。
文件压缩
nginx在传输文件之前先将文件进行压缩,压缩后才将文件进行发送提高传输的效率
压缩模块:ngx_http_gzip_module
语法
gzip on | off > default off
模块的开启与关闭
gzip_comp_level level(1-9) > default 1
压缩级别
gzip_http_version 1.0|1.1 > default 1.1
压缩版本
使用
http {
gzip on; #开启gzip
gzip_disable "msie6"; #IE6不使用gzip
gzip_vary on; #设置为on会在Header里增加 "Vary: Accept-Encoding"
gzip_proxied any; #代理结果数据的压缩
gzip_comp_level 6; #gzip压缩比(1~9),越小压缩效果越差,但是越大处理越慢,所以一般取中间值
gzip_buffers 16 8k; #获取多少内存用于缓存压缩结果
gzip_http_version 1.1; #识别http协议的版本
gzip_min_length 1k; #设置允许压缩的页面最小字节数,超过1k的文件会被压缩
gzip_types text/html application/javascript text/css; #对特定的MIME类型生效,js和css文件会被压缩
未开启前的首页访问传输
开启压缩后的首页传输
页面缓存
ngx_http_headers_module
expired 的作用主要用于控制页面的缓存,用于减轻服务端的压力。
语法
expired time;
expired epoch | max | off >> default off
缓存默认是关闭的,因为缓存的弊端在于其时效性,若对实时的更新有要求,那么缓存就不适合使用。
操作服务器的缓存开启与关闭
启动服务器缓存模块
server{
listen 8001;
server_name Jankin.com;
location / {
root /Jankin_web;
index index.html;
#random_index on;
#buffer 24h
expires 24h;
}
#。。。
测试
防盗链
启用网站的防盗链功能
location / {
root /Jankin_web;
index index.html;
#锁住所有资源 server_name书写白名单
valid_referers none blocked *.Jankin.com server_name Jankin.com ;
if ($invalid_referer) { #判断是否禁止访问,若是,返回403
return 403;
}
#buffer 24h
expires 24h;
}
白名单访问正常 200
防盗链访问
访问限制
网络中有一种攻击叫做“泛洪攻击”
SYN攻击利用的是TCP的三次握手机制,攻击端利用伪造的IP地址向被攻击端发出请求,而被攻击端发出的响应报文将永远发送不到目的地,那么被攻击端在等待关闭这个连接的过程中消耗了资源,如果有成千上万的这种连接,主机资源将被耗尽,从而达到攻击的目的。 ----节选自《百度百科》
泛洪攻击图例
防护
第一道防御:硬件防火墙
第二道防御:依靠网络的安全产品 eg CDN(内容分发网络)、火绒等将
第三道防御: 通过服务器工具抵御一定的攻击
访问限制模块
ngx_http_limit_req_module:限制请求
ngx_http_limit_conn_module:限制连接
通过压力测试工具,进行服务器压测
yum install -y httpd-tools #该包有一款叫ab的压测工具
ab -n 100 -c 10 http://tianyun.me/ # -n 请求数量 -c并发级别 ,命令含义 : 发送100次请求,分10次并发发送到http://tianyun.me/
测试结果
#前三行介绍的是这款工具的介绍信息
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
#开始测试 Jankin.com网站
Benchmarking Jankin.com (be patient).....done
#服务器使用的软件 nginx/1.20.2
Server Software: nginx/1.20.2
#服务器使用的域名Jankin.com
Server Hostname: Jankin.com
#服务器使用的端口号:80
Server Port: 80
#测试的文档地址:根目录 /
Document Path: /
#请求的文档大小为671 bytes
Document Length: 671 bytes
#并发的级别 为10级,命令中自己设置的
Concurrency Level: 10
#总共花费时间为 0.025秒
Time taken for tests: 0.025 seconds
#完成的请求次数 100
Complete requests: 100
#失败的请求次数 0
Failed requests: 0
#传递的总字节数
Total transferred: 81600 bytes
#传递的html页面总字节数
HTML transferred: 67100 bytes
#服务器每秒的可完成的请求数推测
Requests per second: 4010.91 [#/sec] (mean)
#一次请求完成的时间
Time per request: 2.493 [ms] (mean)
#在所有并发中,一次请求的时间
Time per request: 0.249 [ms] (mean, across all concurrent requests)
#传输率
Transfer rate: 3196.19 [Kbytes/sec] received
#连接的时间信息
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 0
Processing: 0 2 0.3 2 4
Waiting: 0 2 0.2 2 2
Total: 1 2 0.3 2 4
#在特定时间内服务的请求的百分比
Percentage of the requests served within a certain time (ms)
50% 2
66% 2
75% 2
80% 2
90% 2
95% 2
98% 4
99% 4
100% 4 (longest request)
限制请求:ngx_http_limit_req_module
定义
#限制请求,二进制地址,限制策略的名称,占用的空间,允许每秒请求次数
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
#$binary_remote_addr 以二进制记录请求的远程地址
#zone=req_zone:10m 给设置的限制起一个名称,调用时可直接使用名称调用,记录远程地址的空间限制为10M
#rate=1r/s; 限制速度 : 1次/秒(一秒内只能请求一次)
一个ipv4的地址,能占用4bytes,10M的存储空间能存储将近250万的IP地址
引用
limit_req zone=req_zone;
操作
#在主配置文件的http模块中定义限制请求的规则 nginx.conf
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#定义限制
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=1r/s;
access_log /var/log/nginx/access.log main;
#在网站子配置中使用限制规则 default.conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
#限制请求
limit_req zone=req_limit;
}
再次进行压测,结果
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking Jankin.com (be patient).....done
Server Software: nginx/1.20.2
Server Hostname: Jankin.com
Server Port: 80
Document Path: /
Document Length: 671 bytes
Concurrency Level: 10
Time taken for tests: 0.014 seconds
Complete requests: 100
Failed requests: 99 #失败了99次,只成功了一次
(Connect: 0, Receive: 0, Length: 99, Exceptions: 0)
Non-2xx responses: 99
Total transferred: 64770 bytes
HTML transferred: 49676 bytes
Requests per second: 7330.30 [#/sec] (mean)
Time per request: 1.364 [ms] (mean)
Time per request: 0.136 [ms] (mean, across all concurrent requests)
Transfer rate: 4636.56 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 0
Processing: 1 1 0.1 1 2
Waiting: 1 1 0.1 1 1
Total: 1 1 0.1 1 2
Percentage of the requests served within a certain time (ms)
50% 1
66% 1
75% 1
80% 1
90% 1
95% 1
98% 1
99% 2
100% 2 (longest request)
查看服务错误日志
[root@iZbp16o0v29fi6s8yin962Z ~]# tail -n 3 /var/log/nginx/error.log
2021/12/20 09:58:16 [error] 169039#169039: *98 limiting requests, excess: 0.988 by zone "req_limit", client: 127.0.0.1, server: default_nginx_web.com, request: "GET / HTTP/1.0", host: "Jankin.com"
2021/12/20 09:58:16 [error] 169039#169039: *99 limiting requests, excess: 0.988 by zone "req_limit", client: 127.0.0.1, server: default_nginx_web.com, request: "GET / HTTP/1.0", host: "Jankin.com"
#在2021/12/20 09:58:16的时候出现了错误,原因是出现了第100次限制请求,限制规则为req_limit , 被限制的远程客户端 127.0.0.1 ,服务网站域名为default_nginx_web.com 请求是get请求,端口是Jankin.com:80端口
2021/12/20 09:58:16 [error] 169039#169039: *100 limiting requests, excess: 0.988 by zone "req_limit", client: 127.0.0.1, server: default_nginx_web.com, request: "GET / HTTP/1.0", host: "Jankin.com"
限制链接:ngx_http_limit_conn_module
目的:通过id地址,限制链接(TCP),实验环境无法测试
定义
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
使用
limit_conn conn=conn_limit 1; #每个IP每次只允许一个链接
扩展:网站的压测工具
ab
webbench
Siege
http_load
访问控制
控制访问的两种方式
1、基于主机(IP):封杀IP
2、基于用户(username&&password)
**基于IP控制模块:ngx_http_access_module **
指令
黑白名单
allow : IP白名单
deny : IP黑名单
使用
allow address | CIDR | unix: | all;
适用范围
http \ server \ location \ limit_except
操作
#设置主机号为127.0.0.1的IP访问根目录为黑名单,在网站子配置中配置 default.conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
allow 113.68.220.169;
deny all;
#限制请求
limit_req zone=req_limit;
}
使用压测工具测试
his is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking Jankin.com (be patient).....done
Server Software: nginx/1.20.2
Server Hostname: Jankin.com
Server Port: 80
Document Path: /
Document Length: 154 bytes
Concurrency Level: 1
Time taken for tests: 0.002 seconds
Complete requests: 5
Failed requests: 0 #均被控制
Non-2xx responses: 5
Total transferred: 1530 bytes
HTML transferred: 770 bytes
Requests per second: 2821.67 [#/sec] (mean)
Time per request: 0.354 [ms] (mean)
Time per request: 0.354 [ms] (mean, across all concurrent requests)
Transfer rate: 843.19 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 0 0 0.5 0 1
Waiting: 0 0 0.5 0 1
Total: 0 0 0.5 0 1
Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 1
90% 1
95% 1
98% 1
99% 1
100% 1 (longest request)
错误日志
2021/12/20 10:50:00 [error] 169316#169316: *5 access forbidden by rule, client: 127.0.0.1, server: default_nginx_web.com, request: "GET / HTTP/1.0", host: "Jankin.com"
用户控制:ngx_http_auth_module
指定
auth_basic String | off; #将账户名密码写在命令的后面
auth_basic_user_file file; #将用户名与密码的信息存放在文件中,模块去文件中查询
使用httpd-tools创建加密访问用户信息文件
[root@iZbp16o0v29fi6s8yin962Z ~]# htpasswd -cm /etc/nginx/conf.d/passwd user1
New password:
Re-type new password:
Adding password for user user1
[root@iZbp16o0v29fi6s8yin962Z ~]# cat /etc/nginx/conf.d/passwd
user1:$apr1$YW.kPrA.$u7z57kRVppL52b5oLYD1j1
#创建第二个用户
[root@iZbp16o0v29fi6s8yin962Z ~]# htpasswd -m /etc/nginx/conf.d/passwd user2 #命令中不要加-cm 因为已经存在文件,而m表示加密
New password:
Re-type new password:
Adding password for user user2
[root@iZbp16o0v29fi6s8yin962Z ~]# cat /etc/nginx/conf.d/passwd
user1:$apr1$YW.kPrA.$u7z57kRVppL52b5oLYD1j1
user2:$apr1$ZlTxEgEO$RTZOGPbWO2j9ZiPeLVp7C0
在默认网站中配置用户访问控制
server {
listen 80;
server_name default_nginx_web.com;
#将网站中的存在nginx单词替换成Jankin
sub_filter nginx "Jankin";
#是否只换一次,关闭
sub_filter_once off;
allow 113.68.220.169;
auth_basic "用户认证";
auth_basic_user_file /etc/nginx/conf.d/passwd;
deny all;
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 0 0 0.5 0 1
Waiting: 0 0 0.5 0 1
Total: 0 0 0.5 0 1
Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 1
90% 1
95% 1
98% 1
99% 1
100% 1 (longest request)
**错误日志**
```bash
2021/12/20 10:50:00 [error] 169316#169316: *5 access forbidden by rule, client: 127.0.0.1, server: default_nginx_web.com, request: "GET / HTTP/1.0", host: "Jankin.com"
用户控制:ngx_http_auth_module
指定
auth_basic String | off; #将账户名密码写在命令的后面
auth_basic_user_file file; #将用户名与密码的信息存放在文件中,模块去文件中查询
使用httpd-tools创建加密访问用户信息文件
[root@iZbp16o0v29fi6s8yin962Z ~]# htpasswd -cm /etc/nginx/conf.d/passwd user1
New password:
Re-type new password:
Adding password for user user1
[root@iZbp16o0v29fi6s8yin962Z ~]# cat /etc/nginx/conf.d/passwd
user1:$apr1$YW.kPrA.$u7z57kRVppL52b5oLYD1j1
#创建第二个用户
[root@iZbp16o0v29fi6s8yin962Z ~]# htpasswd -m /etc/nginx/conf.d/passwd user2 #命令中不要加-cm 因为已经存在文件,而m表示加密
New password:
Re-type new password:
Adding password for user user2
[root@iZbp16o0v29fi6s8yin962Z ~]# cat /etc/nginx/conf.d/passwd
user1:$apr1$YW.kPrA.$u7z57kRVppL52b5oLYD1j1
user2:$apr1$ZlTxEgEO$RTZOGPbWO2j9ZiPeLVp7C0
在默认网站中配置用户访问控制
server {
listen 80;
server_name default_nginx_web.com;
#将网站中的存在nginx单词替换成Jankin
sub_filter nginx "Jankin";
#是否只换一次,关闭
sub_filter_once off;
allow 113.68.220.169;
auth_basic "用户认证";
auth_basic_user_file /etc/nginx/conf.d/passwd;
deny all;