Magento"前端控制器达到100路由器匹配迭代"错误

Chr*_*ian 26 exception magento

当我的网站开始抛出异常"前端控制器达到100路由器匹配迭代"时,我的网站每天下降一到两次.一旦发生这种情况,访问管理员和前端就会消失.我刚刚离开了一个错误页面.

这是从Magento 1.5.0.1升级到1.5.1.0后开始的.如果我手动清除var/cache /目录,我就会重新运行.

我已经用Google搜索了这个.在有限的搜索结果中,我发现没有什么能帮助我解决这个问题.

任何有关为什么会发生这种情况以及如何解决这些问题的见解将不胜感激.

--update -----------------------

使用Andrey Tserkus的有用答案中提供的调试代码,我能够确定错误是由我的一些路由器消失引起的.

调试代码输出的普通路由器是:总计7:admin,标准,cms,amshopby,fishpig_wordpress,seosuite,默认

发生错误时,它们已更改为:Total 3:admin,standard,default

当发生这种情况时,似乎缺少的路由会导致代码针对每个页面请求迭代到100.我将进一步研究这种情况.

Luk*_*ers 13

更新2:我有一些进一步的更改,应该有助于防止100路由器匹配迭代的不同原因

https://github.com/convenient/magento-ce-ee-config-corruption-bug#update-2-further-improvements

================================================== ==================

更新:MAGENTO已将我的答案用作补丁

https://github.com/convenient/magento-ce-ee-config-corruption-bug#update-good-news-a-patch-from-magento

================================================== ==================

我最近花了很长时间研究这个bug.我已经写了我充分的调查结果,解释和复制在这里.

https://github.com/convenient/magento-ce-ee-config-corruption-bug

但是,对于简短的回答.这似乎是一个Magento错误,可以通过覆盖Mage_Core_Model_Config::init以下内容来纠正:

 public function init($options=array())
 {
     $this->setCacheChecksum(null);
     $this->_cacheLoadedSections = array();
     $this->setOptions($options);
     $this->loadBase();

     $cacheLoad = $this->loadModulesCache();
     if ($cacheLoad) {
         return $this;
     }
     //100 Router Fix Start
     $this->_useCache = false;
     //100 Router Fix End
     $this->loadModules();
     $this->loadDb();
     $this->saveCache();
     return $this;
 }
Run Code Online (Sandbox Code Playgroud)

编辑:更新以测试香草1.5

我刚刚在1.5的vanilla安装上运行了复制脚本.除CONFIG缓存禁用外,其他所有缓存都有.

它没有100 router像1.13 那样产生错误,但确实打破了网站,显示的所有主页都是白屏.

原因是,当我们寻找控制器和行动时,我们匹配Mage_Core_IndexController::indexAction而不是Mage_Cms_IndexController::indexAction.

class Mage_Core_IndexController extends Mage_Core_Controller_Front_Action {

    function indexAction()
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

Mage_Core_IndexController::indexAction 是一个空函数,并完美地解释白页.

我可以放置时,不会再复制此错误_useCache = false进入Mage_Core_Model_Config.

我相信也许你的Magento网站独特的配置可能会导致它完全无法匹配控制器,而不是回到这个Mage_Core_IndexController行动?


And*_*kus 11

错误消息过于笼统,无法尝试解决此问题.我建议你聘请一些自由职业者Magento网站开发人员来查看你实际网站上的问题来源.理论上无法解决.

从消息中可以看出,问题出现是因为您的路由器正在为调度请求进行循环引用.其中一个匹配请求,但不调度并再次将其推送到重新调度.或者根本没有路由器匹配请求.

您可以通过访问Magento核心文件app/code/core/Mage/Core/Controller/Varien/Front.php获取更多信息,找到行

while (!$request->isDispatched() && $i++<100) {
    foreach ($this->_routers as $router) {
        if ($router->match($this->getRequest())) {
            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并用它们替换它们

Mage::log('----Matching routers------------------------------');
Mage::log('Total ' . count($this->_routers) . ': ' . implode(', ', array_keys($this->_routers)));
while (!$request->isDispatched() && $i++<100) {
    Mage::log('- Iteration ' . $i);
    $requestData = array(
        'path_info' => $request->getPathInfo(),
        'module' => $request->getModuleName(),
        'action' => $request->getActionName(),
        'controller' => $request->getControllerName(),
        'controller_module' => $request->getControllerModule(),
        'route' => $request->getRouteName()
    );

    $st = '';
    foreach ($requestData as $key => $val) {
        $st .= "[{$key}={$val}]";
    }
    Mage::log('Request: ' . $st);
    foreach ($this->_routers as $name => $router) {
        if ($router->match($this->getRequest())) {
            Mage::log('Matched by "' . $name . '" router, class ' . get_class($router));
            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在等待站点产生错误之后,打开var/log/system.log并查看有关系统内部情况的调试信息.它将有助于看到更好,路由器打破了系统.


sil*_*tar 6

此消息是由错误的缓存配置数据引起的.我不确定是什么原因导致缓存的配置被破坏 - 我猜它可能会根据Magento的运行方式而变化.

我想,如果你仍然可以访问Magento后端,你可以尝试清除系统>缓存管理下的缓存.如果这没有帮助(或者如果您无法访问Magento后端,这很可能出现此错误),那么通过在app /中查找<cache> <backend>的值来确定如何设置缓存/local.xml.如果你使用文件进行缓存(默认),你可以清除magento/var/cache

rm -rf /path/to/magento/var/cache/*
Run Code Online (Sandbox Code Playgroud)

如果您正在使用memcached,请在<port>下找到该端口,您可以这样做

telnet memcache_server portnumber
flush_all
Run Code Online (Sandbox Code Playgroud)

或者,如果你使用redis,你可以这样做

telnet redis_server portnumber
FLUSHALL
Run Code Online (Sandbox Code Playgroud)