1、对常用I/O模型进行比较说明
一、IO模型的四个特性
关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。
同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成
异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态
关注调用者在等待结果返回之前所处的状态
阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。
非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完- 成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。
二、网络 I/O 模型
2.1 阻塞型 I/O 模型(blocking IO)
阻塞IO模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞。用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间。
内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成read操作用户需要等待read将数据读取到buffer后,才继续处理接收的数据。
整个I/O请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够
优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源
缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销较大,apache 的preforck使用的是这种模式。
2.2非阻塞型 I/O 模型 (nonblocking IO)
用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据到达后,才真正读取到数据,继续执行。
即 “轮询”机制存在两个问题:如果有大量文件描述符都要等,那么就得一个一个的read。这会带来大量的Context Switch(read是系统调用,
每调用一次就得在用户态和核心态切换一次)。轮询的时间不好把握。这里是要猜多久之后数据才能到。等待时间设的太长,程序响应延迟就过大;
设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。
2.3多路复用 I/O 型(I/O multiplexing)
多路复用IO指一个线程可以同时(实际是交替实现,即并发完成)监控和处理多个文件描述符对应各自的IO,即复用同一个线程一个线程之所以能
实现同时处理多个IO,是因为这个线程调用了内核中的SELECT,POLL或EPOLL等系统调用,从而实现多路复用IO。
优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述符一个线程),这样可以大大节省系统资源
缺点:当连接数较少时效率相比多线程+阻塞 I/O 模型效率较低,可能延迟更大,因为单个连接处理需要 2 次系统调用,占用时间会有增加
2.3信号驱动式 I/O 模型 (signal-driven IO)
信号驱动I/O的意思就是进程现在不用傻等着,也不用去轮询。而是让内核在数据就绪时,发送信号通知进程。调用的步骤是:通过系统调用sigaction ,
并注册一个信号处理的回调函数,该调用会立即返回,然后主程序可以继续向下执行,当有I/O操作准备就绪,即内核数据就绪时,内核会为该进程产生一个
SIGIO信号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用recvfrom 获取数据,将用户进程所需要的数据从内核空间拷贝到用户空间。
此模型的优势在于等待数据报到达期间进程不被阻塞。用户主程序可以继续执行,只要等待来自信号处理函数的通知。在信号驱动式 I/O 模型中,应用程序
使用套接口进行信号驱动 I/O,并安装一个信号处理函数,进程继续运行并不阻塞当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调
用 I/O 操作函数处理数据。
优点:线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此可以提高资源的利用率
缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知
2.4 异步 I/O 模型 (asynchronous IO)
异步I/O 与 信号驱动I/O最大区别在于,信号驱动是内核通知用户进程何时开始一个I/O操作,而异步I/O是由内核通知用户进程I/O操作何时完成,
两者有本质区别,相当于不用去饭店场吃饭,直接点个外卖,把等待上菜的时间也给省了。相对于同步I/O,异步I/O不是顺序执行。用户进程进行
aio_read系统调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到socket数据准备好了,
内核直接复制数据给进程,然后从内核向进程发送通知。IO两个阶段,进程都是非阻塞的。信号驱动IO当内核通知触发信号处理程序时,信号处
理程序还需要阻塞在从内核空间缓冲区拷贝数据到用户空间缓冲区这个阶段,而异步IO直接是在第二个阶段完成后,内核直接通知用户线程可以
进行后续操作了
优点:异步 I/O 能够充分利用 DMA 特性,让 I/O 操作与计算重叠
缺点:要实现真正的异步 I/O,操作系统需要做大量的工作。目前 Windows 下通过 IOCP 实现了真正的
三、五种IO对比
这五种 I/O 模型中,越往后,阻塞越少,理论上效率也是最优前四种属于同步 I/O,因为其中真正的 I/O操作(recvfrom)将阻塞进程/线程,只有异步 I/O 模型才与 POSIX 定义的异步 I/O 相匹配。
2、nginx中的模块分类及常见核心模块有哪些
1、模块分类
核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件驱动机制 、进程管理等核心功能
标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置 等等
可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如: Flash多媒体传输 、解析 GeoIP 请求、网络传输压缩 、 安全协议 SSL 支持等
邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持
Stream服务模块: 实现反向代理功能,包括TCP协议代理
第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等
2、常见核心模块
ngx_core
ngx_errlog
ngx_conf
ngx_events
ngx_event
ngx_epoll
ngx_regex
3、描述nginx中worker_processes、worker_cpu_affinity、worker_rlimit_nofile、worker_connections配置项的含义
worker_processes
worker进程的数量,应小于等于cpu核心数,auto为当前主机cpu核心数
work_processes 4
worker_cpu_affinity
配置CPU亲和,将worker进程与通过cpumask与指定cpu绑定,减少切换造成的CPU时间损耗.
worker_cpu_affinity 00000001 00000010 00000100 00001000 #后面跟的是十六进制数字,00000001表示号cpu
worker_rlimit_nofile
指定worker进程的nice值,范围[-20,20]
worker_rlimit_nofile 10
worker_connections
设置单个工作进程的最大并发连接数
events {
worker_connections 65536;
....
}
4、编译安装nginx,实现多域名 https"
一、编译安装nginx
1.1 获取源码包
[root@cetnos7 ~]#wget -O /usr/local/src/nginx-1.18.0.tar.gz http://nginx.org/download/nginx-1.18.0.tar.gz
[root@cetnos7 ~]#cd /usr/local/src/
[root@cetnos7 src]#tar xvf nginx-1.18.0.tar.gz
1.2 准备工作
[root@cetnos7 ~]#yum -y install gcc pcre-devel openssl-devel zlib-devel
[root@cetnos7 ~]#useradd -s /sbin/nologin nginx
1.3 进行编译
[root@cetnos7 ~]#cd nginx-1.18.0
[root@cetnos7 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@cetnos7 nginx-1.18.0]#make -j 4 && make install
[root@cetnos7 nginx-1.18.0]#chown -R nginx.nginx /apps/nginx
[root@cetnos7 nginx-1.18.0]#ll /apps/nginx/
total 0
drwxr-xr-x 2 nginx nginx 333 Nov 28 13:37 conf
drwxr-xr-x 2 nginx nginx 40 Nov 28 13:37 html
drwxr-xr-x 2 nginx nginx 6 Nov 28 13:37 logs
drwxr-xr-x 2 nginx nginx 19 Nov 28 13:37 sbin
1.4 创建server文件
[root@centos7 ~]#vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=nginx documentation
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/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
[root@centos7 ~]#mkdir /apps/nginx/run/ #创建pid目录
[root@centos7 ~]#vim /apps/nginx/conf/nginx.conf
pid /apps/nginx/run/nginx.pid;
1.5 启动nginx
[root@cetnos7 ~]# ln -s /apps/nginx/sbin/nginx /usr/sbin/
[root@cetnos7 ~]#nginx -v
nginx version: nginx/1.18.0
[root@cetnos7 ~]#systemctl enable --now nginx
[root@cetnos7 ~]#ll /apps/nginx/run/
total 4
-rw-r--r-- 1 root root 5 Nov 28 13:57 nginx.pid
二、实现多域名
[root@cetnos7 ~]#vim /apps/nginx/conf/nginx.conf
#添加以下内容
server {
listen 80;
server_name www.pc.test1.org;
location / {
root /data/nginx/html/test1;
index index.html;
}
}
server {
listen 80;
server_name www.pc.test2.org;
location / {
root /data/nginx/html/test2;
index index.html;
}
}
server {
listen 80;
server_name www.pc.test3.org;
location / {
root /data/nginx/html/test3;
index index.html;
}
}
创建web目录
[root@cetnos7 conf.d]#mkdir /data/nginx/html/test{1..3} -p
[root@cetnos7 conf.d]#echo "<h1>pc.test1<h1>" > test1/index.html
[root@cetnos7 conf.d]#echo "<h1>pc.test2<h1>" > test2/index.html
[root@cetnos7 conf.d]#echo "<h1>pc.test3<h1>" > test3/index.html
重启nginx
[root@cetnos7 ~]#nginx -t #检查配置语法是否正确
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@cetnos7 ~]#nginx -s reload
测试
[root@client ~]#cat /etc/hosts
10.0.0.7 test1.org test2.org test3.org #添加本地域名解析
[root@client ~]#curl www.pc.test1.org www.pc.test2.org www.pc.test3.org
<h1>pc.test1<h1>
<h1>pc.test2<h1>
<h1>pc.test3<h1>
三、实现https
3.1 生成自签名证书
[root@centos7 ~]#mkdir /apps/nginx/certs -p
[root@centos7 ~]#cd /apps/nginx/certs
[root@centos7 ~]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt
Generating a 4096 bit RSA private key
...++
..............................................................................................................................................................................................................................................................................................................................................................................................................................................++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:guangdong
Locality Name (eg, city) [Default City]:guangzhou
Organization Name (eg, company) [Default Company Ltd]:test.org
Organizational Unit Name (eg, section) []:test
Common Name (eg, your name or your server's hostname) []:ca.test.org
Email Address []:admin@123.org
[root@7-1 certs]#ll
total 8
-rw-r--r-- 1 root root 2102 Nov 28 15:39 ca.crt
-rw-r--r-- 1 root root 3272 Nov 28 15:39 ca.key
3.2自制key和csr文件
[root@7-1 certs]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.test1.org.key -out www.test1.org.csr #重复此步骤,生成test2,test3的相关文件
[root@7-1 certs]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.test2.org.key -out www.test2.org.csr
[root@7-1 certs]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.test3.org.key -out www.test3.org.csr
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:guangdong
Locality Name (eg, city) [Default City]:guangzhou
Organization Name (eg, company) [Default Company Ltd]:test.org
Organizational Unit Name (eg, section) []:nginx
Common Name (eg, your name or your server's hostname) []:www.pc.test1.org
Email Address []:root@test1.org
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
##注意国家,省,公司这个三个参数要与CA的对应##
#签发证书
[root@7-1 certs]#openssl x509 -req -days 3650 -in www.pc.test1.org.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.pc.test1.org.crt
[root@7-1 certs]#openssl x509 -req -days 3650 -in www.pc.test2.org.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.pc.test2.org.crt
[root@7-1 certs]#openssl x509 -req -days 3650 -in www.pc.test3.org.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.pc.test3.org.crt
#合并证书文件
[root@7-1 certs]#cat www.test1.org.crt ca.crt > www.test1.org.pem
[root@7-1 certs]#cat www.test2.org.crt ca.crt > www.test2.org.pem
[root@7-1 certs]#cat www.test3.org.crt ca.crt > www.test3.org.pem
#证书文件目录如下
total 72
-rw-r--r--. 1 root root 2114 May 1 01:35 ca.crt
-rw-r--r--. 1 root root 3272 May 1 01:35 ca.key
-rw-r--r--. 1 root root 17 May 1 01:45 ca.srl
-rw-r--r--. 1 root root 2004 May 1 01:43 www.test1.org.crt
-rw-r--r--. 1 root root 1756 May 1 01:36 www.test1.org.csr
-rw-r--r--. 1 root root 3272 May 1 01:36 www.test1.org.key
-rw-r--r--. 1 root root 4118 May 1 01:45 www.test1.org.pem
-rw-r--r--. 1 root root 2004 May 1 01:44 www.test2.org.crt
-rw-r--r--. 1 root root 1756 May 1 01:38 www.test2.org.csr
-rw-r--r--. 1 root root 3272 May 1 01:38 www.test2.org.key
-rw-r--r--. 1 root root 4118 May 1 01:46 www.test2.org.pem
-rw-r--r--. 1 root root 2004 May 1 01:45 www.test3.org.crt
-rw-r--r--. 1 root root 1756 May 1 01:39 www.test3.org.csr
-rw-r--r--. 1 root root 3272 May 1 01:39 www.test3.org.key
-rw-r--r--. 1 root root 4118 May 1 01:46 www.test3.org.pem
3.3 修改配置文件
##在配置文件的sever语句块添加,如下内容以test1为例:
server {
listen 80;
listen 443 ssl;
server_name www.pc.test1.org;
ssl_certificate /apps/nginx/certs/www.test1.org.pem;
ssl_certificate_key /apps/nginx/certs/www.test1.org.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
location / {
root /data/nginx/html/test1;
index index.html;
}
}
[root@cetnos7 ~]#nginx -t
[root@cetnos7 ~]#nginx -s reload
3.4 访问测试
[root@client ~]#curl https://www.pc.test1.org -k
<h1>pc.test1<h1>
[root@client ~]#curl https://www.pc.test2.org -k
<h1>pc.test2<h1>
[root@client ~]#curl https://www.pc.test3.org -k
<h1>pc.test3<h1>