Nginx (engine x) 是一个高性能的HTTP(解决C10k的问题)和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。
高并发
IO多路复用
epoll
异步
非阻塞
第一种:最传统的多进程并发模型 (每进来一个新的I/O流会分配一个新的进程管理。)
第二种:I/O多路复用 (单个线程,通过记录跟踪每个I/O流(sock)的状态,来同时管理多个I/O流 。)
发明它的原因,是尽量多的提高服务器的吞吐能力。
在同一个线程里面, 通过拨开关的方式,来同时传输多个I/O流
select是第一个实现 (1983 左右在BSD里面实现的)。
select 被实现以后,很快就暴露出了很多问题。
• select 会修改传入的参数数组,这个对于一个需要调用很多次的函数,是非常不友好的。
• select 如果任何一个sock(I/O stream)出现了数据,select 仅仅会返回,但是并不会告诉你是那个sock上有数
据,于是你只能自己一个一个的找,10几个sock可能还好,要是几万的sock每次都找一遍…
• select 只能监视1024个链接。
• select 不是线程安全的,如果你把一个sock加入到select, 然后突然另外一个线程发现,这个sock不用,要收
回,这个select 不支持的,如果你丧心病狂的竟然关掉这个sock, select的标准行为是不可预测的
于是14年以后(1997年)一帮人又实现了poll, poll 修复了select的很多问题,比如
• poll 去掉了1024个链接的限制,于是要多少链接呢, 主人你开心就好。
• poll 从设计上来说,不再修改传入数组,不过这个要看你的平台了,所以行走江湖,还是小心为妙。
其实拖14年那么久也不是效率问题, 而是那个时代的硬件实在太弱,一台服务器处理1千多个链接简直就是神
一样的存在了,select很长段时间已经满足需求。
但是poll仍然不是线程安全的, 这就意味着,不管服务器有多强悍,你也只能在一个线程里面处理一组I/O流。
你当然可以那多进程来配合了,不过然后你就有了多进程的各种问题。
于是5年以后, 在2002, 大神 Davide Libenzi 实现了epoll.
epoll 可以说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题, 比如:
• epoll 现在是线程安全的。
• epoll 现在不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据,你不用自己去找了。
异步,非阻塞
$ pstree |grep nginx
|-+= 81666 root nginx: master process nginx
| |--- 82500 nobody nginx: worker process
| \--- 82501 nobody nginx: worker process
1个master进程,2个work进程
每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是异步回调。
CPU时钟/中断设计
ADSL
官方连接:Nginx
Mainline version: 主线版,即开发版
Stable version: 最新稳定版,生产环境上建议使用的版本
Legacy versions: 遗留的老版本的稳定版
下载安装包
创建文件
/etc/yum.repos.d/nginx.repo
配置nginx.repo
[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
默认开启最新版本,如果使用主线版本包,运行下面命令
sudo yum-config-manager --enable nginx-mainline
配置环境:getenforce
systemctl status firewalld
yum -y install nginx
systemctl start nginx
systemctl enable nginx
nginx -V 查看安装附带的功能模块
rpm -ql nginx
所有文件
/etc/logrotate.d/nginx
日志轮转
/etc/nginx/nginx.conf
总配置文件
/etc/nginx/conf.d
子配置文件
/etc/nginx/conf.d/default.conf
默认的网站配置文件
/etc/nginx/fastcgi_params 动态网站模块文件-python,php所需的相关变量
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/koi-utf 字符集,文件编码
/etc/nginx/win-utf
/etc/nginx/koi-win
/etc/nginx/mime.types 文件关联程序 网站文件类型 和 相关处理程序
/etc/nginx/modules 模块文件夹。第三方模块
/etc/sysconfig/nginx
# Configuration file for the nginx service.
NGINX=/usr/sbin/nginx
CONFFILE=/etc/nginx/nginx.conf
/etc/sysconfig/nginx-debug
# Configuration file for the nginx-debug service.
NGINX=/usr/sbin/nginx-debug
CONFFILE=/etc/nginx/nginx.conf
LOCKFILE=/var/lock/subsys/nginx-debug
/usr/lib/systemd/system/nginx-debug.service nginx调试程序启动脚本
`/usr/lib/systemd/system/nginx.service systemctl 服务脚本`
`/usr/sbin/nginx 主程序`
/usr/sbin/nginx-debug nginx调试程序
/usr/share/doc/nginx-1.12.1 文档
/usr/share/doc/nginx-1.12.1/COPYRIGHT
/usr/share/man/man8/nginx.8.gz man 手册
/usr/share/nginx
/usr/share/nginx/html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html 默认网页
/var/cache/nginx
各种缓存
ls /var/cache/nginx/
client_temp fastcgi_temp proxy_temp scgi_temp uwsgi_temp
/var/log/nginx
日志文件夹
ls /var/log/nginx/
access.log error.log
access.log error.log
Nginx 模块目录
nginx -V
nginx version: nginx/1.14.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: 配置参数./configure --help查询帮助
--prefix=/etc/nginx 安装路径
--sbin-path=/usr/sbin/nginx 程序文件
--modules-path=/usr/lib64/nginx/modules 模块路径
--conf-path=/etc/nginx/nginx.conf 主配置文件
1
2 user nginx; 运行nginx程序的独立账号
3 worker_processes 1; 启动的worker进程数量(cpu 数量一致或者auto)
4
5 error_log /var/log/nginx/error.log warn; 错误日志存放的位置
6 pid /var/run/nginx.pid;
7
8
9 events { 事件
#use epoll;#事件驱动模型epoll【默认】;
#事件驱动模型分类,select|poll|kqueue|epoll|resig|/dev/poll|eventport
10 worker_connections 1024; 每个worker进程允许处理的最大连接数,例如10240,65535
11 }
12
13
14 http {
15 include /etc/nginx/mime.types; 文档和程序关联记录
16 default_type application/octet-stream; 字节流处理方式
17 #日志格式 获取访问的地址,时间,·····
18 log_format main '$remote_addr - $remote_user [$time_local] "$request" '
19 '$status $body_bytes_sent "$http_referer" '
20 '"$http_user_agent" "$http_x_forwarded_for"';
21
22 access_log /var/log/nginx/access.log main;
23
24 sendfile on; #下图
25 #tcp_nopush on; #下图注释
26
27 keepalive_timeout 65; 优化参数, 长连接
28
29 #gzip on; 压缩参数
30
31 include /etc/nginx/conf.d/*.conf; 包含子配置文件夹
32
}
vim /etc/nginx/conf.d/default.conf
1 server { 默认网站配置文件
2 listen 80; 监听端口
3 server_name localhost; FQDN
4
5 #charset koi8-r; 网页字符类型
6 #access_log /var/log/nginx/host.access.log main; 日志
7
8 location / {
9 root /usr/share/nginx/html; 主目录
10 index index.html index.htm; 默认主页名
11 }
12
13 #error_page 404 /404.html; 错误页面
14
15 # redirect server error pages to the static page /50x.html
16 #
17 error_page 500 502 503 504 /50x.html; 错误页面
18 location = /50x.html { 错误页面
19 root /usr/share/nginx/html; 错误页面主目录
20 }
21
22 # proxy the PHP scripts to Apache listening on 127.0.0.1:80 代理设置
23 #
24 #location ~ \.php$ {
25 # proxy_pass http://127.0.0.1;
26 #}
27
28 # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 动态网站设置
29 #
30 #location ~ \.php$ {
31 # root html;
32 # fastcgi_pass 127.0.0.1:9000;
33 # fastcgi_index index.php;
34 # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
35 # include fastcgi_params;
36 #}
37
38 # deny access to .htaccess files, if Apache's document root 访问控制部分
39 # concurs with nginx's one
40 #
41 #location ~ /\.ht {
42 # deny all;
43 #}
44 }
45
创建文件
vim /etc/nginx/conf.d/xinjian.conf
server {
listen 80;
server_name xuleilinux.com;
location / {
root /xuleilinux;
index index.html ;
}
}
官方文档
日志模块名称 ngx_http_log_module
log_format 日志格式
access_log 访问日志
error_log
open_log_file_cache 日志缓存
log_format
简介
Nginx有非常灵活的日志记录模式。每个级别的配置可以有各自独立的访问日志。日志格式通过log_format命令定义。
语法
Syntax: log_format name [escape=default|json] string …;
name 表示格式名称
string 表示定义的格式
默认值
Default: log_format combined “…”;
log_format 有默认的无需设置的combined日志格式,相当于apache的combined日志格式
环境
Context: http context
定义设置位置
vim /etc/nginx/nginx.conf
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;
$remote_addr 远程地址:记录客服端IP地址
$remote_user 远程用户:记录客户端用户名
$[time_local] 本地时间:服务器自身时间
$request 请求:记录请求的URL和HTTP协议 “GET /1.html HTTP/1.1” “GET /index.html HTTP/1.1”
$staus 状态:记录请求状态
$body_bytes_sent 发送给客户端的字节数,不包括响应头的大小
$http_referer 记录从哪个页面链接访问过来的 (超链接)
$http_user_agent 记录客户端浏览器相关信息
$htttp_x_forwarded_for 代理IP
favicon.ico 文件是浏览器收藏网址时显示的图标,当第一次访问页面时,浏览器会自动发起请求获取页面的favicon.ico文件。当/favicon.ico文件不存在时,服务器会记录404日志。
127.0.0.1 - - [26/Jul/2015:22:25:07 +0800] “GET /favicon.ico HTTP/1.1” 404 168 “-” “Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:36.0) Gecko/20100101 Firefox/36.0” “-”
127.0.0.1 - - [26/Jul/2015:22:25:07 +0800] “GET /favicon.ico HTTP/1.1” 404 168 “-” “Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:36.0) Gecko/20100101 Firefox/36.0” “-“
当一个站点没有设置favicon.ico时,access.log会记录了大量favicon.ico 404信息。
这样有两个缺点:
1.使access.log文件变大,记录很多没有用的数据。
2.因为大部分是favicon.ico 404信息,当要查看信息时,会影响搜寻效率。
解决方法如下:
在nginx的配置中加入
location = /favicon.ico {
log_not_found off;
access_log off;
}
以上配置说明:
location = /favicon.ico 表示当访问/favicon.ico时,
log_not_found off 关闭日志
access_log off 不记录在access.log
完整配置如下:
server {
listen 80;
server_name fdipzone.com;
root /Users/fdipzone/home;
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log debug;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location / {
index index.html index.htm index.php;
include /usr/local/etc/nginx/conf.d/php-fpm;
}
}
tail -f /var/log/nginx/access.log
某条记录
192.168.100.254 - - [17/Dec/2017:14:45:59 +0800] "GET /nginx-logo.png HTTP/1.1" 200 368 "http://192.168.100.10/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0" "-"
含义
192.远程主机IP
- 分割符 用户
[2017] 系统本地时间
get 获得下载,还有post提交
/nginx-log.png 下载图片
http 版本
200 状态码,200成功
368 字节大小
http://192.168.100.10/ 来自访问链接
Mozilla/5.0 浏览器版本
Windows NT 6.1 客户端系统类型
error_log
404server{
error_page 404 /404.html;
location = /404.html {
root /xuleilinux;
}
}
systemctl restart nginx
vim /xuleilinux/404.html
访问不存在的页面
观察404页面现象
简介
大量访问到来时,对于每一条日志记录,都将是先打开文件,再写入日志,然后关闭.占用了系统的IO,与业务无关。
可以使用open_log_file_cache来设
Syntax
open_log_file_cache max=1000 inactive=20s min_uses=3 valid=1m ;
max 1000 指的是日志文件的FD,最大的缓存数量为1000。超了怎么办,看下面
min_users 3 20秒内小于3次访问的FD,就给你清掉,结合inactive 20s 的时间。
valid 1m 检查周期为1分钟。
总结:缓存最多1000个,到了极限,每分钟开始清除掉 20 秒内小于3次的文件FD.Default:open_log_file_cache off;
Context:http,server,locatition
http{} 将整个服务器所有网站,所有页面的日志进行缓存
server{} 将某一个网站的所有页面日志,进行缓存
location{}某一个页面的日志,进行缓存。
前言
Nginx安装,会默认启动日志轮转。
rpm -ql nginx | grep log
/etc/logrotate.d/nginx /var/log/nginx
查看
/etc/logrotate.d/nginx
/var/log/nginx/*.log { #待切割日志
2 daily #天
3 missingok #丢失不提示
4 rotate 52 #52份
5 compress #压缩
6 delaycompress #推迟压缩
7 notifempty #空文件的话,不转储
8 create 640 nginx adm #创建新的日志文件,属主
9 sharedscripts #轮转后脚本
10 postrotate
11 if [ -f /var/run/nginx.pid ]; then
12 kill -USR1 `cat /var/run/nginx.pid`
13 fi
USR1亦通常被用来告知应用程序重载配置文件;例如,向Apache HTTP服务器发送一个USR1信号将导致以下步骤的发 生:停止接受新的连接,等待当前连接停止,重新载入配置文件,重新打开日志文件,重启服务器,从而实现相对平滑的不关机的更改。
14 endscript
15 }
轮转语句
指令 /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
切割原理
1.cron 每小时呼唤一次anacron
vim /etc/cron.hourly/0anacron
2.anacrontab 以天,周,月循环往复vim /etc/anacrontab
3.天循环vim /etc/cron.daily/logrotate
4.立刻循环指令 /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status
5.anacron 当天的时间戳vim /var/spool/anacron/cron.daily
20180731
6.anacron循环后的时间戳vim /var/lib/logrotate/logrotate.status
"/var/log/nginx/host.404.log" 2017-11-19-0:8:56
根据该时间确定是否轮转。
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
[root@www ~]# cp /var/log/nginx/access.log /
[root@www ~]# ls /
access.log boot dev home lib64 mnt proc run srv tmp var yifan
bin defaultBackUp.conf etc lib media opt root sbin sys usr xuleilinux
#统计PV量
[root@www ~]awk '{print $1}' /access.log | wc -l
48
#7.1 11分访问的
[root@www ~] grep '01/Jul/2022:11' /access.log | wc -l
7
#统计11点到11:34 访问量
[root@www ~]awk '$4>="[01/Jul/2022:11:00:00]" && $4<="[01/Jul/2022:11:34:00]" {print $0}' /access.log |wc -l
6
#统计IP地址访问量,次数从高到低排列;sort 冒泡排列;-k2,对第二列值重新排列;-rn以相反顺序按从大到小排列
[root@www ~] grep '01/Jul/2022' /access.log | awk '{ ips[$1]++ } END{for(i in ips){print i,ips[i]} } '| sort -k2 -rn | head -n10
192.168.238.132 32
192.168.122.1 1
#统计7-1访问量大于10的IP
grep '01/Jul/2022' /access.log | awk '{ ips[$1]++ } END{for(i in ips){ if(ips[i]>10) {print i,ips[i]}} } '| sort -k2 -rn | head -n10
#统计访问页面最多的10个页面
[root@www ~]# grep '01/Jul/2022' /access.log | awk '{ urls[$7]++ } END{for(i in urls){ print urls[i],i}} '| sort -k2 -rn | head -n10
4 /1.html
26 /
1 /index.html
1 /.html
1 /favicon.ico
'统计访问链接的内容的大小()'
[root@xuleilinux ~]# grep '01/Jul/2022' /access.log | awk '{ urls[$7]++; size[$7]+=$10}END{for(i in urls){print urls[i],size[i],i}}'| sort -k1 -rn | head -n10
26 612 /
4 612 /1.html
1 612 /index.html
1 153 /.html
1 153 /favicon.ico
#统计每个IP访问访问状态码的数量
[root@xuleilinux ~]# grep '01/Jul/2022' /\access.log | awk '{ ip_code[$1" "$9]++}
END{ for(i in ip_code){print i,ip_code[i]} }' | sort -k1 -rn | head -n10
192.168.238.132 404 5
192.168.238.132 304 25
192.168.238.132 200 2
192.168.122.1 404 1
#每个IP访问状态码为404及出现的次数($status)
[root@xuleilinux ~]# grep '01/Jul/2022' /access.log | awk '{if($9=="404"){ip_code[$1" "$9]++}}
END{for(i in ip_code){print i,ip_code[i]}}'
192.168.238.132 404 5
192.168.122.1 404 1
#统计前一分钟的PV量
[root@xuleilinux ~]# date=$(date -d '-1 minute' +%Y:%H:%M); awk -v date=$date '$0 ~ date{i++}END{print i}' /access.log
#统计时间段8:30--9:00的IP,出现404状态的数量
[root@xuleilinux ~]# awk '$4>="[01/Jul/2022:08:30:00" &&
$4<="[01/Jul/2022:09:00:00"
{if($9=="404"){ip_code[$1" "$9]++}}
END{for(i in ip_code){print i,ip_code[i]}}' /access.log
192.168.238.132 404 7
192.168.122.1 404 1
#统计2022年7月1日 各种状态码数量
[root@xuleilinux ~]# grep '01/Jul/2022' /access.log | awk '{code[$9]++} END{for(i in code){print i,code[i]}}'
304 25
200 2
404 6
#百分比
[root@xuleilinux ~]# grep '01/Jul/2022' /access.log | awk '{code[$9]++;total++} END{for(i in code){printf i" ";printf code[i]"\t";printf "%.2f",code[i]/total*100;print "%"}}'
304 25 75.76%
200 2 6.06%
404 6 18.18%