我的Zend应用程序使用3个ini配置文件,总共要解析200多行,包含100多条指令。每个请求都解析这些文件吗?有人说他们(如here和here)。如果是这样,这不是效率问题吗?
这些链接中的评论含有混淆情绪 - 有人说你应该避免ini配置文件并在PHP中进行配置,有人说你可以使用Zend_Cache_Frontend_File,有些人说这不是问题。但是,如果您预计会有相当多的流量,那么每次请求解析200行文本肯定会很快成为问题吗?
如果您的确建议使用缓存技术,请详细说明如何实施缓存技术?
答案 0 :(得分:10)
是的,除非您缓存它们,否则每次都会对它们进行解析。它确实节省了时间(我在自己的项目中检查过)。
那么如何使用Zend_Cache_Frontend_File
来缓存ini文件?好吧,我可以为你提供一个例子。在我的项目中,我有route.ini文件,其中包含许多自定义路由:
<强> routes.ini 强>
routes.showacc.route = "/@show/:city/:id/:type"
routes.showacc.type = "Zend_Controller_Router_Route"
routes.showacc.defaults.module = default
routes.showacc.defaults.controller = accommodation
routes.showacc.defaults.action = show
routes.showacc.defaults.city =
routes.showacc.defaults.type =
routes.showacc.defaults.id =
routes.showacc.defaults.title =
routes.showacc.reqs.id = "\d+"
;and more
在我的 Bootstrap.php 中,我使用缓存加载它们(如果可能):
protected function _initMyRoutes() {
$this->bootstrap('frontcontroller');
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
// get cache for config files
$cacheManager = $this->bootstrap('cachemanager')->getResource('cachemanager');
$cache = $cacheManager->getCache('configFiles');
$cacheId = 'routesini';
// $t1 = microtime(true);
$myRoutes = $cache->load($cacheId);
if (!$myRoutes) {
// not in cache or route.ini was modified.
$myRoutes = new Zend_Config_Ini(APPLICATION_PATH . '/configs/routes.ini');
$cache->save($myRoutes, $cacheId);
}
// $t2 = microtime(true);
// echo ($t2-$t1); // just to check what is time for cache vs no-cache scenerio
$router->addConfig($myRoutes, 'routes');
}
缓存在 application.ini 中设置,如下所示
resources.cachemanager.configFiles.frontend.name = File
resources.cachemanager.configFiles.frontend.customFrontendNaming = false
resources.cachemanager.configFiles.frontend.options.lifetime = false
resources.cachemanager.configFiles.frontend.options.automatic_serialization = true
resources.cachemanager.configFiles.frontend.options.master_files[] = APPLICATION_PATH "/configs/routes.ini"
resources.cachemanager.configFiles.backend.name = File
resources.cachemanager.configFiles.backend.customBackendNaming = false
resources.cachemanager.configFiles.backend.options.cache_dir = APPLICATION_PATH "/../cache"
resources.cachemanager.configFiles.frontendBackendAutoload = false
希望这有帮助。
答案 1 :(得分:4)
如果您加载像ZF这样的框架,则会加载数十个包含数千行代码的文件。必须为每个用户和请求读取文件。服务器端你有一些磁盘控制器缓存等等,所以不必每次都从磁盘中实际读取文件。此外,操作系统中的内存管理器会跟踪它并为内存提供一些缓存,因此不必每次都将内存读取到内存中。接下来,您通常会有一个数据库,其中或多或少发生相同的事情,因为数据库最终存储在硬盘驱动器上的文件中。数据库服务器或多或少地读取文件和相同的故事。
那么,我会担心配置文件中的几行吗?当然不是因为我需要我的应用程序的数据才能工作。来自哪里是次要的。
关于使用Zend_Cache进行缓存。如果你有紧凑的数据,并且不需要像Zend_Config中的文件那样进行大量处理,你将获得微小的微秒。您实际上是将紧凑格式存储为另一种紧凑格式;序列化的字符串,必须再次反序列化。如果你可以缓存数据以避免数据库访问或渲染整个视图,包括模型的所有数据请求,我们正在谈论一个完全不同的故事。
答案 2 :(得分:2)
如果你假设PHP文件缓存在内存中,而解析的ini文件也在内存中,你可以在跳过Zend_Config_Ini类和解析过程的同时将ini文件转换为php文件。
# public/index.php
$cachedConfigFile = APPLICATION_PATH.'/../cache/application.ini.'.APPLICATION_ENV.'.php';
if(!file_exists($cachedConfigFile) || filemtime($cachedConfigFile) < filemtime(APPLICATION_PATH . '/configs/application.ini'))
{
require_once 'Zend/Config/Ini.php';
$config = new Zend_Config_Ini( APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV );
file_put_contents($cachedConfigFile, '<?php '.PHP_EOL.'return '.var_export($config->toArray(),true).';' );
}
$application = new Zend_Application(
APPLICATION_ENV,
$cachedConfigFile // originally was APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
->run();
我用ab测试过。非缓存配置:
ab -n 100 -c 100 -t 10 http://localhost/
Requests per second: 45.57 [#/sec] (mean)
Time per request: 2194.574 [ms] (mean)
Time per request: 21.946 [ms] (mean, across all concurrent requests)
Transfer rate: 3374.08 [Kbytes/sec] received
vs Cached config:
Requests per second: 55.24 [#/sec] (mean)
time per request: 1810.245 [ms] (mean)
Time per request: 18.102 [ms] (mean, across all concurrent requests)
Transfer rate: 4036.00 [Kbytes/sec] received
性能提升18%。
答案 3 :(得分:0)
据我们创建文件的朋友说:
https://github.com/QualityCase/Mini-Case/blob/master/modules/admin/Bootstrap.php
我发现这非常有用:
protected function _initConfig()
{
if(!$config = $this->_cache->load('config')) {
$config = new Zend_Config_Ini(BASE_PATH . '/configs/application.ini');
$config = $config->toArray();
$this->_cache->save($config, 'config');
}
Zend_Registry::set('config', $config);
}