最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

fpm模式下讀取到is_cli為何為true

2023-03-19 08:06 作者:吳小敏63  | 我要投稿

php-fpm下讀取到is_cli為true,不知道你們是否遇到過,我是遇到了。。。。
有人會說,即使為true又怎么了,你是沒遇到有些根據(jù)is_cli來走不同邏輯判斷的,如果讀取的是錯的就會引起很大的問題。。。。


問題出現(xiàn)和簡單排查

維護的老系統(tǒng)里有個上傳的服務(wù),用的是比較老的codeigniter,構(gòu)建完代碼后,突然發(fā)現(xiàn) 1個上傳url報路徑找不到
具體表現(xiàn)如下

因為這里是a1.domain.com去調(diào)取upload.domain.com,所以出現(xiàn)跨域(如果upload.domain.com?正常的話,是有設(shè)置跨域的),現(xiàn)在明顯設(shè)置跨域的失效了

直接打開鏈接看,如下圖

因為是線上,即使再自信沒改到這里,也要趕緊聯(lián)系運維同事回滾代碼,但是回滾后發(fā)現(xiàn)依然如此。
當時急的不行,讓測試同事讓他看看其它的上傳鏈接是否可正常上傳,發(fā)現(xiàn)其它的上傳(比如視頻上傳,其它的圖片的上傳)是沒問題的,唯一的區(qū)別就是走不走這個index.php入口文件

排查

因為當時已經(jīng)晚上近10點了,使用的人也不多,一邊讓測試同學(xué)幫驗證。我這邊趕緊查代碼。日常開發(fā)用的不是CI框架,趕緊搜索

ERROR: Not Found The controller/method pair you requested was not found.

這個是哪提示出來的,
在項目中發(fā)現(xiàn)代碼位置如下,而且僅此一處

而且看到前面的is_cli,就是納悶我這是php-fpm的網(wǎng)頁請求,為何is_cli為true呢

追到is_cli的實現(xiàn)

if ( ! function_exists('is_cli')) { /** * Is CLI? * * Test to see if a request was made from the command line. * * @return bool */ function is_cli() { return (PHP_SAPI === 'cli' OR defined('STDIN')); } }

后來一路追到ci的路由解析

system/core/Router.php

124 ? ? ? ? public function __construct($routing = NULL) 125 ? ? ? ? {126 ? ? ? ? ? ? ? ? $this->config =& load_class('Config', 'core');127 ? ? ? ? ? ? ? ? $this->uri =& load_class('URI', 'core');128 ? ? ? ? ? ? ? ? //var_dump(PHP_SAPI);129 ? ? ? ? ? ? ? ? //var_dump(defined('STDIN'));130 ? ? ? ? ? ? ? ? //var_dump( is_cli());131 ? ? ? ? ? ? ? ? $this->enable_query_strings = ( ! is_cli() && $this->config->item('enable_query_strings') === TRUE);132133 ? ? ? ? ? ? ? ? // If a directory override is configured, it has to be set before any dynamic routing logic134 ? ? ? ? ? ? ? ? is_array($routing) && isset($routing['directory']) && $this->set_directory($routing['directory']);135 ? ? ? ? ? ? ? ? $this->_set_routing();136137 ? ? ? ? ? ? ? ? // Set any routing overrides that may exist in the main index file138 ? ? ? ? ? ? ? ? if (is_array($routing))139 ? ? ? ? ? ? ? ? {140 ? ? ? ? ? ? ? ? ? ? ? ? empty($routing['controller']) OR $this->set_class($routing['controller']);141 ? ? ? ? ? ? ? ? ? ? ? ? empty($routing['function']) ? OR $this->set_method($routing['function']);142 ? ? ? ? ? ? ? ? }143144 ? ? ? ? ? ? ? ? log_message('info', 'Router Class Initialized');145 ? ? ? ? }

結(jié)合上圖128,129行和上面is_cli函數(shù)的實現(xiàn)代碼,130行不可能為true啊

腦袋快要炸了,通過調(diào)試發(fā)現(xiàn)只要131行的$this->enable_query_strings為true,那么上傳功能就沒問題

經(jīng)過思考和猜測,嚴重懷疑是fpm讀取到了cli下的opcache

主要基于以下幾點

  • 其它入口(非index.php)的路徑?jīng)]問題

  • 命令行里有php index.php 這種定時腳本在跑

  • opcache的配置

ri了一下如下 $ php --ri 'Zend opcache'Zend OPcache Opcode Caching => Up and Running Optimization => Enabled SHM Cache => Enabled File Cache => Enabled Startup => OK Shared memory model => mmap Cache hits => 0Cache misses => 0Used memory => 36560720Free memory => 231874736Wasted memory => 0Interned Strings Used memory => 415960Interned Strings Free memory => 16361256Cached scripts => 0Cached keys => 0Max keys => 16229OOM restarts => 0Hash keys restarts => 0Manual restarts => 0Directive => Local Value => Master Value opcache.enable => On => On opcache.use_cwd => On => On opcache.validate_timestamps => On => On opcache.validate_permission => Off => Off opcache.validate_root => Off => Off opcache.inherited_hack => On => On opcache.dups_fix => Off => Off opcache.revalidate_path => Off => Off opcache.log_verbosity_level => 1 => 1opcache.memory_consumption => 256 => 256opcache.interned_strings_buffer => 16 => 16opcache.max_accelerated_files => 8000 => 8000opcache.max_wasted_percentage => 10 => 10opcache.consistency_checks => 0 => 0opcache.force_restart_timeout => 3600 => 3600opcache.revalidate_freq => 2 => 2opcache.file_update_protection => 2 => 2opcache.preferred_memory_model => no value => no value opcache.blacklist_filename => no value => no value opcache.max_file_size => 0 => 0opcache.protect_memory => 0 => 0opcache.save_comments => 1 => 1opcache.fast_shutdown => 0 => 0opcache.optimization_level => 0x7FFFBFFF => 0x7FFFBFFFopcache.opt_debug_level => 0 => 0opcache.enable_file_override => Off => Off opcache.enable_cli => On => On opcache.error_log => no value => no value opcache.restrict_api => no value => no value opcache.lockfile_path => /tmp => /tmp opcache.file_cache => /tmp => /tmp opcache.file_cache_only => 0 => 0opcache.file_cache_consistency_checks => 1 => 1opcache.huge_code_pages => Off => Off

