e-works数字化企业网  »  文章频道  »  基础信息化  »  终端和服务器

浅谈如何提高服务器并发处理能力

2017/10/5    来源:简书    作者:佚名      
关键字:服务器  服务器处理能力  
服务器的本质工作就是,争取以最快的速度将内核缓冲区中的用户请求数据一个不剩地都拿出来,然后尽快处理,再将响应数据放到一块又能够与发送数据的缓冲区中,接着处理下一拨请求。
    目录
 
    (一)什么是服务器并发处理能力
 
    (二)有什么方法衡量服务器并发处理能力
 
    1.吞吐率
 
    2.压力测试
 
    (三)怎么提高服务器的并发处理能力
 
    1,提高CPU并发计算能力
 
    (1)多进程&多线程
 
    (2)减少进程切换,使用线程,考虑进程绑定CPU
 
    (3)减少使用不必要的锁,考虑无锁编程
 
    (4)考虑进程优先级
 
    (5)关注系统负载
 
    (6)关注CPU使用率,除了用户空间和内核空间的CPU使用率以外,还要关注I/O wait
 
    2,减少系统调用
 
    3,考虑减少内存分配和释放
 
    (1)改善数据结构和算法复制度
 
    (2)使用内存池
 
    (3)考虑使用共享内存
 
    4,考虑使用持久连接
 
    5,改进I/O模型
 
    (1)DMA技术
 
    (2)异步I/O
 
    (3)改进多路I/O就绪通知策略,epoll
 
    (4)Sendfile
 
    (5)内存映射
 
    (6)直接I/O
 
    6,改进服务器并发策略
 
    (1)一个进程处理一个连接,非阻塞I/O,使用长连接
 
    (2)一个进程处理多个连接,异步I/O,使用长连接
 
    7,改进硬件环境
 
    (一)什么是服务器并发处理能力?
 
    一台服务器在单位时间里能处理的请求越多,服务器的能力越高,也就是服务器并发处理能力越强
 
    服务器的本质工作就是,争取以最快的速度将内核缓冲区中的用户请求数据一个不剩地都拿出来,然后尽快处理,再将响应数据放到一块又能够与发送数据的缓冲区中,接着处理下一拨请求。
 
    (二)有什么方法衡量服务器并发处理能力?
 
    一,吞吐率
 
    量化指标:吞吐率,单位时间里服务器处理的最大请求数,单位req/s
 
    再深入一些,HTTP请求通常是对不同资源的请求,也就是请求不同的URL,有的是请求图片,有的是获取动态内容,有的是静态页面,显然这些请求所花费的时间各不相同,而这些请求再不同时间的组成比例又是不确定的,所以实际情况下的吞吐率是非常复杂的。
 
    正因为这些请求的性质不同,所以服务器并发能力强弱关键在于如何正对不同的请求性质来设计最优并发策略。如一台服务器处理诸多不同性质的请求,在一定程度上使得服务器的性能无法充分发挥。而并发策略的设计就是在服务器同时处理较多请求时,合理协调和充分利用CPU计算和I/O操作,使其在较大并发用户数的情况下提供较高吞吐率。
 
    另外,实际上多少用户同时发来请求并不是服务器所能决定的,一旦实际并发用户数过多,则势必影响站点质量。所以得出最大并发用户数的意义,在于了解服务器的承载能力,并且结合用户规模考虑适当的扩展方案。
 
    在考虑用户模型时,用户访问web站点时通常使用浏览器,浏览器对于同一域名下URL的并发下载是多线程的,不过有最大限制的,所以前面说到的最大并发数,具体到真实的用户,可能不是一对一的关系。
 
    而从服务器角度,实际并发用户数的可以理解为服务器当前维护的代表不同用户的文件描述符总数,也就是并发连接数。服务器一般会限制同时服务的最多用户数,比如apache的MaxClents参数。
 
    这里再深入一下,对于服务器来说,服务器希望支持高吞吐率,对于用户来说,用户只希望等待最少的时间,显然,双方不能满足,所以双方利益的平衡点,就是我们希望的最大并发用户数。
 
    二,压力测试
 
    有一个原理一定要先搞清楚,假如100个用户同时向服务器分别进行10个请求,与1个用户向服务器连续进行1000次请求,对服务器的压力是一样吗?实际上是不一样的,因对每一个用户,连续发送请求实际上是指发送一个请求并接收到响应数据后再发送下一个请求。这样对于1个用户向服务器连续进行1000次请求,任何时刻服务器的网卡接收缓冲区中只有1个请求,而对于100个用户同时向服务器分别进行10个请求,服务器的网卡接收缓冲区最多有100个等待处理的请求,显然这时的服务器压力更大。
 
    压力测试前提考虑的条件:
 
    (1)并发用户数
 
    (2)总请求数
 
    (3)请求资源描述
 
    并发用户数是指某一时刻同时向服务器发送请求的用户总数。
 
    压力测试中关系的时间有细分以下2种,
 
    (1) 用户平均请求等待时间
 
    (这里暂不把数据在网络的传输时间,还有用户PC本地的计算时间计算入内)
 
    (2) 服务器平均请求处理时间
 
    用户平均请求等待时间主要用于衡量服务器在一定并发用户数下,单个用户的服务质量;而服务器平均请求处理时间就是吞吐率的倒数,一般来说,用户平均请求等待时间=服务器平均请求处理时间*并发用户数
 
    (三)怎么提高服务器的并发处理能力呢?
 
    一,提高CPU并发计算能力
 
    服务器之所以可以同时处理多个请求,在于操作系统通过多执行流体系设计使得多个任务可以轮流使用系统资源,这些资源包括CPU,内存以及I/O.这里的I/O主要指磁盘I/O,和网络I/O
 
    (1)多进程&多线程
 
    多执行流的一般实现就是进程。多进程的好处不仅在于CPU时间的轮流使用,还在于对CPU计算和I/O操作进行很好的重叠利用,这里的I/O主要指磁盘I/O和网络I/O.实际上,大多数进程的时间主要消耗在I/O操作上,现代计算机的DMA技术可以让CPU不参与I/O操作的全过程,比如进程通过系统调用,使得CPU向网卡或者磁盘等I/O设备发出指令,然后进程被挂起,释放出CPU资源,等待I/O设备完成工作后通过中断来通知进程重新就绪。对于单任务而言,CPU大部分时间空闲,这时候多进程的作用尤为重要。
 
    而且进程的优越性还在其相互独立带来的稳定性和健壮性方面。
 
    进程的缺点:每个进程都有自己的独立空间和生命周期。当子进程被父进程创建后,便将父进程地址空间的所有数据复制到自己的地址空间中,完全继承父进程的上下文信息。进程的创建使用fork()系统调用,还是有一定的开销的,这个开销若太频繁,其可能成为影响性能的主要因素。
 
    那是否越多进程数越好呢?请看下面讨论:
 
    (2)减少进程切换
 
    进程拥有独立的内存空间,每个进程都只能共享CPU寄存器。一个进程被挂起的本质是将它在CPU寄存器中的数据拿出来暂存在内存态堆栈着那个,而一个进程恢复工作的本质就是把它的数据重新装入CPU寄存器,这段装入和移出的数据称为“硬件上下文”,除此之外,进程上下文还包含进程允许所需的一切状态信息。
 
    当硬件上下文频繁装入和移出时,所消耗的时间是非常可观的。可用Nmon工具监视服务器每秒的上下文切换次数。
 
    为了尽量减少上下文切换次数,最简单的做法就是减少进程数,尽量使用线程并配合其它I/O模型来设计并发策略。
 
    还可以考虑使用进程绑定CPU技术,增加CPU缓存的命中率。若进程不断在各CPU上切换,这样旧的CPU缓存就会失效。
 
    (3)减少使用不必要的锁
 
    服务器处理大量并发请求时,多个请求处理任务时存在一些资源抢占竞争,这时一般采用“锁”机制来控制资源的占用,当一个任务占用资源时,我们锁住资源,这时其它任务都在等待锁的释放,这个现象称为锁竞争。
 
    通过锁竞争的本质,我们要意识到尽量减少并发请求对于共享资源的竞争。比如在允许情况下关闭服务器访问日志,这可以大大减少在锁等待时的延迟时间。要最大程度减少无辜的等待时间。
 
    这里说下无锁编程,就是由内核完成这个锁机制,主要是使用原子操作替代锁来实现对共享资源的访问保护,使用原子操作时,在进行实际的写操作时,使用了lock指令,这样就可以阻止其他任务写这块内存,避免出现数据竞争现象。原子操作速度比锁快,一般要快一倍以上。
 
    例如fwrite(), fopen(),其是使用append方式写文件,其原理就是使用了无锁编程,无锁编程的复杂度高,但是效率快,而且发生死锁概率低。
 
    (4)除了上述所说,要优化服务器的并发处理能力,还要考虑进程优先级(可由进程决定),进程调度器会动态调整运行队列中进程的优先级,通过top观察进程的PR值
 
    (5)还要关注系统负载,可在任何时刻查看/proc/loadavg, top中的load average也可看出
 
    (6)还要关注CPU使用率,除了用户空间和内核空间的CPU使用率以外,还要关注I/O wait,它是指CPU空闲并且等待I/O操作完成的时间比例。(top中查看wa的值)
 
    二,考虑系统调用
 
    进程若运行在用户态,这时可使用CPU和内存来完成一些任务,而当进程需要对硬件外设进行操作的时候(如读取磁盘文件,发送网络数据等),就必须切换到内核态,这时它拥有更多的权力来操纵整个计算机。
 
    而系统调用涉及进程从用户态到内核态的切换,导致一定的内存交换,这也是一定程度上的上下文切换,所以系统调用的开销通常认为比较昂贵的。
 
    所以要减少不必要的系统调用,也是服务器性能优化的一个方面。例如在apache中,修改httpd.conf文件,可以减少对文件路径中各级目录下检测是否存在.htacess文件这个open()系统调用; 还可以修改httpd.conf文件来减少多余的gettimeofday()系统调用。
 
    但有时若使用一些简单的系统调用能代替大量的逻辑运算,这样反而使用系统调用更能优化性能

责任编辑:李欢
本文为授权转载文章,任何人未经原授权方同意,不得复制、转载、摘编等任何方式进行使用,e-works不承担由此而产生的任何法律责任! 如有异议请及时告之,以便进行及时处理。联系方式:editor@e-works.net.cn tel:027-87592219/20/21。
e-works
官方微信
掌上
信息化
编辑推荐
新闻推荐
博客推荐
视频推荐