《构建高性能Web站点》第三章服务器并发处理能力

1.吞吐率

说到Web服务器的并发处理能力,那就一定得有一个量化的描述,我们一般使用单位时间内服务器处理的请求数来描述其并发处理能力,但是听起来有点长,我们习惯称其为吞吐率(Throughput),单位是“reqs/s”。需要注意的是,吞吐率这个概念有时候还用于描述其他指标,比如单位时间内的通信数据量等。

单从定义来看,吞吐率描述了服务器在实际运行期间单位时间内处理的请求数,然而,我们更加关心的是服务器并发处理能力的上限,也就单位时间内服务器能够处理的最大请求数,即最大吞吐率。所以我们普遍使用“压力测试”的方法,通过模拟足够数目的并发用户数,分别持续发送一定的HTTP请求,并统计测试持续的总时间,计算出基于这种“压力”下的吞吐率,即为一个平均计算值。

我们知道在一个含有较多变量的数据模型中求解最优化结果是非常困难的,所以我们一般都简化模型,对同一个特定的有代表性的请求进行压力测试,然后根据需要,对多个请求的吞吐率按照比例计算加权平均值。

压力测试的前提条件

这么一来,我们要统计吞吐率,便存在一些潜在的前提,那就是压力的描述和请求性质的描述。压力的描述一般包括两部分,即并发用户数和总请求数,也就是模拟多少个用户同时向服务器发送多少个请求,随后会有关于并发用户数的详细介绍。

所以,吞吐率的前提包括如下几个条件:
1.并发用户数
2.总请求数
3.请求资源描述

这时你可能有一个实际的问题,假如100个用户同时向服务器分别进行10次请求,与1个用户向服务器连续进行1000次请求,效果一样吗?也就是说给服务器带来的压力一样吗?
这样一来,从微观层面来看,1 个用户向服务器连续进行1000 次请求的过程中,任何时刻服务器的网卡接收缓冲区中只有来自该用户的1个请求,而100个用户同时向服务器分别进行10次请求的过程中,服务器网卡接收缓冲区中最多有100个等待处理的请求,显然这时候服务器的压力更大。

注意区分概念吞吐率(单位时间内请求数量)和并发用户数。

另外值得说明的是,即使我们通过压力测试得出服务器支持的最大并发数,但这与实际并发用户数却是两回事,因为有多少用户同时发来请求并不是服务器所能决定的,该来的总是要来,那是客观存在的。

所以,得出最大并发数的意义,在于了解服务器的承载能力,并且结合用户规模考虑适当的扩展方案。

在刚才讲到并发用户数的时候,我们简单地提到了用户等待时间,这也是压力测试结果中很重要的一个指标。总结一下,我们所关心的时间有以下两种:
● 用户平均请求等待时间
● 服务器平均请求处理时间

用户平均请求等待时间主要用于衡量服务器在一定并发用户数的情况下,对于单个用户的服务质量;而服务器平均请求处理时间与前者相比,则用于衡量服务器的整体服务质量,它其实就是吞吐率的倒数。

简单地说,并发策略的设计就是在服务器同时处理较多请求的时候,如何合理协调并充分利用CPU计算和I/O操作,使其在较大并发用户数的情况下提供较高的吞吐率。

2.CPU并发计算

服务器之所以可以同时处理多个请求,在于操作系统通过多执行流体系设计使得多个任务可以轮流使用系统资源,这些资源包括CPU、内存以及I/O等。

从本质上讲,多进程的好处并不仅仅在于CPU时间的轮流使用,还在于对CPU计算和I/O操作进行了很好的重叠利用,这里的I/O主要是指磁盘I/O和网络I/O,它们的速度和CPU相比,就像老牛漫步和超音速飞机一样相距甚远。所以对于单任务而言,CPU大部分时间空闲,这时候多进程的作用便显得尤为重要。进程的调度由内核来进行,从内核的观点看,进程的目的就是担当分配系统资源的实体。

每个进程都有自己独立的内存地址空间和生命周期。当子进程被父进程创建后,便将父进程地址空间的所有数据复制到自己的地址空间,完全继承父进程的所有上下文信息,它们之间可以通信,但是不互相依赖,也无权干涉彼此的地址空间。

轻量级进程已经允许共享一些资源,比如地址空间、打开的文件等。轻量级进程减少了内存的开销,并为多进程应用程序的数据共享提供了直接支持,但是其上下文切换的开销还是在所难免的。

内核中的进程调度器(Scheduler)维护着各种状态的进程队列。在Linux中,进程调度器维护着一个包括所有可运行进程的队列,称为“运行队列(Run Quere)”,以及一个包括所有休眠进程和僵尸进程的列表。

一个进程被挂起的本质就是将它在CPU寄存器中的数据拿出来暂存在内核态堆栈中,而一个进程恢复工作的本质就是将它的数据重新装入CPU寄存器,这段装入和移出的数据我们称为“硬件上下文”,它也是进程上下文的一部分,除此之外,进程上下文中还包含了进程运行时需要的一切状态信息。

