基础
I/O 模型
I/O 概述
- I/O 就是把数据从内核空间中的内存数据 复制到 用户空间进程的内存当中
I/O 分类
Linux 中的 I/O
- 磁盘 I/O
- 磁盘 I/O 是进程向内核发起的系统调用;
- 假设请求磁盘上的某个资源,比如说 html 文件或者图片:
- 内核会通过相应的驱动程序将目标文件加载到内核的内存空间,加载完成之后把数据从内核内存再复制给进程内存
- 网络 I/O
- 一切皆文件,本质就是对 socket 文件的读写
- 总结:
- 无论是磁盘I/O还是网络I/O,每次I/O都要经由两个阶段:
- 先将数据加载至内核内存空间(缓冲区),时间较长
- 然后将数据从内核缓冲区复制到用户空间进程的内存,时间较短
- 无论是磁盘I/O还是网络I/O,每次I/O都要经由两个阶段:
同步与异步
同步与异步 关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知
同步 synchronous;被调用者并不提供事件的处理结果相关的通知信息,需要被调用者主动询问事件是否处理完成
异步 asynchronous;被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态
阻塞与非阻塞
阻塞与非阻塞 关注调用者在等待结果返回之前所处的状态
阻塞 blocking;指IO操作需要彻底完成后才返回结果到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情
非阻塞 nonblocking;指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情
小结
**假设用水壶烧水这件事举例:**启动水壶后;
-
需要定期关注水是否烧开(同步),期间不能做其他事情(阻塞),这就是同步/阻塞。
-
需要定期关注水是否烧开(同步),期间可以去做别的事情(非阻塞),这就是同步/非阻塞。
-
水烧开后水壶会发出水烧开的信号来提醒我(异步),期间不能做其他事情(阻塞),这就是异步/阻塞。
-
水烧开后水壶会发出水烧开的信号来提醒我(异步),期间可以去做别的事情(非阻塞),这就是异步/非阻塞。
Nginx 概述
- nginx是一个性能优异的web服务器应用,并且还能提供强大的反向代理功能
为什么这么快
- epoll 模型
- 支持sendfile零复制技术
- 即将数据从磁盘中读出后进入内核空间后直接发送给soket缓存区,从而省略了user缓存这一步
特性
- 模块化设计、较好的扩展性
- 高可靠性
- 支持热部署:不停机更新配置文件、升级版本、更换日志文件等
- 低内存消耗:10000个kepp-alive连接模式下的非活动连接,消耗内存仅2.5M
- event-driven、aio、mmap、sendfile
处理机制
- 一个master进程带领多个worker进程进行数据处理
- master进程只负责将客户端请求调度到worker
- 真正进行数据处理的是worker进程
Apache VS Nginx
Nginx:
-
使用 epoll 模型
-
IO 多路复用,Epoll(freebsd 上是 kqueue)
-
高性能
-
高并发
-
占用系统资源少
-
C10K? 不存在
Apache:
-
使用 select 模型
-
阻塞 + 多进程 / 多线程
-
更稳定,Bug 少
-
模块更丰富
-
C10K? 存在
Nginx 安装
yum安装
#centos自带安装
yum -y install nginx
#官方自带源安装
#https://nginx.org/en/linux_packages.html#RHEL-CentOS
#配置官方的yum源文件,然后再安装编译安装
下载源码:https://nginx.org/en/download.html
#下载源码包
[root@centos8 ~]# cd /usr/local/src/
[root@centos8 src]# wget https://nginx.org/download/nginx-1.18.0.tar.gz
#创建nginx账号
[root@centos8 ~]#useradd -r -s /sbin/nologin nginx
#安装相关依赖包
#centos
yum -y install make gcc pcre-devel openssl-devel zlib-devel
#ubuntu
apt -y install make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev
#指定编译安装选项(根据生产需要指定)
[root@centos8 src]# tar xf nginx-1.18.0.tar.gz
[root@centos8 src]# cd nginx-1.18.0/
[root@centos8 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
#开始编译安装
[root@centos8 nginx-1.20.1]#make -j 2 && make install
#修改权限
[root@centos8 nginx-1.20.1]#chown -R nginx.nginx /apps/nginx
#将可执行文件创建软连接
[root@centos8 nginx-1.20.1]#ln -s /apps/nginx/sbin/nginx /usr/sbin/编译安装后实现开机自动启动
#创建目录
[root@centos8 ~]#mkdir /apps/nginx/run
#修改权限
[root@centos8 nginx-1.20.1]#chown -R nginx.nginx /apps/nginx
#修改配置文件
[root@centos8 ~]#vim /apps/nginx/conf/nginx.conf
pid /apps/nginx/run/nginx.pid;
#创建service文件
[root@centos ~]#vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/apps/nginx/run/nginx.pid
ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /apps/nginx/run/nginx.pid)"
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /apps/nginx/run/nginx.pid)"
[Install]
WantedBy=multi-user.target
#更新service文件并实现开机启动
[root@centos8 ~]# systemctl daemon-reload
[root@centos8 ~]# systemctl enable --now nginx.service Nginx 命令
- **注意:**systemctl也可以实现服务的启动、停止、和重新加载、但是不要和nginx自带的启动停止等工具混用,否则会出现错误
#启动服务
[root@centos8 apps]#nginx
[root@centos8 apps]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
#停止服务
nginx -s stop
#重新加载配置文件
nginx -s reload
#检查配置文件语法
nginx -t
#显示版本
nginx -v
#显示编译选项
nginx -VNginx 配置文件
Nginx 配置文件参考文档:
配置文件自定生成(仅作参考):
配置文件格式
- directive value [value2 …];
- 必须以分号结尾
- 支持使用配置变量:
- 内建变量:由Nginx模块引入,可直接使用
- 自定义变量:由用户使用set命令定义,格式:set variable_name value;
- 引用变量:$variable_name
配置文件结构
main # 主配置段,即全局配置段,对http,mail都有效
events { # 定义 Nginx 如何处理连接的事件,如连接数限制、超时等
...
}
http { # 记录各 server 的公共配置,例如:HTTP 服务器或反向代理服务器的配置,包括 HTTP 请求的处理、代理设置、缓存设置、日志记录等。
...
server { # 每个server用于定义一个虚拟主机,用于匹配到来的请求并确定如何处理该请求。第一个server为默认虚拟服务器。
...
location / { # 定义某个 URI(或者 URI 的一部分)的配置,用于匹配到来的请求并确定如何处理该请求。一个 server 中可以有多个 location
...
}
}
}
mail { # mail 协议相关配置段,默认配置文件不包括此配置段
...
}
stream { # 定义基于TCP、UDP、UNIX等协议的后端代理配置,默认配置文件不包括此配置段
...
}