第十六周--作业
1、对常用I/O模型进行比较说明
同步/异步
同步(synchronous)是指被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成;异步(asynchronous)指的是被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态。 同步/异步关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。 |
阻塞/非阻塞
阻塞(blocking)指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情;非阻塞(nonblocking)指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。 阻塞/非阻塞关注调用者在等待结果返回之前所处的状态。 |
网络I/O模型
网络I/O模型包括阻塞型、非阻塞型、复用型、信号驱动型和异步五种。<br><br>阻塞型I/O模型(blocking IO) |
阻塞型I/O模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞。用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间,内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成read操作;用户需要等待read将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够。
非阻塞型I/O模型 (nonblocking IO)
在非阻塞型I/O模型中,用户线程发起IO请求时立即返回,但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据到达后,才真正读取到数据,继续执行。这会带来“轮询”机制中所存在两个问题:如果有大量文件描述符都要等,那么就得一个一个的read,这会带来大量的Context Switch(read是系统调用,每调用一次就得在用户态和核心态切换一次);此外轮询的时间也不好把握,需要猜多久之后数据才能到,如果等待时间设的太长,程序响应延迟就过大,如果设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。
多路复用I/O模型(I/O multiplexing)
多路复用I/O模型主要包括select、poll和epoll三种系统调用,这三种系统调用的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select/poll/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程,当用户进程调用了select,那么整个进程会被block,同时kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。
信号驱动式I/O模型(signal-driven IO)
信号驱动I/O的意思就是进程现在不用傻等着,也不用去轮询,而是让内核在数据就绪时,发送信号通知进程。
调用的步骤是:通过系统调用sigaction,并注册一个信号处理的回调函数,该调用会立即返回,然后主程序可以继续向下执行,当有I/O操作准备就绪,即内核数据就绪时,内核会为该进程产生一个SIGIO信号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用recvfrom获取数据,将用户进程所需要的数据从内核空间拷贝到用户空间。
此模型的优势在于等待数据报到达期间进程不被阻塞,用户主程序可以继续执行,只要等待来自信号处理函数的通知。在信号驱动式I/O模型中,应用程序使用套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,可以在信号处理函数中调用I/O操作函数处理数据
异步I/O模型(asynchronous IO)
异步I/O与信号驱动I/O最大区别在于,信号驱动是内核通知用户进程何时开始一个I/O操作,而异步I/O是由内核通知用户进程I/O操作何时完成,两者有本质区别,相当于不用去饭店场吃饭,直接点个外卖,把等待上菜的时间也给省了。
相对于同步I/O,异步I/O不是顺序执行。用户进程进行aio_read系统调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到socket数据准备好了,内核直接复制数据给进程,然后从内核向进程发送通知。IO两个阶段,进程都是非阻塞的。
在信号驱动IO中,当内核通知触发信号处理程序时,信号处理程序还需要阻塞在从内核空间缓冲区拷贝数据到用户空间缓冲区这个阶段,而异步IO直接是在第二个阶段完成后,内核直接通知用户线程可以进行后续操作了。
2、nginx中的模块分类及常见核心模块有哪些
nginx的常用核心模块有: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: 启动Nginx工作进程的数量,一般设为和CPU核心数相同 worker_cpu_affinity: 将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的 worker_rlimit_nofile: 所有worker进程能打开的文件数量上限,包括:Nginx的所有连接(例如与代理服务器的连接等) worker_connections: 设置单个工作进程可以同时打开的最大连接数。这个数字包括所有连接(例如与代理服务器的连接等) |
4、编译安装nginx,实现多域名 https"
编译安装Nginx
#安装依赖包 yum -y install gcc pcre-devel openssl-devel zlib-devel #创建账号 useradd -s /sbin/nologin nginx #解压源码包 tar xvf nginx-1.20.2.tar.gz -C /usr/local/ cd /usr/local/nginx-1.20.2/ #解压并运行configure脚本 ./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 -j 2 make install #修改文件属性 chown -R nginx.nginx /apps/nginx/ #创建软连接 ln -s /apps/nginx/sbin/nginx /usr/sbin/<br><br>#修改主配置文件<br>mkdir /apps/nginx/run<br>chown -R nginx.nginx /apps/nginx/run<br>vim /apps/nginx/conf/nginx.conf<br>#添加此行:pid run/nginx.pid;<br><br>#创建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/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
重读配置文件
systemctl daemon-reload
实现多域名
假设以上编译安装的Nginx服务器中要部署两个网站,一个是PC端的,域名为www.mage.com,另一个为手机端的,域名为m.mage.com。 创建配置文件存放路径 mkdir /apps/nginx/conf.d/ vim /appd/nginx/conf/nginx.conf grep -E 'http|include' /apps/nginx/conf/nginx.conf http { include mime.types; include /apps/nginx/conf.d/*.conf; # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; # proxy_pass http://127.0.0.1; # include fastcgi_params; 创建子配置文件 cd /apps/nginx/conf.d/ vim pc.conf server { listen 80; server_name www.mage.com; root /data/nginx/html/pc; } vim /mobile server { listen 80; server_name m.mage.com; root /data/nginx/html/mobile; } mkdir /data/nginx/html/pc/ -p mkdir /data/nginx/html/mobile/ -p echo 'Hello! Welcome to PC website!' > /data/nginx/html/pc/index.html echo 'Hello! Welcome to mobile website!' > /data/nginx/html/mobile/index.html nginx -t nginx -s reload |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通