服务器并发处理能力
2019-07-24 17:59:43 0 举报
AI智能生成
构建高性能web服务-服务器并发处理能力-学习整理
作者其他创作
大纲/内容
压测的前提
了解压力来自哪里
压力描述
请求性质描述
并发用户数(概念)
并发访问数(概念)
测试用具
LoadRunner
ab
cpu并发以及进程线程概念和在内核中的表示
吞吐率
每秒梳理请求数量
req/s
吞吐率和压力测试
最大吞吐率来标识服务器的处理能力
简化模型
对一个特定的有代表性的请求进行压力测试
然后对多个请求计算加权平均值
针对不同的请求特性来涉及最优并发策略
一台服务器要同时处理不同的请求,导致一定程度上,一台机器的性能无法充分发挥
这个是不是就为什么要拆分微服务,尽量让业务粒度细化,让一台机器的请求
让一台机器的请求尽量处理类似的事
压力测试的前提
前提
压力的描述
并发用户数
总请求数
请求性质的描述
请求的URL代表的资源
1kb大小的静态文件
包含10次数据库查询的动态内容
并发用户数
一个用户请求1000次 vs 10个用户请求100次
缓冲区一直只有1个用户的请求
网卡缓冲区最多有10个等待处理的请求
吞吐率是实在一定并发用户数的情况下,服务器处理请求能力的量化体现
服务器和用户双方所期待的最大利益
并发数增大会导致服务器处理能力下降
并发数小客户得到反馈更快
时刻保持大量的服务器会导致资源浪费
所以服务是否需要考虑支持动态扩容
服务处理能力
并发用户数
并发连接数
当请求性质的描述是1kb大小的静态文件,则最大并发用户数客户大于并发连接数
web服务器做的工作的本质是
以最快的速度从内核缓冲区将用户的请求拿过来处理完,再响应到发送缓存中区
让用户的请求再内核处理时间最短
Apache 的 mod_status
请求等待时间
用户平均请求等待时间
多并发下,由于线程交错使用cpu时间片,导致处理时长拉长
服务器平均请求处理时间
很亮服务器的整体服务质量,吞吐率的倒数
硬件环境
压力测试
工具
Apache自带的ab
命令 ab
ab -n1000 -c10 http://localhost/test.htm
-n总请求数
-c并发用户数
具体参数和返回说明 P46
LoadRunner
Jmeter
并发数增长带来 req/s的提升,吞吐量在一定量之后会下降,用户平均等待时间也会增加
评估各种性质的并发请求
比如插入,查询,用时不同,io量不同,处理时长不同
CPU并发计算
进程
使用现代计算机的DMA技术可以让CPU不参与IO的全过程
大多数进程的资源和时间都消耗在了IO上
子进程创建会复制父进程的上下文
造成系统开销
轻量级进程
进程之间相互独立
无法很好的维护共享空间
内存的大量消耗会导致性能提升的压制因素
稳定性和健壮性
线程
Linux 定义了线程接口 pthread
从内核角度看,多线程只是一个普通的进程
由用户调用库函数,模拟实现的多执行流
多线程的管理完全在用户态完成
SMP中表现较差
因为只有内核的进程调度器才有权利分配多个CPU的时间
POSIX线程的另一种是现实LinuxThreads
内核级线程
实现原理
将线程和轻量级进程进行一对一关联
每个线程实际上就是一个轻量级进程
让线程完全由内核的进程调度器来管理
对SMP支持好
内核线程
线程管理由内核来进行
LinuxThread加入了glibc libc的目前版本
在一些系统中,内核线程被支持,线程管理由内核来进行
进程调度器
单CPU(应该是和核数有关)
进程调度器维护各种状态的进行队列
运行队列
休眠进程和僵尸进程队列
根据进程优先级进行运行
top
进程优先级
Priority
PR
PR的单位是时钟个数
这个具体取决于CPU和操作系统
比如Linux一个时钟10ms,则PR15代表当前线程的时间片是150ms
Linux2.6的进程调度器更加偏爱IO密集型进程,因为发起IO操作之后会阻塞,不会占用CPU太多时间
关于这点,之前有提到,IO操作一般是分发给其他硬件处理读写,CPu不占用太多时间
传统的Unix中
进程调度器为所有进程计算nice值的时候,需要锁住进程表
对于多处理的SMP来说,其他CPU因为锁表无法切换进程
商业化操作系统和LInux中,给每个处理器分配一个队列,互不影响
问题:如何更好的理解和处理
CPU密集型程序
IO密集型程序
系统负载
查看/proc/loadavg
可以了解到运行队列的情况
2/2321
2321此时的进程总数 , 2 代表此时运行队列中的进程数
0.42 0.33 0.28
系统负载
系统最近1分钟,5分钟 15分钟的系统负载
其他查看命令
top
w
使用循环累加器来增加系统负载
测试系统负载能力
进程切换
进程调度器需要在合适的时间挂起正在运行的进程,同时恢复某个进程
上下文切换
进程拥有自己独立的进程空间
但是每个进程只能共享CPU寄存器
一个进程被挂起的本质,就是将它在CPU寄存器中的数据拿出来,暂存在内核态堆栈中,而进程恢复就是放进寄存器
Nmon工具见识服务器每秒上下文切换次数
用apache进行压力测试
使用prefork模式
通过一个父进程先创建一定数量的子进程,让子进程accept竞争用户的请求,一旦acceprt成功,可以处理
每个子进程可以处理的请求由MaxRequestsPreChild进行配置
查看某时刻的httpd进程数
ps afx | grep httpd | wc -l
理解什么是httpd进程数,应该是只有一个
通过线程拓展处理能力
参数
RES
物理内存空间
SWAP
虚拟内存大小
VIRT
RES+SWAP
如果希望支持较大的并发数
要尽量减少上下文切换次数
58页和大脑的对比还是很有意思,值得琢磨
IOWait
CPU空闲并且等待IO操作完成的时间比例
衡量CPU性能
59
锁竞争
系统调用
运行模式
用户态
内核态
一般情况下,用户态,需要对硬件外设进行操作的时候,比如读写磁盘文件,发送网络数据等 切换到内核态
提高系统底层安全性和简化开发模型
存在一定的内存空间交换,一定程度上的上下文切换
系统调用的开销通常比较昂贵
减少系统调用
内存分配
对于传统应用,主要开销在临时变量的内存分配和数据复制时间
通过改善数据结构和算法复杂度来适当减少数据复制时间
apache 在运行时内存使用量非常大
多进程模型
基于内存池策略的内存管理方案
将抽象出来后移入APR库中作为通用内存管理模块
所以在运行开始就需要申请大量内存作为内存池
同样是单进程模型的Nginx,内存量使用更小
Nginx
使用多线程来处理请求,让多个请求之间可以共享内存资源
从而减少内存使用量
内存分配策略是web服务器并发处理能力的重要保障
子主题
持久连接
长连接
TCP通信的一种普通方式
在一次TCP连接中发送多次数据而不断开连接
建立TCP连接操作本身是一项不小的开销,所以在允许的情况下,尽量减少连接
对于密集型图片或者网页小数据请求有明显加速作用
Connection: Keep-Alive
浏览器支持配置
Client端配置
Apache中修改httpd.conf中的 KeepAliveTimeOut 30来修改
默认5秒
长连接超时时间不用设置过长,会导致资源无法有效占用,引发的损失超过了因为重复连接造成的损失
尽量减少连接次数,重用连接通道
IO模型
IO操作根据设备不同分为多种
内存IO
较少提及
速度相对比较快
网络IO
购买独享带宽和高带宽网络适配器
磁盘IO
使用RAID阵列,可以并行访问磁盘增加IO速度
由于IO操作需要内核系统调用来完成,CPU需要等待
尽管我们利用多进程等方式来利用空闲的CPU
本质在于CPU的参与模式
PIO和DMA
PIO
内存和磁盘之间的数据传输需要通过CPU控制(很早之前)
需要占用大量的CPU时间,导致文件访问时系统几乎停滞响应
DMA
Direct Memory Access
内存直接访问
CPU向DMA控制器发命令
DMA主要用来降低CPU的占有率
同步阻塞IO
类型
web服务器等待用户访问
IO等待是不可避免的,阻塞是指发起IO操作的进程被阻塞,而不是CPU被阻塞
同步非阻塞IO
两种操作,一种是等待数据的就绪,另一种是等待数据的复制
对于网络IO来说,前者需要的时间更长
非阻塞IO通过多次轮询来确认数据是否就绪
比如导入
一般针对网络IO有效
?
多路IO就绪通知
检查文件描述符是否就绪
减少对socket调用数据接收的方法进行检查
多路IO就绪通知允许用一种方法同时监视所有文件描述符
这个只是帮助我们快速获取数据就绪状态,实际数据海市需要选择阻塞或者非阻塞
感觉是对应了观察者模式,多了一层监视器来监视数据就绪状态,同时简化监视器
其他知识见76页
内存映射
将内存中某快递至空间和我们要指定的磁盘文件相关联,从而把我们对这块内存的访问转换为对底盘文件的访问
内存映射类型
共享型
可写
私有型
只读
Apache2.x中使用了内存映射
Apache对于较小的静态文件,选择使用内存映射来读取
直接IO
Linux2.6中 内存映射和直接访问文件在本质上没有差异
数据从进程用户内核空间到磁盘需要经过两次复制
磁盘与内核缓冲区
内核缓冲区与用户态内存空间
引入内核缓冲区的目的在于提高磁盘文件的访问性能,因为当进程需要读取磁盘文件是,如果文件内容已经在缓存空间了就不需要再次访问磁盘
对于一些复杂的应用,比如数据库服务器,为了充分提升性能,希望绕过内存缓冲区,有自己在用户态空间时间并管理IO缓冲区
缓存机制
写延迟机制
Mysql的Innodb存储引擎,其自身可以进行数据和索引的缓存管理
可以配置绕过内存缓冲区
NIO,AIO,BIO
收藏
收藏
0 条评论
下一页