第八周作业

3.总结LVS的NAT和DR模型工作原理,并完成DR模型实战?

答:LVS的NAT和DR模型都是反向代理的应用;LVS之NAT的特点:

(1)后端服务器RS的IP地址必须和proxy服务器的DIP在同一个子网,而且应该使用私网地址,RS的网关必须指向proxy服务器的DIP;

(2)请求报文和响应报文都必须经过proxy服务器,要开启路由转发,请求数量多的时候,proxy容易出现性能瓶颈;

(3)支持端口映射,可以修改请求报文的目标端口。

DR的工作原理:Direct Routing,直接路由,也是LVS的默认路由模式,其将从客户端接收到的请求报文的MAC源地址和MAC目标地址分别修改为DIP所在接口的MAC和后端服务器RS的RIP所在接口的MAC,源IP和源端口,目标IP和目标端口在整个过程中均保持不变,修改完成后将请求报文发往后端服务器RS,后端服务器RS处理后直接将响应报文发送回给客户端;

DR的工作特点

(1)proxy服务器和后端服务器RS都配置VIP;

NAT的工作原理:客户端通过访问LVS的代理服务器的VIP地址,将请求数据报文发送到代理服务器,proxy服务器收到客户端的请求数据报文后,将网络层的目的地址和目的端口在PREROUTING链中修改为后端RS服务器的IP地址和端口,源IP地址CIP保持不变,再将修改后的数据包发往后端RS服务器,后端R,经过自己S服务器接收到请求并处理完成后,将源地址修改为自己的IP地址,将目的地址修改为客户端的VIP的网关发往proxy服务器,proxy服务器收到RS的响应报文后,再将响应报文的源地址修改为proxy的VIP,响应报文的目的地址CIP不变,最终发送响应报文到客户端。

(2)确保前端路由器将目标IP为VIP的请求报文发往proxy代理服务器,因此要在后端服务器RS上修改内核参数以此限制arp通告和应答级别;

(3)RS的RIP可以使用私网地址,也可以使用公网地址,RIP和DIP必须在同一子网,而且RIP的网关不能指向DIP,以确保响应报文不会经过proxy代理服务器;

(4)请求报文要经过proxy代理服务器,但响应报文不经过proxy代理服务器,而是由后端服务器RS直接发往客户端;

(5)不支持端口映射,即端口不能修改;

(6)无需开启ip_forward。

DR模式的实现:

用wireshar抓包分析LVS的DR模式特点:

4.总结http协议的通信过程详解?

答:

(1)首先客户端根据http协议URL中的主机域名进行DNS解析,得到请求主机域名的真实IP地址,根据DNS解析的IP地址和http服务器进行TCP三次握手建立通信连接;

(2)服务器接收到http请求报文后,根据请求报文的URL统一资源定位符进行解析,获取http请求的资源和请求方法等相关信息,根据请求方法,请求资源,首部和可选的主体部分对请求进行处理;

(3)访问资源==>服务器获取http请求报文中请求的资源web服务器,即存放了web资源的服务器,负责向请求者提供对方请求的静态资源或者动态运行后生成的资源;

(4)构建响应报文==》一旦web服务器识别资源,就执行请求方法中描述的动作,并返回响应报文,响应报文中包含有响应状态码,响应首部,如果生成了响应主体的话,还包括响应主体;

(5)发送响应报文==》web服务器通过连接发送数据时也会面临和接收数据一样的问题,服务器可能有很多条到客户端的连接,有些是空闲的,有些在向服务器发送数据,还有一些在向客户端回送响应数据,服务器要记录连接的状态,还要特别注意对持久连接的处理:对非持久连接而言,服务器应该在发送整条报文后,关闭自己这一端的连接;对持久连接来说,连接可能仍保持打开状态,在这种情况下,服务器要正确地计算Content-Length首部,不然客户端就无法知道需要什么时候结束;

(6)记录日志==》最后,当http一次请求--发送事务结束时,web服务器会在其日志文件中添加一个条目,用来记录描述已经执行的事务。

5.总结网络IO模型和Nginx架构?

答:

(1)阻塞IO模型是最简单的IO模型,用户线程在内核进行IO操作时被阻塞;用户线程通过系统调用read发起IO读操作,由用户空间转到内核空间,内核等到数据包到达后,然后将接受的数据拷贝到用户空间,完成read读操作;用户需要等待read将数据读取到buffer后,才能继续处理接受的数据,整个IO请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够;

优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用CPU的资源;

缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存和线程切换开销较大。

(2)非阻塞型IO模型==》用户线程发起IO请求时立即返回,但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据到达后,才能真正读取到数据,继续执行;即“轮询”机制存在问题:如果有大量文件描述符都要等,那么就得一个一个的read,这会带来大量的Context Switch==》read是系统调用,每调用一次就得在用户态和内核态切换一次;轮询的时间不好把握,这里是要猜多久之后数据才能到,等待的时间设的太长,程序响应延迟就过大,设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性;

(3)IO多路复用==》指一个线程可以同时(实际是交替实现,即并发完成)监控和处理多个文件描述符对应各自的IO,即复用同一个线程;一个线程之所以能同时处理多个IO,这是因为这个线程调用了内核中的select,poll和epoll等系统调用,从而实现多路复用IO;

IO多路复用是一种机制,即程序注册一组socket文件描述符给操作系统,表示“我要监视这些fd是否有IO事件发生,有了就告诉程序去处理”;

IO多路复用指内核一旦发现进程指定的一个或者多个IO条件准备读取,就通知该进程多个连接共用一个等待机制,本模型会阻塞进程,但是进程是阻塞在select等系统调用上,而不是阻塞在真正的IO操作上===》用户首先将需要进行的IO操作添加到select中,同时等待select系统调用返回,当数据到达时,IO被激活,select函数返回,用户线程正式发起read读请求,读取数据并继续执行;

从流程上来看,使用select的系统调用进行IO请求和同步阻塞模型没有太大的区别,甚至还多添加监视IO,以及调用select函数的额外操作,效率更差,并且阻塞了2次,但是第一次阻塞在select上时,select可以监控多个IO上是否有IO操作准备就绪,即可以达到在同一个线程内同时处理多个IO请求的目的,而不是像阻塞IO那种,一次只能监控一个IO;

虽然上述方式允许单线程内处理多个IO请求,但是每个IO请求的过程还是阻塞的(在select函数上阻塞),平均时间甚至比同步阻塞IO模型还要常,如果线程只是注册自己需要的IO请求,然后自己去做自己的事情,等到数据到来时再进行处理,则可以提高CPU的利用率;

IO多路复用是最常使用的IO模型,但是其异步程度还不够“彻底”,因为其使用了会阻塞线程的select等系统调用,因此IO多路复用只能称为异步阻塞IO模型,而非真正的异步IO;

综上所述,IO多路复用的基本原理就是通过系统调用select/poll/epoll这个函数会不断轮询所负责的所有socket,当某个socket有数据到达了,内核就会通知用户进程;当用户进程调用了select等系统调用,那么整个进程会被阻塞,而同时,内核会监控所有的select负责的socket,当任何一个socket中的数据准备好了,select就会返回,整个时候,用户进程再调用read操作,将数据从内核拷贝到用户进程;

优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述符一个线程),这样可以大大节省系统资源;

缺点:当连接数较小时效率比多线程加阻塞IO模型效率低,可能延迟更大,因为单个连接处理需要

次系统调用,占用时间会有增加。

(4)信号驱动式IO模型==>意思就是进程不用傻等着,也不用去轮询,而是让内核在数据就绪时,发送信号通知进程;调用的步奏是通过系统调用sigaction,并注册一个信号处理回调函数,此调用会立即返回,然后主程序可以继续向下执行,当有IO操作准备就绪,即内核数据就绪时,内核会为该进程产生一个SIGIO信号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用recvfrom获取数据,将用户进程所需要的数据从内核空间拷贝到用户空间;

优点:在于等待数据到达期间进程不被阻塞,用户主程序可以继续执行,只要等待来自信号处理函数的通知;在信号驱动式IO模型中,应用程序使用套接口进行驱动IO,并安装一个信号处理函数,进程继续运行并不阻塞;当数据准备好时,进程会受到一个SIGIO信号,可以在信号处理函数中调用IO操作函数处理数据,线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求,因此可以提高资源的利用率;

缺点:信号IO在大量IO操作时可能会因为信号队列溢出导致没法通知;

(5)异步IO模型==》其与信号驱动IO最大区别在于,信号驱动是内核通知用户进程何时开始一个IO操作,而异步IO是由内核通知用户进程IO操作何时完成,这两者的有本质区别,相当于不用去饭店吃饭,直接点个外卖,把等待上菜的时间也给节省了;

