单个服务器如何处理请求

web服务器最简单的形式就是一个程序,它侦听HTTP请求,在收到一个HTTP请求之后做出回复。当然在接收请求后服务器所做的东西是我们关注的焦点。在下文中也会提及到node是如何简单的实现一个web服务器。

常用的是Apache,tomcat等服务器解决web请求。现在更多的人会使用Nginx解决web请求,这也有一定的道理。本文主要研究各服务器比较成熟的多任务处理方式。下文会详细的提到。

Apache:

说到web应用平台,基本上第一反应都是LAMP这个经典的平台。其中Apache使用的时间也是众多服务器中使用比较稳定的。对于单个请求,Apache处理的流程和基本的web服务器流程差不多,我们主要看一下Apache的多任务处理:

(1) 我们知道操作系统早就实现了并发机制,则充分利用操作系统的并发机制提高服务器的单机运行效率是服务器开发者不断追求的目标。但是,因为不同的操作系统平台和计算机硬件的差别使得并发模型没有一个通用的规则,在很多平台上非常优秀的并发模型换到另一个平台上就变成性能很差;另外同一个系统平台但是执行的任务不同,同一个并发模型的并发性能也有很大差异;所以并发的性能的影响因素包括:

  • 操作系统平台
  • 服务器跑的任务

(2) Apache 是用C语言开发的,所以入口是一个main主程序,主程序一旦调用MPM模型中的ap_mpm_run函数后,就进入了多进程并发处理状态,为了并发处理客户端的请求,Apache会产生多个进程,而每个进程又会产生多个线程.

Aapche提供了多个并发模型:

  • prefork:一般用于Unix操作系统,基于进程的并发,以进程为一个处理client请求的基本单位;有多个子进程(但没有线程);一般Linux系统会默认次并发模型
  • worker:新的MPM,同事使用了线程和进程,效率比单纯使用进程的Prefork MPM要高(既有进程、也有线程)
  • WinNT :适用于windows系统平台,以线程作为处理client请求的基本单位

(3) MPM的主要任务

MPM的主要任务是创建进程或线程并对它们进行管理,包括在空闲的时候终止多余的进程或线程,以及在忙碌的时候启动更多的进程和线程;另外一个任务是在套接字上(socket)上监听客户端的请求,当请求到达时,MPM将把它派发给创建好的进程和线程,继而进入请求处理阶段(每一个进程或线程将自始至终只负责一个客户端的请求)

其实这里就包含了很多我们需要慢慢梳理的东西。比如Apache的进程模型:Apache里面多进程模式(多线程模式)。都是Apache本身维护的一个进程池来分配进程来处理单个请求的。进程和线程的优缺点这里也不一一述说。

Nginx篇

在说Nginx之前,我想说一下Node中一个比较好的处理请求的方式,采用异步I/O的方式。就像我们编程一样,单线程同步编程顺序执行任务的方式比较符合编程人员顺序思考的思维方式,但是会因阻塞I/O导致硬件资源得不到更优的使用。而多线程编程模型也因为编程中的死锁、状态同步等问题而头疼。

首先我们来了解阻塞和非阻塞两个名词(简单描述,具体的可以阅读操作系统方面的知识):

阻塞I/O的一个特点就是调用之后一定要等到系统内核层面完成所有操作后,调用才结束。阻塞I/O最主要的就是等待过程中有可能浪费时间。不能使CPU的处理能力最大化

非阻塞I/O和阻塞的区别在于非阻塞I/O不带数据直接返回,等要获取数据,还需要通过文件描述符再次读取。非阻塞I/O返回之后,CPU的时间片可以用来处理其他事务。但非阻塞I/O也存在一些问题。由于完整的I/O没有完成,立即返回的并不是业务层期望的数据,而仅仅是当前调用的状态。为了获取完整的数据,应用程序需要重复调用I/O操作来确认是否完成。这种重复调用判断操作是否完成的技术叫做轮询。

轮询技术(主要):

