小服务器(1G内存)php7.1-fpm mysql nginx的简单优化记录

起因:

#。一台1G内存的服务器,出现MYSQL自动停止的情况。

过程:

#。查MYSQL日志:/var/log/mysql/error.log,INNODB的一个初始化错误,导致开始shutting down

4c532a057d9856e01faac3d17e6f565f.png

#。开始错误的认为是MYSQL相关的参数设置错误,尝试调试了相关参数后,重启。

    ##。后来先重启起来使用,没过多久,情况重现。

    ##。发现出现这个情况的,一般是在用户上传大文件EXCEL导入,就出现。

    ##。而且出现这个情况的那一会儿,马上重启MYSQL是失败的,尝试先重启了PHP7.1-FPM,才能成功。OK,定位问题出在PHP7.1-FPM这里。

#。先从PHP程序入手调试解决问题:

    ##。尝试在CI3中找内存调试相关的函数库:

    基准测试类(http://codeigniter.org.cn/user_guide/libraries/benchmark.html#id5)中提到“显示内存占用”,然而它的前提是 PHP 在安装时使用了 –enable-memory-limit 参数进行编译,而我们服务器基本采用APT-GET,尝试使用这个函数,没有输出。

后来直接使用PHP的memory_get_usage,可以获取当前的内容占用情况,结合ini_get(‘memory_limit’)获取当前的内存限制情况(实际上应该是可以使用ini_set设置超过该值)。

    在本地XAMPP环境下再次调试出问题的EXCEL的文件上传,同时改良了PhpSpreadsheet读取EXCEL文件的方式(参考:https://www.cnblogs.com/webwei2017/articles/9094028.html),以减少内存消耗,发现本地测试没有报错。

以为已经解决问题,GIT提交,线上PULL。在线测试,发现无法上传,报内存溢出的错误:

   Allowed memory size of xxx bytes exhausted at xxx:xxx (tried to allocate xxx bytes)

   查看memory_limit为512MB,难道是NGINX还有另外的内存限制,找到了这些资料:

   查看php-fpm开启的进程数以及每个进程的内存限制,https://www.cnblogs.com/terryguan/p/6599788.html

    按第3步,查看我们服务器的php_admin_value[memory_limit]参数,发现是注销状态,猜测应该不是这个问题。

nginx+php-fpm模式php内存泄漏探究,https://blog.csdn.net/blakefez/article/details/46691171

    很好的材料,用图的方式,把原理说的很明白。文中提到了几个关键的点:

    PHP配置文件里面的memory_limit 这个东西,其实,它限制的只是这个“请求处理”的内存。所以,这个参数跟php-fpm进程占用的内存并没有什么关系。那为什么会有占用2G大小的php-fpm进程呢?原因是这样的:php是用c写的,所以,难免又会一些内存泄露(当PHP出现内存溢出时,相关的变量是不会销毁的)。也就是说,在“请求处理”这个过程结束后,有些变量没有被销毁,然后就导致一个php-fpm进程占用的内存越来越大。

    那么,有什么办法能阻止这个问题呢?方法一:写不泄漏内存的php程序;方法二:在php-fpm配置文件中,将pm.max_requests这个参数设置小一点。这个参数的含义是:一个php-fpm子进程最多处理pm.max_requests个用户请求后,就会被销毁。当一个php-fpm进程被销毁后,它所占用的所有内存都会被回收。

    方法一,显然比较难,有很多的不确定因素,同时写好成本也比较高。

#。再次TOP查看内存情况,发现问题

    SSH客户端,命令top,查看内存情况,发现:

    剩余内存仅剩300左右,MYSQLD就占用500MB左右,重启MYSQLD,仍然是500MB左右,这个对于小服务器来说,太浪费了,找到以下材料:

    MySQL 5.6内存占用过高解决方案

    https://blog.csdn.net/wulantian/article/details/41119755

解决与结论:

   #。经过上面的过程,基本理解了出问题的原因,结论如下:

   服务器剩余内存本来就不足300MB,部分PHP请求(EXCEL导入操作)内存溢出,导致继续压缩内存,最后一次EXCEL导入执行时,占用了所有剩余的内存,这时MYSQLD刚好要做清空和初始化innodb_buffer操作,执行过程中,发现内存没有了,初始化失败,于是开始所有的shutting down,直到全部关闭。

    #。解决办法:

    ##。调整MYSQLD,释放更多的内存:小服务器,MYSQL的压力非常小,不需要占用这么多的内存。参考(MySQL 5.6内存占用过高解决方案,https://blog.csdn.net/wulantian/article/details/41119755),在/etc/mysql/my.cnf文件中的[mysqld]最底部,添加

performance_schema_max_table_instances=200

table_definition_cache=200

table_open_cache=128

    重启mysqld(service mysql restart),TOP查看,搞定。

    ##。设置NGINX,及时处理掉占着内存的php-fpm(特别是溢出的):参考文中提到的nginx+php-fpm模式php内存泄漏探究,修改/etc/php/7.1/fpm/pool.d/www.conf

pm.max_requests = 1

    重启php7.1-fpm(service php7.1-fpm restart)

后续与反思:

#。服务器的配置优化要考虑到程序内存溢出和占用的情况。

#。消耗大的程序的要重视内存与执行时间的调试。

#。很久没折腾服务器的优化运维,这里也有大量的内容。

 

转载请注明出处:IT要点网 » 小服务器(1G内存)php7.1-fpm mysql nginx的简单优化记录

转载于:https://my.oschina.net/sumweb/blog/3007969

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值