服务器高并发解决方案

服务器高并发解决方案,第1张

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

服务器的并发处理能力如何

服务器在单位时间内能够处理的请求越多,服务器的能力就越高,即服务器的并发处理能力越强。

有什么方法可以衡量服务器的并发处理能力

1。吞吐率

吞吐率,单位时间内服务器处理的最大请求数,以请求/秒为单位。

从服务器的角度来看,实际的并发用户数可以理解为服务器当前维护的代表不同用户的文件描述符的总数,即并发连接数。一般服务器会限制同时服务的最大用户数,比如apache的MaxClents参数。

让我们在这里深入一下。对于服务器来说,服务器希望支持高吞吐量。对于用户来说,用户只想等待最少的时间。显然双方都无法满足,所以双方利益的平衡才是我们想要的最大并发用户数。

2。压力测试

有一个原则必须先明确。如果100个用户同时向服务器发出10个请求,那么对服务器的压力是否和1个用户连续向服务器发出1000个请求一样?实际上是不一样的,因为对于每个用户来说,连续发送请求实际上就是发送一个请求,收到响应数据再发送下一个请求。这样,如果一个用户连续向服务器发出1000个请求,那么服务器的NIC接收缓冲区在任何时候都只有一个请求,而对于100个用户同时向服务器发出10个请求,服务器的NIC接收缓冲区最多会有100个请求等待处理,这显然会使服务器的压力更大。

压力测试之前要考虑的条件