select/poll:创建一个关注事件的描述符集合,再去等待这些事件发生,然后再轮询描述符集合,检查事件发生,有就进行处理

epoll:把描述符列表的管理交由内核负责,一旦有事件发生,内核把发生事件的描诉符列表通知给进程,避免了轮询整个描述符列表。

rtsig:工作进程会通过系统内核建立一个rtsig队列用于存放标记事件发生的信号。

上述描述整理出完成整个异步I/O的环节为:事件循环(典型的生产者/消费者),观察者,请求对象,执行回调。

则Node通过事件驱动的方式处理请求,无须每一个请求创建额外的对应线程,可以省掉创建线程和销毁线程的开销,生成的线程少,减低上下文切换。

其实Nginx内部实现和Node有异曲同工之妙。下面说一下Nginx服务器的web请求处理机制:

1.多进程方式:多进程方式的优点在于各个子进程之间相互独立,处理客户端请求的过程彼此不受到干扰,不会相互影响,提供服务的稳定性。缺点也很明显:操作系统生成一个子进程需要进行内存复制等操作,在资源和事件产生额外开销。(apache可以采用预生成进程机制改进,交互完成后,该进程也不结束)

2.多线程方式: 缺点:多个线程位于同一个进程内,可以访问同样的内存空间,彼此之间相互影响。都要由开发者对内存进行管理

3.异步方式

同步机制:指发送方发送请求后,需要等待接受到接收方发回的响应后,才接着发送下一个请求;

异步机制:发送方发送一个请求后,不等待接收方相应这个请求,就继续发送下一个请求。形成一个队列,接收方处理完成后通知发送方。

阻塞调用方式为,调用结果返回之前,当前线程从运行状态被挂起,一直等到结果返回之后,才进入就绪状态,获取cpu后继续执行

非阻塞调用:线程不被挂起,立即返回执行下一个调用。

Nginx服务器有一个master进程,多个worker进程,工作进程使用了异步非阻塞方式。

Nginx的事件处理机制(IO状态通知给工作进程,IO调用完成后能主动通知工作进程,事件驱动模型)

事件驱动模型:事件收集器,事件发送器,事件处理器(多路IO复用方式)参考轮询的实现。

当然Nginx有其他很多的功能:比如作为反向代理缓存和负载均衡方面也有比较好的表现。下几篇就会介绍。

至于Tomcat还在学习中,具体的处理模型也会和Apache等进行比较。希望尽快能发文。

小结:本篇主要学习了服务器多任务处理请求的流程。也有很多不太清楚的地方。请大家多多指点。

