docker部署lnmp环境后端代码无法热加载现象
问题描述:
修改后端code,如下图
在浏览器无法热加载到修改的文件内容
追踪问题过程:
1、关闭nginx的sendfile
# 关闭sendfile(在http层或者在server层)
sendfile
off;
sendfile可以让sendfile()发挥作用。sendfile()可以在磁盘和TCP socket之间互相拷贝数据(或任意两个文件描述符)。Pre-sendfile是传送数据之前在用户空间申请数据缓冲区。之后用read()将数据从文件拷贝到这个缓冲区,write()将缓冲区数据写入网络。sendfile()是立即将数据从磁盘读到OS缓存。因为这种拷贝是在内核完成的,sendfile()要比组合read()和write()以及打开关闭丢弃缓冲更加有效。
仍然无法热加载
2、判断是html文件无法热加载还是php文件无法热加载
结论:经过测试,发现是php文件无法热加载,由此追踪到php配置
3、了解opcache
Opcache 的前生是Optimizer+
,它是PHP的官方公司 Zend 开发的一款闭源但可以免费使用的 PHP 优化加速组件。 Optimizer+ 将PHP代码预编译生成的脚本文件Opcode
缓存在共享内存中供以后反复使用,从而避免了从磁盘读取代码再次编译的时间消耗。同时,它还应用了一些代码优化模式,使得代码执行更快。从而加速PHP的执行。
正常的php代码运行过程:
备注:request请求(nginx,apache,cli等)-->Zend引擎读取.php文件-->扫描其词典和表达式 -->解析文件-->创建要执行的计算机代码(称为Opcode)-->最后执行Opcode--> response 返回
每一次请求PHP脚本都会执行一遍以上步骤,如果PHP源代码没有变化,那么Opcode也不会变化,显然没有必要每次都重行生成Opcode,结合在Web中无所不在的缓存机制,我们可以把Opcode缓存下来,以后直接访问缓存的Opcode岂不是更快,启用Opcode缓存之后的流程图如下所示:
4、安装opcache
在php5.5+版本里,已经默认开启了opcache,而笔者这次试用的是php7.2
在php.ini里有如下配置
zend_extension=opcache.so
[opcache]
opcache.enable=1
#允许在web环境使用,默认是开启的。
opcache.enable_cli=1
#运行在cli环境使用
5、解决问题
opcache.revalidate_freq
这个选项用于设置缓存的过期时间(单位是秒),当这个时间达到后,opcache会检查你的代码是否改变,如果改变了PHP会重新编译它,生成新的opcode,并且更新缓存。
值为“0”表示每次请求都会检查你的PHP代码是否更新(这意味着会增加很多次stat系统调用,译注:stat系统调用是读取文件的状态,这里主要是获取最近修改时间,这个系统调用会发生磁盘I/O,所以必然会消耗一些CPU时间,当然系统调用本身也会消耗一些CPU时间)。
可以在开发环境中把它设置为0,生产环境下不用管
因为下面会介绍另外一个设置选项。
opcache.validate_timestamps
当这个选项被启用(设置为1),PHP会在opcache.revalidate_freq设置的时间到达后检测文件的时间戳(timestamp)。
如果这个选项被禁用(设置为0),opcache.revalidate_freq会被忽略,PHP文件永远不会被检查。这意味着如果你修改了你的代码,然后你把它更新到服务器上,再在浏览器上请求更新的代码对应的功能,你会看不到更新的效果,你必须得重新加载你的PHP(使用kill -SIGUSR2强制重新加载)。
重启 fpm 和 nginx
kill -USR2 cat `/usr/local/php/var/run/php-fpm.pid`
nginx -s reload
6、opcache的其他附加配置
opcache.max_accelerated_files
这个选项用于控制内存中最多可以缓存多少个PHP文件。这个选项必须得设置得足够大,大于你的项目中的所有PHP文件的总和。
你可以运行“find . -type f -print | grep php | wc -l”这个命令来快速计算你的代码库中的PHP文件数。
opcache.memory_consumption
opcache使用的内存的总量,这个选项的默认值为64MB,你可以通过调用opcachegetstatus()来获取opcache使用的内存的总量,如果这个值很大,你可以把这个选项设置得更大一些。
opcache.interned_strings_buffer
这是一个很有用的选项,但是似乎完全没有文档说明。PHP使用了一种叫做字符串驻留(string interning)的技术来改善性能。例如,如果你在代码中使用了1000次字符串“foobar”,在PHP内部只会在第一使用这个字符串的时候分配一个不可变的内存区域来存储这个字符串,其他的999次使用都会直接指向这个内存区域。这个选项则会把这个特性提升一个层次——默认情况下这个不可变的内存区域只会存在于单个php-fpm的进程中,如果设置了这个选项,那么它将会在所有的php-fpm进程中共享。在比较大的应用中,这可以非常有效地节约内存,提高应用的性能。
这个选项的值是以兆字节(megabytes)作为单位,如果把它设置为16,则表示16MB,默认是4MB,这是一个比较低的值。
opcache.fast_shutdown
另外一个很有用但也没有文档说明的选项。从字面上理解就是“允许更快速关闭”。它的作用是在单个请求结束时提供一种更快速的机制来调用代码中的析构器,从而加快PHP的响应速度和PHP进程资源的回收速度,这样应用程序可以更快速地响应下一个请求。把它设置为1就可以使用这个机制了。
最终我们对于opcache在php.ini的设置如下:
opcache.revalidate_freq=0 opcache.validate_timestamps=0 (在开发环境可以把这一行注释掉) opcache.max_accelerated_files=7963 opcache.memory_consumption=192 opcache.interned_strings_buffer=16 opcache.fast_shutdown=1
热门话题 · · · · · · ( 去话题广场 )
- 解锁我的夏日旅行足迹地图 活动 24.7万次浏览
- 低谷期如何将“自怜”转化成“自爱”? 2.0万次浏览
- 每天夸夸自己的三件小事 3694次浏览
- 晒出你的上影节最爱 新话题
- 第26届上海国际电影节 8.5万次浏览
- 人生第一次不顾别人感受,结果_____ 1701次浏览