1、INPUT和OUTPUT
INPUT和OUTPUT对应就是I/O模型
1.1 I/O模型
影响用户体验的因素,主要是:响应的速度,与I/O模型有关。
常见的I/O模型:
- 磁盘I/O:构建响应报文的速度,表示数据从内存回复到网卡的过程
- 网络I/O:接收发送的速度,表示数据从网卡到内存的过程,在 进程的 fd文件夹下形成了 一个临时文件 用来存储这次访问的基本信息
1.2 零拷贝技术(磁盘I/O)
方法一: 在内核空间 开辟一块共享空间,用户空间的程序,可以直接去共享空间进行处理,从而减少拷贝次数。
方法二: sendfile (调优)
sendfile 类似于软链接,作用是:减少内核态和用户态之间的拷贝次数,加快i/o速度。
1.3 网络I/O模型⭐⭐⭐
1.3.1 同步/异步
同步/异步(消息反馈机制):关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。
- 同步:nginx主动去问内核,是否完成了任务
- 异步:内核主动反馈给nginx交代的任务
1.3.2 阻塞/非阻塞(用的少!)
阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态
- 阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。完成之前只能接待一个请求!
- 非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。完成之前可以接待多个请求!
1.3.3 四种组合
- 同步阻塞:发起方主动去问 接收方是否完成任务;处理完成之前,接收方会被挂起,不会处理别的事情
- 同步非阻塞:发起方主动去问 接收方是否完成任务;处理完成之前,可以处理别的请求
- 异步阻塞:接收方主动给发起方反馈消息;处理完成之前,接收方会被挂起,不会处理别的事情
- 异步非阻塞:接收方主动给发起方反馈消息;处理完成之前,可以处理别的请求
变种:是目前主流,即多路复用模型
1.3.4 五个模型
- 阻塞性I/O模型:相当于 异步阻塞(最简单、基本不用!)
- 非阻塞I/O模型:相当于 同步非阻塞
- 多路复用I/O模型(能满足,足够用!)
- 信号驱动式I/O模型:效率高
- 异步I/O模型:相当于 异步非阻塞 效率高
1.4 epoll
nginx共有8种模型,默认选择的epoll模型。最常用的模型是前3种:
- select
- poll
- epoll
- rtsig
- kqueue
- /dev/poll
- eventport
- Iocp
select | poll | epoll | |
---|---|---|---|
操作方式 | 遍历 | 遍历 | 回调 |
底层实现 | 数组 | 链表 | 哈希表 |
IO效率 | 每次调用都仅从线性遍历,时间复杂度为O(n) | 同select | 时间复杂度O(1) |
最大连接数 | 1024(X86)、2048(X64) | 无上限 | 无上限 |
fd拷贝 | 每次调用select,都需要把fd集合,从用户态拷贝到内核态 | 每次调用poll,都要把fd集合,从用户态拷贝到内核态 | 调用epoll_ctl 时,拷贝进内核态并保存,之后每次epoll_wait不拷贝 |
- select 遍历
- poll 也是遍历,但是能用epoll就不用poll。
- epoll 回调,主动反馈。epoll 在fd里有报警机制。
select和epoll之间的区别:
epoll是poll的升级版,epoll只能在linux中使用,window中不支持epoll。
2、nginx概述
nginx架构:主程序master+子进程worker
- master:不干活,只接收请求,然后分配工作给worker
- worker:干活
2.1 yum安装nginx
`nginx和apache共用80端口`