相对于同步IO,异步IO不是顺序执行,用户进程进行aio_read系统调用之后,无论内核数据是否准备好,都会直接返回给用户进程,然后用户进程可以去做别的事情,等到socket数据准备好了,内核直接复制数据给进程,然后从内核向用户进程发送通知,这2个IO阶段,用户进程都是非阻塞的;

信号驱动IO当内核通知触发信号处理程序时,信号处理程序还需要阻塞在从内核空间缓冲区拷贝数据到用户空间缓冲区这个阶段,而异步IO直接是在第2个阶段完成后,内核直接通知用户线程可以继续后续的操作了;

优点:异步IO能够充分利用DMA特性,让IO操作与计算重叠;

缺点:要实现真正的异步IO,操作系统需要做大量的工作。

Nginx架构:

Nginx是多进程组织模型,由一个Master主进程和若干Worker工作进程组成:

master主进程的工作过程和功能:

(1)接收外部的操作请求,并建立listen的socket;

(2)master主进程fork出work子进程,并根据外部的不同操作,通过信号管理work子进程;

(3)监控worker子进程的运行状态,worker子进程异常终止后,会自动重启worker子进程;

(4)读取Nginx配置文件并验证其有效性和正确性;

(5)按照配置生成,管理和结束工作进程;

(6)接收外界指令,比如重启,升级和退出服务器等指令;

(7)不中断服务,实现平滑升级,重启服务并应用新的配置;

(8)不中断服务,实现平滑升级,升级失败后进行回滚处理;

(9)开启日志文件,获取文件描述符;

worker工作进程工作过程和功能:

(1)新请求到来时,所有worker进程的listenfd都变为可读;

(2)竞争锁accept_mutex,获胜的注册listenfd的读事件;

(3)在读事件中,accept当前连接;

(4)接收客户的请求,并将请求依次送入各个功能模块进行处理;

(5)与后端服务器通信,接收后端服务器的处理结果;

(6)缓存数据,访问缓存索引,查询和调用缓存数据;

(7)发送请求结果,响应客户端的请求;

(8)接收主程序指令,比如重启,升级和退出等。

7.总结nginx核心配置,并实现nginx多虚拟主机?

答:

(1)全局配置段,对全局生效,主要设置nginx的启动用户/组,启动的工作进程数量,工作模式,nginx的PID路径,日志路径等;

(2)events事件驱动相关的配置:主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多个网络连接,使用哪种事件驱动模型处理请求,每个工作进程可以同时支持的最大连接数,是否开启对多工作进程下的网络连接进行序列化等;

(3)http模块是nginx服务配置中的重要部分,缓存,代理和日志格式定义等绝大多数功能和第三方模块都可以在这里设置,而且http模块可以包含多个server模块,而一个server模块又可以包含多个location模块;http模块可以配置文件引入,MIME-Type定义,日志自定义,是否启用sendfile,连接超时时间和单个连接的请求上限等;

(4)server模块可以设置一个虚拟主机,可以包含自己的全局块,也可以包含多个location模块,可以配置本虚拟主机监听的端口,本虚拟主机的域名名称和IP;

(5)location模块是server的一个指令,其为nginx服务器提供比较多而且灵活的指令,主要是基于nginx接收到的请求字符串,对用户请求的URL进行配置,并对特定的指令进行处理,包括地址重定向,数据缓存和应答控制等功能都是在这部分实现,另外很多第三方模块的配置也是在location模块中配置的。

8.总结nginx日志格式定制?

答:访问日志是记录客户端的具体请求内容信息,而在全局配置模块中的error_log是记录nginx服务器运行时的日志保存路径和记录日志的级别,因此两者是不同的,而且nginx的错误日志一般只有一个,但是访问日志可以在不同的server中定义多个,定义一个访问日志需要使用access_log指定日志的保存路径,使用log_format指定日志的格式,格式中定义要保存的具体日志内容;

访问日志由ngx_http_log_module模块实现;

nginx默认的访问日志记录内容相对比较单一,默认的格式也不方便后期做日志分析,生产环境中通常将nginx日志转换为 json格式:

log_format access_json '{

' "host": "$server_addr", '

' "clientip": "$remote_addr", '

' "size": "$body_bytes_sent", '

' "responsetime": "$request_time", '

' "uri" : "$uri", '

' "xff": "$http_x_forwarded_for", '

' "tcp_xff": "$proxy_protocol_addr", '

' "status": "$status"

}';

注意:log_format指令只能在http模块中配置,access_log指令必须配置在其后面;

例如==》access_log  /apps/nginx/logs/access_json.log  access_json;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值