用户态/内核态:
在这里插入图片描述
我们一般采用“锁”机制来控制资源的占用,当一个任务占用资源的时候,我们锁住资源,这时候其他任务都在等待锁的释放,这种现象我们称为锁竞争。

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

1

3.系统调用

4.内存分配

5.持久连接

6.I/O模型

设备的数据输入/输出,也就是I/O(In/Out)操作。事实上,I/O操作根据设备的不同分为很多种类型,比如内存I/O、网络I/O、磁盘I/O。

在介绍I/O模型之前,有必要简单地说说慢速I/O设备和内存之间的数据传输方式。

我们拿磁盘来说,很早以前,磁盘和内存之间的数据传输是需要CPU控制的,也就是说如果我们读取磁盘文件到内存中,数据要经过CPU存储转发,这种方式称为PIO。显然这种方式非常不合理,需要占用大量的CPU时间来读取文件,造成文件访问时系统几乎停止响应。

后来,DMA(直接内存访问,Direct Memory Access)取代了PIO,它可以不经过CPU而直接进行磁盘和内存的数据交换。在DMA模式下,CPU只需要向DMA控制器下达指令,让DMA控制器来处理数据的传送即可,DMA控制器通过系统总线来传输数据,传送完毕再通知CPU,这样就在很大程度上降低了CPU占有率,大大节省了系统资源,而它的传输速度与PIO的差异其实并不十分明显,因为这主要取决于慢速设备的速度。

可以肯定的是,PIO模式的计算机我们现在已经很少见到了。

I/O等待是不可避免的,那么既然有了等待,就会有阻塞,但是注意,我们说的阻塞是指当前发起I/O操作的进程被阻塞,并不是CPU被阻塞,事实上没有什么能让CPU阻塞的,CPU只知道拼命地计算,对于阻塞一无所知。

同步:执行一个操作之后,等待结果,然后才继续执行后续的操作。
异步:执行一个操作后,可以去执行其他的操作,然后等待通知再回来执行刚才没执行完的操作。
阻塞:进程给CPU传达一个任务之后,一直等待CPU处理完成,然后才执行后面的操作。
非阻塞:进程给CPU传达任我后,继续处理后续的操作,隔断时间再来询问之前的操作是否完成。这样的过程其实也叫轮询。

在这里插入图片描述

同步和异步是相对于操作结果来说,会不会等待结果返回。
阻塞和非阻塞是相对于线程是否被阻塞。

参考文章:
https://www.cnblogs.com/Anker/p/5965654.html
https://www.cnblogs.com/George1994/p/6702084.html

同步与异步是对应的,它们是线程之间的关系,两个线程之间要么是同步的,要么是异步的。

阻塞与非阻塞是对同一个线程来说的,在某个时刻,线程要么处于阻塞,要么处于非阻塞。

参考文章:
https://www.cnblogs.com/-900401/p/4015048.html
https://baijiahao.baidu.com/s?id=1612594086537323804&wfr=spider&for=pc

内存映射:

Linux内核提供一种访问磁盘文件的特殊方式,它可以将内存中某块地址空间和我们要指定的磁盘文件相关联,从而把我们对这块内存的访问转换为对磁盘文件的访问,这种技术称为内存映射(Memory Mapping)。
在大多数情况下,使用内存映射可以提高磁盘I/O的性能,它无须使用read()或write()等系统调用来访问文件,而是通过mmap()系统调用来建立内存和磁盘文件的关联,然后像访问内存一样自由地访问文件。

内核缓冲和I/O缓冲:

引入内核缓冲区的目的在于提高磁盘文件的访问性能,因为当进程需要读取磁盘文件时,如果文件内容已经在内核缓冲区中,那么就不需要再次访问磁盘;而当进程需要向文件中写入数据时,实际上只是写到了内核缓冲区便告诉进程已经写成功,而真正写入磁盘是通过一定的策略进行延迟的。

然而,对于一些较复杂的应用,比如数据库服务器,它们为了充分提高性能,希望绕过内核缓冲区,由自己在用户态空间实现并管理I/O缓冲区,包括缓存机制和写延迟机制等,以支持独特的查询机制,比如数据库可以根据更加合理的策略来提高查询缓存命中率。另一方面,绕过内核缓冲区也可以减少系统内存的开销,因为内核缓冲区本身就在使用系统内存。

用户进程是运行在用户空间的,不能直接操作内核缓冲区的数据。 用户进程进行系统调用的时候,会由用户态切换到内核态,待内核处理完之后再返回用户态。例如:read把数据从内核缓冲区复制到进程i/o缓冲区,write把数据从进程i/o缓冲区复制到内核缓冲区,内核缓冲区再和磁盘之间的交换。

在这里插入图片描述

7.服务器并发策略

一个进程处理一个连接,非阻塞I/O
一个线程处理一个连接,非阻塞I/O
一个进程处理多个连接,非阻塞I/O
一个线程处理多个连接,非阻塞I/O

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值