不灭的焱

革命尚未成功,同志仍须努力

作者:php-note.com  发布于:2017-11-28 23:34  分类:PHP库/系统/微信 

从上篇的执行流程,可以得出第一个需要思维转换的点:

Swoole是完全的长驻内存的

这个是和web开发第一个很大的不同,之前我们在做web开发,基本不怎么考虑内存控制的问题,这里从两个方面来进行结比:

  • 性能加速

    长驻内存一个最大的好处就是可以性能加速,主要通过下面几个点来进行:

    a)  请求全局共享。在fpm模式下,我们处理一个请求,通常会有一些空消耗,比如框架共用文件加载,配置文件加载,那么在swoole中,可以在onworkerstart的时候提前一次性把一些必要的文件和配置加载好,不必每次receive重复加载一遍,这样能提升不小的性能

    b)  可以做连接池了

     

  • 隐患

    虽然长驻内存能有不小的性能加速,但由于web开发时候形成的思维定势,很容易造成内存泄漏,所以要注意几下几点:

    a)  资源的释放,如果是公用的资源,建议在onworkerstart里提前创建好,否则在onReceive里,一定要及时的释放。

    b)  static数组,这个是很容易踩到的坑,static数组如果存在只增不减,那最终就会导致oom了。

    c)   单例或全局注册数,单例可以很好的控制内存泄漏,但由于swoole里的单例是全请求共享,所以一但初始化了一个类之后,上一个请求修改的这个类,会影响到下一个请求,这也是很多人会忽略掉的。举个很典型的例子,现在redis用的比较多了,在swoole,单例了一个redis类,我在某个请求突然执行了selectDb,那就导致了下面所有的请求可能就get数据失败了。

     

  • 超全局变量     

    超全局变量是phper用的比较多的,由于swoole是多进程的架构,如果在worker里进行task投递之后,在task里是无法得到worker里的数据的,所以这个坑也是经常被踩到,现在的框架基本抛弃直接通过超全局变量的方式来获取数据,基本都封装了一套取参数的方法,所以在swoole里强烈推荐用此方法,不管是worker转到task还是task转到worker, 我只要把获取到的外部数据通过框架的参数初始化这样的流程,那么在框架内部用就是安全的。

 

当然,swooele也提供了和fpm类似的max_request机制,可以控制每个worker或task进程处理一定请求总数之后,自动退出,由管理进程重新拉起一个新的worker或task进程,从而达到内存完全释放的目的。

 

总之,在长驻内存的swoole下进行项目开发,可以培养我们更好的控制内存,更清楚的了解程序的细节,这个思维可以扩展到其他服务器编程的语言中,对自我的提升是很有帮助的。

 

 

摘自:http://guangla.lofter.com/post/1d337f35_8350827