IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

高性能web服务器-读书笔记

技术 总结 记录 生活 工作 2011-02-27 22:54:39 累计浏览 7,778 次
本机暂存

    进程:

    Cpu能够处理多个请求,在于操作系统通过多执行流体系设计使得多个任务可以轮流使用资源.

    多执行流的一般实现是进程,多进程的好处首先在于Cpu时间的轮流使用,另外对于Cpu计算和I/O(磁盘和网路I/O)操作进行了重叠

    大多数进程的时间消耗在I/O操作上.DMA技术可以让Cpu不参与I/O操作的全过程,比如进程通过系统调用,使得Cpu

    向网卡等设备发出指令,然后进程挂起,Cpu资源释放,等待I/O完成操作后通过中断告之进程重新就绪.

    进程有自己的地址空间和生命周期.进程维护着庞大的地址空间和上下文信息,无法共享数据,所以类似于Apache

    这样的服务器在处理大量请求的时候,内存大量消耗造成性能瓶颈。多进程的优势在于稳定和安全. 这也是Apache服务器的一些特点.

    线程:

    线程由多种实现,有些不是由内核支持的,从内核角度来看,只是一个普通进程,由用户态通过一些库函数模拟实现的

    多执行流,多线程的管理完全在用户态完成.这种实现方式下线程切换的开销相比进程要少些,但是他在多处理的服务器(SMP)中表现较差,因为只有内核的进程调度器才有全力分配多个Cpu时间片.

    Posix线程另一种实现是LinuxThreads,是内核级的线程库,通过clone来创建线程,实现原理是将线程和轻量级进程进行一对一关联

    进程调度器:

    任何时刻只有一个进程处于运行状态,其他处于挂起或者等待状态。进程调度器维护着各种各样的队列。

    进程调度器决定着下一个运行的队列。每个进程可以告诉调度器优先级,调度器在运行的时候也可以动态调整进程的优先级。

    进程调度器一般喜欢I/O密集型操作,在这些进程发起I/O操作后会阻塞,cpu时间占用少,这样其他进程可以更好的运行。进程优先级PR值是调度器分配给进程的时间片,时间片长度是权衡后的结果,进程时间片少,则浪费在上下文切换上的时间比例高,时间片太长,则多任务实时性不够。

    系统负载:

    负载越高代表Cpu无法满足所有的进程处理

    Cpu时间包括:系统时间,用户时间,等待I/O消耗的时间,空闲时间。

    对于一个I/O密集型操作一般WA比较高,但是不代表Cpu就是忙,因为这时系统除了I/O操作没有其它事情做

    假如同时运行一个Cpu密集型操作则WA很低,因为大部分操作进行运算了,用户时间很高。I/0等待操作的时间很短,除非I/O读写操作

    完成才中断,系统时间才有所提高

    进程切换(上下文切换):

    进程调度器在必要的时候挂起正在运行的进程,同时恢复以前挂起的进程。

    进程被挂起的本质将在Cpu寄存器的数据拿出来存储在内核堆栈中,恢复的时候又放入到Cpu寄存器中。

    要提高服务器并发数就是要减少上下文切换,一般就是减少进程,通过线程并和I/O策略来设计并发策略

    这也是Nginx比Apache高效的原因之一。

    IOWAIT:

    代表等待I/O操作完成的时间比例。IOWAIT高不代表I/O出现性能瓶颈,要借助I/O测试和流量问题进行查看。

    IOWAIT来描述Cpu性能,当高的时候,至少说明当前任务的Cpu时间开销相对于I/O操作来说很少,对于依赖磁盘

    操作的应用来看比较正常,因为磁盘操作相对于Cpu来说是比较慢的。

    IOWAIT的值需要根据具体的情况来做分析。

    比如一个下载业务,Nginx启动128个进程,IOWAIT比较高,因为下载服务采用Sendfile,几乎不用用户Cpu时间.

    但是假如Nginx启动8个进程,网络I/O大幅提高,网络流量提升了,原因可能是进程减少了,上下文切换比较少.

    更多的时间可以用在发起sendfile系统调用.所以网络I/O大幅提升,由于磁盘操作存在高速缓存,所以实际的磁盘I/O没有提高,Cpu利用率提升了,所以IOWAIT减少了.

    锁竞争:

    服务器在处理大量并发请求的时候,多个请求处理任务之间也存在一些资源抢占竞争,所以需要一种机制来维持

    一般采用锁机制来控制资源的占用,当一个任务占用资源的时候,锁住资源,这时候其他任务都在等待锁的释放,这就是锁竞争的定义

    系统调用:

    进程有用户态和内核态二种运行模式,进程可以在二种模式下切换,但需要一定开销.

    进程通常运行在用户态.可以使用Cpu和内存来完成一些任务(比如数学计算),而当进程需要对硬件外设进行操作必须切换到内核态,这

    时将有更多的权利控制整个计算机,当在内核态的任务完成后,进程且会用户态.

    进程切换到内核态的过程对于高级语言开发者来说是透明的.程序通过系统调用完成,内核提供一些列的系统调用.

    用户态和内核态的分离,动机主要在于提高系统底层安全以及简化开发模型.』由于系统调用涉及进程从用户态到内核态的切换,导致一定的内存空间交换,即上下文切换,所以系统调用的开销是比较昂贵的.

    内存分配:

    web服务器工作过程中,需要用到大量内存,所以内存的分配和释放及其重要.目前主流的服务器使用各自的策略(改善数据结构和算法复

    杂度减少数据复制时间)来提高效率.比如基于多进程的apache通过内存池管理更加安全,但是对于性能的弥补不是特别高.

    Nginx对于内存的良好表现来至于内存分配策略,它可以使用多线程来处理请求,这使得多个线程之间可以共享资源,从而它的内存使用量大大减少.另外Nginx使用分阶段的内存分配策略,按需分配,及时释放,使得内存使用量保持在很小的范围之内.

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. 我对技术方向的一些反思 (累计阅读 11,320)
  2. Python 多进程日志记录 (累计阅读 7,841)
  3. 有道实习生笔试总结 (累计阅读 5,595)
  4. 从Rails聊聊小公司的研发团队建设 (累计阅读 5,575)
  5. 进程和线程关系及区别 (累计阅读 5,361)
  6. Twitter“鲸鱼”故障技术剖析 (累计阅读 4,122)
  7. 变量在内存中的位置 (累计阅读 3,907)
  8. 一个小小的C 写的web server (累计阅读 3,762)
  9. apache下ab网站压力测试命令的参数、输出结果的中文注解 (累计阅读 3,703)
  10. nginx 利用 rewrite 屏蔽IE浏览器 (累计阅读 3,687)