這里有下面幾個配置項對fpm下讀取到cli的緩存有關(guān)

zend_extension=opcache.soopcache.enable=1opcache.enable_cli=1opcache.memory_consumption=256opcache.interned_strings_buffer=16opcache.max_accelerated_files=8000opcache.max_wasted_percentage=10opcache.use_cwd=1opcache.force_restart_timeout=3600opcache.file_cache=/tmp

  • 1.開啟了cli的opcache 即(enable_cli=1)

  • 2.使用了二級文件緩存 即(opcache.file_cache=/tmp)

于是嘗試刪除opcache的文件緩存,然后重啟fpm,就好了

(實際上是,我打日志調(diào)著調(diào)著 突然自己好了,看fpm的日志是fpm觸發(fā)了自動重啟,我打日志時有修改了相關(guān)文件,fpm重啟時檢查文件更新重新生成了opcache)

后來為了防止這種情況再次發(fā)生就關(guān)閉了cli下的opcache,刪除opcache文件緩存,重啟fpm

然后我在測試上不斷復(fù)現(xiàn),發(fā)現(xiàn)可以穩(wěn)定復(fù)現(xiàn),實錘是fpm下讀取到了cli已經(jīng)生成好的緩存了

原起

這次的問題,我歸結(jié)為以下兩點

  • 對opcache的機制認識不夠

  • CI框架這種fpm里和cli用了同樣的入口文件而且根據(jù)is_cli來進行路由解析,會在我上面的配置和使用下出問題

粗淺探索

測試代碼

現(xiàn)在有以下代碼

路徑為/data/www/emlog/op/

test.phpinclude/fun.php invalidate

test.php

include "include/fun.php";var_dump(sapi());var_dump(is_cli());

include/fun.php

function sapi(){ return php_sapi_name(); }function is_cli() { ? ? ? ? return (PHP_SAPI === 'cli' OR defined('STDIN')); }

invalidate.php

$files=[ '/data/www/emlog/op/test.php', '/data/www/emlog/op/include/fun.php', ];foreach($files as $f){ ? ?$r=opcache_invalidate($f,true); ? ?var_dump($r); }

opcache配置

[opcache]zend_extension=opcache.soopcache.enable=1opcache.enable_cli=1opcache.file_cache=/tmpopcache.memory_consumption=256opcache.interned_strings_buffer=16opcache.max_accelerated_files=8000opcache.max_wasted_percentage=10opcache.use_cwd=1opcache.force_restart_timeout=3600opcache.validate_timestamps=1opcache.revalidate_freq=2opcache.revalidate_path=0

主要是前4個的配置
按照下圖操作

更清楚的圖片見?https://note.youdao.com/ynoteshare/index.html?id=2275a62e0fa926f2cf576940a1cd93d4&type=note&_time=1679154215415

is_cli為true時的緩存

[root@hkui-qy tmp]# cat 8fc9c56d14b6542c6ff7147207730f6b/data/www/emlog/op/include/fun.php.bin |strings OPCACHE 8fc9c56d14b6542c6ff7147207730f6b0 %%1n include/fun.php:235496:235544:/data/www/emlog/op /data/www/emlog/op/include/fun.php is_cli sapi php_sapi_name

is_cli為false時的緩存

[root@hkui-qy tmp]# cat 8fc9c56d14b6542c6ff7147207730f6b/data/www/emlog/op/include/fun.php.bin |strings OPCACHE 8fc9c56d14b6542c6ff7147207730f6b` include/fun.php:235648:235696:/data/www/emlog/op /data/www/emlog/op/include/fun.php496: is_cli STDIN stdin sapi php_sapi_name

共享內(nèi)存緩存與文件緩存

  • fpm在啟動或者重啟時

    • 如果發(fā)現(xiàn)代碼文件和緩存文件匹配,那么會讀取文件的緩存到共享內(nèi)存,所以使用文件緩存(可提前用opcache_compile_file生成opcache),在fpm重啟時,能更快的獲取opcache,減少內(nèi)存使用

    • 如果發(fā)現(xiàn)代碼文件和緩存文件對不匹配(緩存不存在或者代碼文件有改變),那么會重新生成緩存,并同步到文件緩存里

  • 文件修改,fpm檢測到了文件的變化,會重新生成共享內(nèi)存緩存,并不會立馬更新到文件緩存里,fpm重啟 然后重新生成緩存后才會更新到文件緩存


fpm模式下讀取到is_cli為何為true的評論 (共 條)

分享到微博請遵守國家法律
通山县| 双江| 青州市| 安顺市| 阿巴嘎旗| 无为县| 治多县| 克东县| 拉萨市| 丹东市| 美姑县| 开平市| 黎城县| 拜泉县| 广宗县| 兰西县| 榆社县| 诸暨市| 内江市| 桐柏县| 交口县| 泸溪县| 汉阴县| 株洲县| 绥阳县| 连江县| 罗平县| 宣汉县| 类乌齐县| 祥云县| 民丰县| 响水县| 肃宁县| 东乌珠穆沁旗| 海口市| 建德市| 堆龙德庆县| 进贤县| 新建县| 黑山县| 武夷山市|