并发用户数:指某一时刻同时向服务器发送请求的用户总数(HttpWatch)。

  • 请求总数
  • 请求资源描述
  • 等待时间(用户等待时间)
  • 用户请求的平均等待时间
  • 平均服务器请求处理时间
  • 硬件环境
  • 压力测试中关注的时间细分为以下两种:

  • 用户请求的平均等待时间(这里不包括数据在网络中的传输时间和用户PC的本地计算时间)。
  • 平均服务器请求处理时间
  • 平均用户请求等待时间主要用来衡量一定并发用户数下单个用户的服务质量。平均服务器请求处理时间是吞吐率的倒数。一般来说,平均用户请求等待时间=平均服务器请求处理时间*并发用户数。

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

    1。提高CPU的并发计算能力

    服务器之所以可以同时处理多个请求,是因为 *** 作系统通过多执行流架构设计,可以让多个任务轮流使用系统资源,包括CPU、内存和I/O,这里的I/O主要指磁盘I/O和网络I/O。

    多进程和多线程

    多执行流的一般实现是进程,多进程的好处是可以轮流使用CPU时间和重叠CPU计算和IO *** 作。这里的IO主要是指磁盘IO和网络IO,和CPU相比慢得可怜。

    事实上,大多数进程主要把时间花在I/O *** 作上。现代计算机DMA技术可以使CPU不参与I/O *** 作的全过程。比如进程通过系统调用让CPU向网卡或磁盘等I/O设备发出指令,然后进程挂起,释放CPU资源。在I/O设备完成它们的工作后,中断通知进程它已经准备好了。对于单个任务来说,CPU大部分时间是空闲的空,这个时候多进程的作用就显得尤为重要。

    多进程不仅可以提高CPU的并发性。其优势还体现在独立的内存地址空和生命周期带来的稳定性和健壮性,其中一个进程的崩溃不会影响到另一个进程。

    但是该方法也有以下缺点:

  • fork()系统调用开销很大:prefork
  • 进程间调度和上下文切换成本:减少进程数量。
  • 巨大的内存复制:共享内存
  • IPC编程比较麻烦。
  • 过程切换减少

    当频繁加载和移除硬件上下文时,所消耗的时间是相当可观的。Nmon工具可用于监控服务器每秒的上下文切换次数。为了最大限度地减少上下文切换的次数,最简单的方法就是减少进程的数量,尽量使用线程并与其他I/O模型合作设计并发策略。

    还可以考虑使用进程绑定CPU技术,提高CPU缓存的命中率。如果进程一直在每个CPU上切换,旧的CPU缓存将变得无效。

    减少不必要的锁的使用

    当服务器处理大量并发请求时,当多个请求处理任务时,会出现一些资源抢占竞争。此时,一般采用“锁”机制来控制资源占用。当一个任务占用资源时,我们锁定资源,而其他任务正在等待锁的释放。这种现象被称为锁竞争。

    通过锁竞争的本质,我们应该认识到,我们应该尽量减少对共享资源的并发请求的竞争。比如在允许的情况下关闭服务器访问日志,这样可以大大减少锁等待时的延迟时间。尽量减少无辜的等待时间。

    这里的无锁编程是指内核完成这种锁机制,主要是用原子 *** 作代替锁来实现共享资源的访问保护。当使用原子 *** 作时,在实际的写 *** 作中使用锁指令,这样可以防止其他任务写这个内存,避免数据竞争。原子 *** 作速度比锁快,通常快一倍以上。

    比如fwrite(),fopen(),使用append写文件,使用无锁编程,复杂度高,效率高,死锁概率低。

    考虑进程优先级

    进程调度器会动态调整运行队列中进程的优先级,通过top观察进程的PR值。

    考虑系统负载

    可以随时查看/proc/loadavg,也可以在top中看到负载平均值。

    考虑CPU利用率

    除了users空和cores空之间的CPU利用率,还要注意I/Owait,指的是CPU空空闲等待I/O *** 作完成的时间比例(见top中wa的值)。

    2。考虑减少内存分配并释放

    在服务器的工作过程中,需要大量的内存,这就使得内存的分配和释放显得尤为重要。中间临时变量的内存分配和数据复制时间可以通过改进数据结构和算法复制系统来适当减少,服务器自己使用自己的策略来提高效率。

    比如Apache在运行之初就申请了大量的内存作为内存池,如果以后需要,可以直接从内存池中获取,不需要重新分配,避免了频繁的内存分配和释放带来的内存排序时间。

    例如,nginx使用多线程来处理请求,这样多个线程就可以共享内存资源,从而大大降低其整体内存使用量。此外,Nginx的分阶段内存分配策略,按需分配,及时释放,使内存占用保持在一个小范围内。

    另外,还可以考虑共享内存。共享内存是指在多处理器计算机系统中,可以由不同的中央处理器(CPU)访问或由不同的进程共享的大容量内存。这是一种非常快速的进程通信方式。

    但是使用共享内存也有一个缺点,就是多机使用时很难统一数据。

    命令shellipcs可以用来显示系统下共享内存的状态。函数shmget可以创建或打开一个共享存储区。函数shmat将一个现有的共享内存段连接到这个进程空。函数shmctl可以在共享内存段上执行各种 *** 作。函数shmdt分隔共享内存。

    3。考虑使用持久连接

    持久连接也是长连接。它是一种常见的TCP通信方式,即在不断开连接的情况下,在一个TCP连接中连续发送多个数据。相反的方式叫做短连接,即连接建立后,发送一个数据后又断开,然后重新建立连接发送下一个数据,如此循环往复。是否使用持久连接完全取决于应用程序的特性。

    从性能上看,建立TCP连接的 *** 作本身就是一笔不小的开销。如果允许,连接数越少,性能越好。特别是对于密集图片或网页等小数据请求的处理,有明显的加速作用。

    长HTTP连接需要浏览器和web服务器的配合。目前浏览器普遍支持长连接,表现在其发送的HTTP请求头中关于长连接的语句,如下:Connection:Keep-Alive。主流web服务器都支持长连接。例如,在apache中,您可以关闭KeepAlive来关闭长连接。

    对于长连接的有效使用,重点是长连接超时的设置,即长连接什么时候关闭?Apache的默认设置是5s。如果这个时间设置太长,可能会导致无效的资源占用,维护大量的空空闲进程,影响服务器性能。

    4。改进I/O模型

    I/O *** 作根据设备的不同可以分为很多类型,比如内存I/O、网络I/O、磁盘I/O,对于网络I/O和磁盘I/O,它们的速度要慢很多,虽然磁盘I/O可以通过使用RAID磁盘阵列的并行磁盘来加速。购买大连专属网络带宽,使用高带宽网卡,可以提高网络I/O的速度。

    但是这些I/O *** 作需要内核系统调用来完成,而这些又需要CPU来调度,这就使得CPU不得不浪费宝贵的时间来等待缓慢的I/O *** 作。我们希望CPU能够花足够的时间来调度i/O *** 作。如何让高速的CPU和慢速的I/O设备更好的协同工作,是现代计算机一直在讨论的话题。各种I/O模型的本质区别在于CPU的参与方式。

    1。DMA技术

    I/O设备和存储器之间的数据传输由DMA控制器完成。在DMA模式下,CPU只需要向DMA发出命令,让DMA控制器处理数据传输,可以大大节省系统资源。

    2。异步输入/输出

    异步I/O是指在主动请求数据后,可以继续处理其他任务,然后等待I/O *** 作的通知,这样在读写数据时进程就不会被阻塞。

    异步I/O是非阻塞的。当函数返回时,真正的I/O传输已经完成,这使得CPU处理和I/O *** 作重叠得很好。

    3。I/O多路复用

    epoll服务器必须同时处理大量的文件描述符。如果采用同步非阻塞I/O模型,如果同时接收到来自TCP连接的数据,那么接收数据的方法必须依次调用到每个socket,这些socket是否有可接收的数据,必须询问一次。

    如果大多数套接字没有数据要接收,那么进程会浪费大量的CPU时间来检查这些套接字是否有数据要接收。多通道I/O就绪通知的出现为检查大量文件描述符的就绪性提供了高性能的方案。它允许一个进程通过一种方法同时监控所有的文件描述符,并且可以快速获取所有就绪的文件描述符,然后只为这些文件描述符访问数据。

    Epoll可以同时支持水平触发和边沿触发。理论上,边缘触发具有更高的性能,但代码实现复杂,因为任何意外的丢失事件都会导致请求处理错误。

    epoll有两个主要改进:

    Epoll只告诉就绪文件描述符,当调用epoll_wait()来获取文件描述符时,它返回一个表示就绪描述符数量的值,而不是实际的数量。然后,你只需要到epoll指定的一个数组,依次获取对应数量的文件描述符。这里使用了内存映射(mmap)技术,完全节省了系统调用时复制这些文件描述符的开销。

    Epoll采用基于事件的就绪通知方法。它通过epoll_ctrl()预先注册每个文件描述符,一旦一个文件描述符准备好了,内核就会采用类似回调的回调机制,在进程调用epoll_wait()时得到通知。

    IO模型请参考前面写的相关文章JavaNIO.2对于epoll,请参考之前的文章选择、轮询和epoll简介。

    4。发送文件

    大多数时候,我们从服务器请求静态文件,比如图片、样式表等。在处理这些请求时,磁盘文件的数据首先经过内核缓冲区,然后到用户的内存空。不做任何处理,发送到网卡对应的内核缓冲区,然后发送到网卡进行传输。

    Linux提供了sendfile()系统调用,即直接将磁盘文件的特定部分传递给代表客户端的socket描述符,从而加快静态文件的请求速度,减少CPU和内存开销。

    适用场景:对于请求量较小的静态文件,sendfile的作用不太明显,因为发送数据在整个过程中所占的比例远小于大文件请求。

    5。内存映射

    Linux内核提供了一种访问磁盘文件的特殊方式。它可以将内存中的某个地址空与我们指定的磁盘文件关联起来,这样对这个内存的访问就可以转化为对磁盘文件的访问。这种技术被称为内存映射。

    在大多数情况下,内存映射可以提高磁盘I/O的性能,不使用read()或write()等系统调用来访问文件,而是使用mmap()系统调用来建立内存和磁盘文件之间的关联,然后可以像访问内存一样自由地访问文件。

    缺点:处理大文件时,内存映射会导致内存开销大,得不偿失。

    6。直接输入/输出

    在linux2.6中,内存映射和直接访问文件没有本质区别,因为数据需要复制两次,即磁盘和内核缓冲区之间以及内核缓冲区和用户态内存空。

    引入内核缓冲区的目的是为了提高磁盘文件的访问性能。但是对于一些复杂的应用,比如数据库服务器,为了进一步提高性能,他们想绕过内核缓冲区,自己实现和管理用户状态空之间的I/O缓冲区。例如,数据库可以根据更合理的策略来提高查询缓存命中率。另一方面,绕过内核缓冲区也可以减少系统内存的开销,因为内核缓冲区本身就使用系统内存。

    在Linuxopen()系统调用中增加参数选项O_DIRECT,可以绕过内核缓冲区直接访问文件,实现直接I/O。

    在Mysql中,对于Innodb存储引擎,它自己管理数据和索引的缓存,可以在my.cnf配置中分配raw分区跳过内核缓冲区,实现直接I/O。

    改进服务器并发策略

    服务器并发策略的目的是使I/O *** 作和CPU计算尽可能重叠。一方面,CPU在等待I/O时不能空闲,另一方面,CPU在I/O调度上花费的时间要尽可能少。

    进程处理连接,不阻塞I/O

    这样,当多个并发请求同时到达时,服务器必须准备多个进程来处理这些请求。其进程的开销限制了其并发连接数。不过从稳定性和兼容性来看,还是比较安全的。任何子进程崩溃都不会影响服务器本身,父进程可以创建一个新的子进程。这种策略的一个典型例子是Apache的fork和prefork模型。对于并发数不高(比如小于150)且Apache其他功能依赖于它的应用,还是可以选择Apache的。

    一个线程处理一个连接,并且不阻塞IO

    此方法允许在一个进程中由多个线程处理多个连接,一个线程处理一个连接。Apache的worker模型就是一个典型的例子,这使得它能够支持更多的并发连接。但是这种模式的整体性能不如prefork,所以一般不选择工作者模式。

    一个进程处理多个连接,异步I/O

    一个线程同时处理多个连接,潜在的先决条件是使用IO多路复用就绪通知。在这种情况下,处理多个连接的进程称为工作进程或服务进程。worker的数量是可以配置的,比如Nginx中的worker_processes4。

    一个线程处理多个连接,异步IO

    即使有高性能IO多路复用就绪通知,等待磁盘IO也是不可避免的。更有效的方法是对磁盘文件使用异步IO。目前,很少有Web服务器真正支持这种异步IO。

    6。改善硬件环境

    还有一点要提的是硬件环境。服务器的硬件配置通常是提高应用程序性能的最直接和最简单的方法,这称为纵向扩展。这里就不讨论了。

    Dataintheworld在全球120多个国家部署数据中心,在全球多个国家提供海外服务器租赁。所有服务器都可以根据需求配置大带宽、大流量。美国G口独享大带宽服务器,从此告别网络拥堵;

    欢迎分享,转载请注明来源:内存溢出

    原文地址: http://www.outofmemory.cn/zz/746561.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-04-29
    下一篇 2022-04-29

    发表评论

    登录后才能评论

    评论列表(0条)

    保存