yum install epel-release.noarch -y //先下载epel源
yum install nginx -y //yum安装
systemctl start nginx //开启nginx
小拓展:nginx安装后 启动失败,如何解决?:
- 报错信息:开启nginx时 报错
- 解决方法: 排查可能是80端口 被httpd所占,需要先关闭httpd,再重新打开nginx。
2.1.1 主进程和子进程
[root@7-1 ~]# pstree -p|grep nginx
|-nginx(10708)-+-nginx(10709)
| `-nginx(10710)
#自定义子进程数量:
[root@7-1 ~]# vim /etc/nginx/nginx.conf
# worker_processes auto; //注释第6行,auto是自动分配,基本上是1个cpu分配一个子进程worker。
worker_processes 1; //新增配置,自定义可以改成1,就只有一个子进程
[root@7-1 ~]# systemctl restart nginx
[root@7-1 ~]# pstree -p|grep nginx
|-nginx(10971)---nginx(10972)
2.2 nginx模块
- 核心模块
- 标准HTTP模块
- 可选HTTP模块
- 邮件服务模块
- stream服务模块
- 第三方模块
重点是 前三个模块
常用模块:
ngx_http_core_module 核心模块
ngx_http_access_module 访问控制 deny allow
ngx_http_auth_basic_module 身份验证
ngx_http_gzip_module 压缩模块
ngx_http_1og_module 日志模块
ngx_http_proxy_module 代理模块
ngx_http_rewrite_module 重写模块
ngx http_stub_status_module 状态页模块
ngx_http_upstream_module 反向代理
ngx_http_stream_module 四层代理
2.3 编译安装nginx
可以查看老师之前给的nginx脚本!!!
nginx版本:
看中间列,偶数是正式版,奇数是测试版:
编译安装nginx步骤:
#官网地址
https://nginx.org/en/download.html
#查看帮助模块
./configure --help
#关闭防火墙
systemctl stop firewalld
setenforce 0
#新建/data文件夹
mkdir /data
cd /data
#下载源码包
wget http://nginx.org/download/nginx-1.18.0.tar.gz
#解压软件包
tar xf nginx-1.18.0.tar.gz
cd nginx-1.18.0/
mkdir /apps/nginx -p
#安装依赖环境
yum -y install make gcc pcre-devel openssl-devel zlib-devel openssl openssl-devel
#检测环境,指定安装目录
./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
#编译
make -j2
make install
#建立软链接,下次输入nginx命令时,可以自动补全
ln -s /apps/nginx/sbin/nginx /usr/local/sbin
nginx #运行nginx
#新建nginx用户便于管理
useradd -M -s /sbin/nologin nginx
#修改权限
chown -R nginx.nginx /apps/nginx
ll /apps/nginx/
total 0
drwxr-xr-x 2 root root 333 Sep 22 12:49 conf
drwxr-xr-x 2 root root 40 Sep 22 12:49 html
drwxr-xr-x 2 root root 6 Sep 22 12:49 logs
drwxr-xr-x 2 root root 19 Sep 22 12:49 sbin
安装好,生成的四个文件功能如下:
- conf:保存nginx所有的配置文件
- html:目录中保存了nginx服务器的web文件
- logs:用来保存nginx服务器的访问日志错误日志等日志
- sbin:保存nginx二进制启动脚本
源码包内的文件:
- contrib:vim 格式文件,修改nginx配置文件的格式,
编译安装的高亮设置: cp -r /opt/nginx-1.18.0/contrib/vim/* /usr/share/vim/vimfiles/
- conf:配置文件
- man:man帮助 man man/nginx.8 不加路径看不了 nginx.8 文件
- src:源码包 点c 点h 结尾的文件 find src -type f |xargs cat |wc -l 193678
- objs:存储的是编译好的nginx文件
2.4 nginx信号⭐⭐
选项 | 含义 |
---|---|
-t | 检查语法格式 |
-T | 检查语法,并打印所有配置 |
-v | 显示版本 |
-V | 显示详细信息,包括编译的信息 |
-c | 指定配置文件位置,可以不用官方默认的文件,自己指定路径 |
-g | 单独指定配置,不以配置文件中的为准,但注意: 单独改之前,要先将配置文件里的注释掉,二者不能有冲突 |
-s | 发送信号,类似于kill |
-h | help帮助 |
2.4.1 检查语法格式 -t
[root@7-1 ~]# nginx -t //检查语法
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
2.4.2 显示版本 -v
[root@7-1 ~]# nginx -v
nginx version: nginx/1.20.1
2.4.3 指定配置指令 -g
例1:
[root@7-1 ~]# vim /apps/nginx/conf/nginx.conf //编辑配置文件
# worker_processes 4 //改配置之前,要将原配置文件中的注释掉,不能有冲突
[root@7-1 ~]# nginx -g "worker_processes 1" //worker_processes 1是配置文件选项,格式是:关键字+值
例2:
nginx -g “daemon off” //-g意思临时性的设定一次配置文件,不按照默认配置来,按照指定的要求来
小tips:nginx默认后台启动。
2.4.4 发送信号 -s
nginx -s reload 重新加载配置文件⭐⭐
nginx -s stop 停止nginx,并且立即停止
nginx -s quit 优雅的退出,有人访问,不会立即关闭,而是等对方结束后再退出。
nginx -s reopen 重新生成日志文件 等价于nginx -s USR1⭐⭐
nginx -s USR2 飞行中升级
nginx -s 与 kill命令对比:
nginx -s信号 | kill信号 | 含义 |
---|---|---|
nginx -s reload | kill -1(HUP) | 重新加载配置文件 |
nginx -s stop | kill -9 (KILL) | 立即退出 |
nginx -s quit | kill -3(QUIT) | 优雅的退出 |
nginx -s reopen | kill -USR1 | 重新生成日志 |
nginx -s USR2 | —— | 飞行中升级 |
2.5 nginx升级 USR2
实验目的:从nginx1.18.0版本,升级到nginx1.22.0版本
[root@7-1 ~]# cd /opt
[root@7-1 opt]# nginx -v
nginx version: nginx/1.18.0
[root@7-1 opt]# curl -I 192.168.125.100
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 31 May 2024 07:33:29 GMT
Content-Type: text/html
Content-Length: 4833
Last-Modified: Fri, 16 May 2014 15:12:48 GMT
Connection: keep-alive
ETag: "53762af0-12e1"
Accept-Ranges: bytes
[root@7-1 opt]# wget https://nginx.org/download/nginx-1.22.0.tar.gz -P /usr/local/src/ //下载1.22.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
make -j2
make //注意:千万不要make install!!!,不然就覆盖掉了!!!只输make的意思是:万一新版本安装的有问题,还可以还原回旧版本!!!
注意:老版本先不要删除,可以改个名字!!!然后新版本改成老版本改名之前的名字!!!这个时候nginx -v 会显示版本已变,但只是内存版本 变了,客户版本 并没有变化!!!最后使用飞行中升级:
cat nginx.pid
kill -s USR2 pid号
3、基本配置
nginx的配置文件的组成部分:
-
编译安装:
- 主配置:/apps/nginx/conf/nginx.conf
- 子配置:/apps/nginx/conf.d/
-
yum安装:
- 主配置:/etc/nginx/nginx.conf
- 子配置:/usr/share/nginx/
nginx指令组成部分:
- 全局配置(主配置)
- 模块配置
指令注意事项:
- nginx指令每条指令以 ;分号 结尾,指令与值之间以空格符号分隔
pid /apps/run/nginx.pid
指令 [空格] 值
-
部分指令需要放到指定位置,比如 alias别名指令,只能放到 location 模块
-
root 是主站点指令
-
参考官方文档:nginx.org.en.docs
syntax:指令的语法
default:指令的默认值
context:指令可以在哪些配置上下文中使用
3.1 全局配置 main
3.1.1 关闭版本或修改版本
server_tokens off ,注意是在httpd模块下修改,也是唯一 一个在httpd模块下的。
http {
server_tokens off;
nginx -s reload //重新加载
3.1.2 cpu与worker进程 绑定
cpu 的亲缘性,可以理解为cpu与nginx进程进行一 一对应,绑定在一起。
为什么要进行cpu与进程绑定?
当有多个cpu时,进程对应的cpu不是固定的,比如某进程第一次是在cpu1里面处理,第二次可能会在cpu2里面处理。这样就会形成,在cpu1产生的处理数据,cpu2里面是没有的,要从cpu1里面去拷贝,导致浪费资源、降低效率。
[root@7-1 ~]# ps axo pid,cmd,psr,|grep nginx //挑选3个字段,中间以逗号隔开
18620 nginx: master process /usr/ 2 0
18951 nginx: worker process 0 0
18952 nginx: worker process 1 0
18954 grep --color=auto nginx 2 0
#######绑定########
vim /etc/nginx/conf/nignx.conf
worker_cpu_affinity 00000001 00000010 00000100 00001000; //0-3个CPU,上限最多支持8个cpu
nginx -s reload
验证cpu乱跑可以刷新网页即可:
while true ;do ab -c 1000 -n 1000 http://192.168.125.100/;done //-c并发数量,-n总数量
小拓展:
安装压力测试工具:
yum install httpd-tools -y
3.1.3 进程优先级
nice 优先级:-20到19
worker_priority -20; //-20优先级最高
nginx -s reload
3.1.4 进程打开文件的数量⭐⭐⭐⭐⭐⭐
nginx 默认打开的 子进程数量 1024
修改进程打开的文件数量,分为两部分:
- nginx调优
worker_rlimit_nofile 65536;
- 系统调优
[root@localhost ~]#ulimit -a
[root@localhost ~]#ulimit -n 60000
3.1.5 服务是否以 后台方式运行
服务运行分为:前台运行、后台运行。一般都是后台运行,但在某些特殊场景,比如:docker容器,必须设置前台运行
daemon off //前台运行
3.1.6 只有主进程,没有子进程
一般是在测试环境中使用!!!实际生产中极少使用!!!因为主进程类似监工、子进程是干活的。
3.2 event 事件模块
i/o模型调优:
events {
worker_connections 65535; #设置单个工作进程的最大并发连接数
worker_rlimit_nofile; //总数量
use epoll; //event默认使用epoll
}
惊群效应:
accept_mutex on; //轮流派任务
multi_accept on; //同一时间可以处理多个请求
3.3 http设置⭐⭐⭐⭐⭐
格式:
-
http
-
server:主要是对主机的设置,比如:端口号、ip地址、域名、主站点、日志
- location:用来匹配url
-
// 注意:多个相同指令,内部的生效,比如在server和location里都有的话,location生效。
3.3.1 mime.types
格式里有的,就查看;没有的,就下载!
vim /etc/mime.types
小拓展:
nginx默认使用的是gzip压缩 但是,gzip压缩不压缩图片!图片压缩是前端的工作,运维压缩容易造成图片失真!可以寻求第三方软件!!!
3.3.2 listen 监听端口
监听sock 等于监听本机
listen 80; //设置监听地址和端口
注意:listen 80之间没有写IP地址的话,就是默认本机所有IP地址的80端口都监听。
一台机器可以有四块网卡,每块网卡对应一个IP地址。
3.3.3 域名
server_name www.wxj.org;
3.3.4 root
root指令 类似于追加
location /cxk {
root /data/cxk; //系统上的路径,相当于是/data/cxk/cxk/index.html
index index.html index.htm; //先找index.html,没有的话 再找index.htm
}
# error_page 404 /404.html; //两个都没有的话,就报错。
查看错误日志:
tail -f /apps/nginx/logs/error.log
3.3.5 虚拟主机(实验)⭐⭐⭐⭐
nginx 主配置文件里面内容太多,可以在子配置文件里面设置!
实验目的:用一台服务器做两个站点:电脑端和手机端
- 先在主配置文件中,设置子配置文件的路径:
[root@7-1 nginx]# vim /apps/nginx/conf/nginx.conf
http{
include /apps/nginx/conf.d/*.conf; //注意:不要忘记加结束符
[root@7-1 nginx]# cd /apps/nginx
[root@7-1 nginx]# mkdir conf.d
[root@7-1 nginx]# cd conf.d
[root@7-1 nginx]# nginx -s reload
- 设置电脑端:PC
[root@7-1 conf.d]# vim pc.conf
server {
listen 80;
server_name www.pc.com;
root /data/pc/;
}
[root@7-1 conf.d]# nginx -t
[root@7-1 conf.d]# nginx -s reload
- 设置手机端:iphone
[root@7-1 conf.d]# cp pc.conf iphone.conf
[root@7-1 conf.d]# vim iphone.conf
server {
listen 80;
server_name www.iphone.com;
root /data/iphone/;
}
[root@7-1 conf.d]# nginx -t
[root@7-1 conf.d]# nginx -s reload
- 新建文件及准备页面
[root@7-1 data]# cd pc
[root@7-1 pc]# echo "this is 电脑端PC" >index.html
[root@7-1 pc]# cd ..
[root@7-1 data]# cd iphone
[root@7-1 iphone]# echo "this is 手机端iphone" >index.html
- 对面服务器验证:
[root@7-2 ~]# vim /etc/hosts
192.168.125.100 www.pc.com www.iphone.com
[root@7-2 ~]# curl www.pc.com
this is 电脑端PC
[root@7-2 ~]# curl www.iphone.com
this is 手机端iphone //实验成功
3.3.6 alias 别名
location /cxk{
alias /data/; //访问/cxk等于访问/data
}
nginx -s reload
cd /data
echo data > index.html
最后,用对面的服务器去验证!
如果配置一模一样的话,优先级 按照字母顺序读取。
3.3.7 location 去匹配(重点中的重点)
#语法规则:
location [ = | ~ | ~* | ^~ ] url { ... }
匹配规则:
- 先看写法和含义,判断能不能匹配
- 再看优先级,判断具体匹配哪一个
3.3.7.1 五种写法及其含义
写法 | 样式 | 含义 |
---|---|---|
= | location = /cxk | 精确匹配,必须一模一样,一字不差,一旦匹配成功,就不会继续往下匹配 |
^~ | location ^~ /cxk | 以什么开头、(起始于什么),一旦匹配成功,就不会继续去找下面的正则表达式 |
~(波浪符) | location ~ /cxk | 开启正则,区分大小写 |
~* | location ~* /cxk | 开启正则,不区分大小写 |
不带符号 | location /cxk | 前面不加符号,也是起始于什么什么的意思,但是优先级最低 |
3.3.7.2 优先级
#匹配优先级从高到低:
=, ^~, ~/~*, 不带符号
3.3.7.3 不区分大小写案例
location ~* /A.?.jpg$ {
root /opt/nginx
}
/A.?.jpg$ 拆分:
/(第一个) :根
A.? :代表A后面的字符,出现0次或者1次
. :对点进行转义
jpg$ :以jpg结尾
示例:
######格式种空格有问题,复制要注意#######
location = /1.jpg {
root /data/nginx/static1;
index index.html;
}
location /1.jpg {
root /data/nginx/static2;
index index.html;
}
location ~* .(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js)$ {
root /data/nginx/static3;
index index.html;
}
[root@centos8 ~]# mkdir -p /data/nginx/static{1,2,3}
#上传图片到 /data/nginx/static{1,2,3} 并重启nginx访问测试
注意:不区分大小写,nginx系统不能识别。使用上述命令时,要准备一份小写文件、一份大写文件。
3.3.8 access 控制访问
控制访问 可以用两种方式:
- 用户名和密码
- 匹配IP地址
四层控制:网络层
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
deny all;
}
3.3.9 htpasswd
验证模块 需要输入用户名和密码
htpasswd -c 文件路径 姓名 交互式生成密码
htpasswd -bc 文件路径 姓名 密码 直接将密码跟在后面
-c 代表新建用户名和密码对应的文件
-b 将密码跟在用户名后
nginx没有自己的密码生成工具,要用apache的:
yum install httpd-tools -y