构建高可用web站点学习(一)的更多相关文章

  1. 构建高可用web站点学习--前言

    前言:本人对于提高web站点的访问量等的有很浓厚的兴趣,也学习了将近一年的时间,希望能总结点东西,虽然很多东西都是从书籍和资料中学习的,而不是原创,但是这是我总结的一点感悟和进行的分类吧.而且可能思路 ...

  2. 构建高可用web站点学习(二)

    web站点的缓存学习 缓存在web应用里面十分常见,也有各种各样的缓存,从请求开始一直到代码处理的阶段都可以采取缓存.下面就逐一介绍: 一.客户端缓存(浏览器和http方面) 前端页面缓存主要遵循ht ...

  3. 构建高可用web站点学习(三)

    分布式的构建 做为网站访问的生命线(数据访问),当然也可以采用分布式的方法来减轻单台服务器的访问压力.之前有讲过Memcached的分布式,但是Memcached服务器互不通信,所以我们也提过redi ...

  4. 构建高可用web站点(五)

    数据库是web站点中重要的应用,放在第四篇是因为之前来不及总结的原因,在之前的文章我看到了无论是Mysql或者是nosql的一些缓存和分布式一些比较扩展性的功能.但是对于单个数据库来说,它的优化也是我 ...

  5. 构建高可用web站点(四)

    首先我们来了解负载均衡的概念:英文名称为Load Balance,其意思就是将负载(工作任务)进行平衡.分摊到多个操作单元上进行执行,例如Web服务器.FTP服务器.企业关键应用服务器和其它关键任务服 ...

  6. 基于docker+etcd+confd + haproxy构建高可用、自发现的web服务

    基于docker+etcd+confd + haproxy构建高可用.自发现的web服务 2016-05-16 15:12 595人阅读 评论(0) 收藏 举报 版权声明:本文为博主原创文章,未经博主 ...

  7. Dubbo入门到精通学习笔记(十六):Keepalived+Nginx实现高可用Web负载均衡

    文章目录 Keepalived+Nginx实现高可用Web负载均衡 Keepalived+Nginx实现高可用Web负载均衡 高可用架构篇 Keepalived + Nginx 实现高可用 Web 负 ...

  8. 高性能Linux服务器 第11章 构建高可用的LVS负载均衡集群

    高性能Linux服务器 第11章 构建高可用的LVS负载均衡集群 libnet软件包<-依赖-heartbeat(包含ldirectord插件(需要perl-MailTools的rpm包)) l ...

  9. linux RHCS集群 高可用web服务器

    RHCS集群,高可用服务器 高可用 红帽集群套件,提供高可用性,高可靠性,负载均衡,快速的从一个节点切换到另一个节点(最多16个节点)负载均衡 通过lvs提供负载均衡,lvs将负载通过负载分配策略,将 ...

随机推荐

  1. XDocument和XmlDocument的区别

    刚开始使用Xml的时候,没有注意到XDocument和XmlDocument的区别,后来发现两者还是有一些不同的. XDocument和XmlDocument都可以用来操作XML文档,XDocumen ...

  2. 解码美国传奇网络券商:TradeStation

    证券时报记者 桂衍民 张欣然 5万客户,交易量却占美国网络券商8%,网络影响力已连续两年被评为全美前五名,说起美国网络证券,必提TradeStation. TradeStation的确是美国证券界的一 ...

  3. 一个小程序,时间util

    比较时间,如果此时间是今天的显示时间点,今天以前显日期 public String getTime(Date time){               SimpleDateFormat dateFor ...

  4. 美丽的表格样式(使用CSS样式表控制表格样式)

    按照WEB2.0风格,设计了几个表格样式,希望大家喜欢. WEB2.0提倡使用div开布局,但不是要全然放弃使用表格,表格在数据展现方面还是不错的选择. 如今使用介绍使用CSS样式表来控制.美化表格的 ...

  5. 关于Yaffs2在u-boot中的支持

    开发板是一块2G的MLC的NandFlash,页大小8k+512,为其移植u-boot到yaffs2这了.以前在Mini2440上移植过2k+64的slc的NandFlash的Yaffs2支持,当然也 ...

  6. [转] shared_from_this 几个值得注意的地方

    http://hi.baidu.com/cpuramdisk/item/7c2f8d77385e0f29d7a89cf0 shared_from_this()是enable_shared_from_t ...

  7. RunTime 应用实例–关于埋点的思考

    埋点是现在很多App中都需要用到的,这个问题可能每个人都能处理,但是怎样来减少埋点所带来的侵入性,怎样用更加简洁的方式来处理埋点问题,怎样减少误埋,如果上线了发现少埋了怎么办?下面是本文讨论的重点: ...

  8. Android(java)学习笔记228:服务(service)之绑定服务调用服务里面的方法

    1.绑定服务调用服务里面的方法,图解: 步骤: (1)在Activity代码里面绑定 bindService(),以bind的方式开启服务 :                     bindServ ...

  9. NYOJ-520 最大素因子

    这个题基本上就两个知识点, 一个素数筛选法求素数,另一个是求最大公因子, 不过确定最大素数在素数表中的位置时,要用到二分的思想,不然会超时,下面是具体代码的实现; #include <stdio ...

  10. HDU5327

    #include <iostream> #include <stdio.h> #include <cstring> using namespace std; int ...