最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • LNMP架构下WEB服务器如何管理及优化内存?

    正文概述 转载于:掘金(王中阳Go)   2021-04-24   468

    总结

    1. Ngnix+php-FPM的工作方式,似乎是LNMP架构最节省系统资源的工作方式。
    2. 当然,具体的技术选型更多的应该参考自己想要实现的业务需求。

    1. 原因:越来越多的并发连接数

    1. 页面的元素增多,交互复杂
    2. 主流浏览器的连接数在增加

    2. 辅助方案:通过WEB前端优化,降低服务器的压力

    1. 减少web请求
    2. 减轻web请求
    3. 合并页面请求

    3. 推荐方案:节约web服务器的内存

    1. prefork MPM(Apache服务器多道处理器模块),多进程工作模式:
      1. 主进程生成后,他先完成初始化的工作,通过fork的方式预先产生一批子进程(子进程复制父进程的内存空间,不需要再做初始化的工作)
      2. 多进程的好处:进程之间的内存数据是互不干扰的。
      3. 优点:成熟稳定,兼容新老版本,不用担心线程安全的问题
      4. 缺点:不适合高并发的业务场景,一个服务进程占很多内存
    2. worker MPM, 多线程和多进程的混合模式
      1. 和prework一样,也预先fork了几个子进程(数量少),然后每个子进程创建几个线程(包含一个监听线程)。每个请求过来,会交给一个线程来服务。(线程比进程轻量级,所以内存占用更少)。
      2. 注意:并没有解决“keep-alive”长连接的问题,只是把对象编程了更轻量级的线程
      3. 疑问:既然多线程轻量级,为什么不完全采用多线程的方式呢?因为多进程能确保程序的稳定性,如果采用单进程多线程的方式,有一个线程挂了,那么该进程下的其他线程也挂了,会导致全军覆没。
      4. 优点:更优秀的内存管理,高并发场景下表现更优秀。
      5. 缺点:需要考虑线程安全问题,需要引入锁,加大cpu的消耗。
    3. event MPM
      1. 和worker的方式很像,最大的差别在于解决了“keep-alive”场景下,长期被占用的线程资源问题。
      2. 注意:event MPM遇到不兼容的模块时会失效,将回退到worker模式,一个工作线程处理一个请求。
      3. Apache的3种模式中,event MPM是最节约内存的。(需要Linux系统对Epoll的支持才能启用)
    4. 使用轻量级的Ngnix作为web服务器
      1. Ngnix本身就是一个轻量级的web服务器,天生萝莉,比Apache要轻量。
      2. Ngnix通过一个进程来服务N个链接,采用的方式不同于Apache的方式。
    5. sendfile节约内存(这个概念非常重要)
      1. sendfile可以减少数据到“用户态内存空间”(用户缓存区)的拷贝,进而减少对内存的占用。
      2. 为了更好的理解上面所说的原理。笔者先引入下面的概念:内核态和用户态的区别,内核态的优先级高Ring0,而用户态(运行态)的优先级低Ring3;并且当执行用户程序是突然中断,运行状态会从“用户态”切换到“内核态”。
      3. 一般情况下,用户态(程序所在的内存空间)不能直接操作(读写等)各种设备(磁盘,网络,终端等)的。需要使用内核作为中间人来完成对设备的操作。
      4. 来吃个栗子(例子)吧:以最简单的磁盘读写为例,从磁盘A读取文件到磁盘B,其过程是这样的:A文件数据从磁盘开始,然后载入到“内核缓冲区”,然后拷贝到“用户缓存区”,这完成了读操作。写操作也是一样的,从“用户缓存区”拷贝到“内核缓冲区”,最后写入到磁盘B中。
      5. 这样读写文件很累吧。有大神提出了要删繁就简,取消“用户缓存区”那部分拷贝工作,引入了MMP(Memory-Mapping,内存映射)的概念。实现原理是这样的:建立一个磁盘空间和内存的直接映射,数据不再拷贝到“用户缓存区”,而是返回一个指向内存空间的指针。这样我们之前的文件拷贝就变成了如下步骤:A磁盘中文件将数据载入到“内核缓冲区”,B磁盘从“内核缓冲区”拷贝写入文件。减少了一次拷贝过程,减少了内存的占用。
      6. 回到正题:简单来说,sendfile的原理和mmp的方式类似,核心也是减少了“内核缓冲区”到“用户缓冲区”的拷贝。
      7. 优点: 不仅节省了内存,还节省了CPU的开销。

    4. 节约web服务器的CPU

    1. 对于web服务器而言,CPU是另一个非常核心的系统资源。就web服务器而言,除了业务程序消耗CPU外,多线程/多进程的上下文切换,也是比较消耗CPU资源的。
    2. 一个进程/线程无法长时间占用CPU,当发生阻塞或者时间片用完时,就无法继续占用CPU,这时会发生时间上下文的切换,即老的时间片切换到新的时间片,也是耗CPU的。
    3. 在并发连接数目很高的情况下,去轮询检测用户建立的连接状态(socket文件描述符),也是消耗CPU的。
    4. 笔者在这里只介绍一下终极问题及解决办法:

    5. 多线程下的锁对CPU的开销

    1. Apache中的worker和event模式,都有采用多线程。多线程因为共享父进程的内存空间,在访问共享数据的时候,就会产生竞争,也就是线程安全问题。因此通常会引入锁(Linux下比较常用的线程相关的锁有互斥量metux,读写锁rwlock等),成功获取锁的线程可以继续执行,获取失败的通常选择阻塞等待。引入锁的机制,程序的复杂度往往增加不少,同时还有线程“死锁”或者“饿死”的风险(多进程在访问进程间共享资源的时候,也有同样的问题)。
    2. 死锁现象(两个线程彼此锁住对方想要获取的资源,相互阻塞等待,永远无法达不到满足条件)
    3. 饿死现象(某个线程,一直获取不到它想要锁资源,永远无法执行下一步)
    4. 为了避免这些锁导致的问题,就不得不加大程序的复杂度,解决方案一般有:
      1. 对资源的加锁,根据约定好的顺序,大家都先对共享资源X加锁,加锁成功之后才能加锁共享资源Y。
      2. 如果线程占有资源X,却加锁资源Y失败,则放弃加锁,同时也释放掉之前占有的资源X。
    5. 在使用PHP的时候,在Apache的worker和event模式下,也必须兼容线程安全。通常,新版本的PHP官方库是没有线程安全方面的问题,需要关注的是第三方扩展。PHP实现线程安全,不是通过锁的方式实现的。而是为每个线程独立申请一份全局变量的副本,相当于线程的私人内存空间,但是这样做相对多消耗一些内存。这样的好处:不需要引入复杂的锁机制实现,也避免了锁机制对CPU的开销。

    参考文档

    本文参考链接,感谢作者 ,节选自上文链接的思路


    起源地下载网 » LNMP架构下WEB服务器如何管理及优化内存?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元