CakePHP性能问题-模式加载30-50秒

时间:2018-08-03 13:20:50

标签: php mysql cakephp

我正在为一家面包店开发一个在线销售管理应用程序。我决定使用Cake PHP作为框架,并使用Mochahost作为托管服务提供商,因为我没有听说两者都有任何重大缺点。

我的应用程序目前处于开发阶段。它使用的MySQL用户只有一个可用的数据库,该数据库仅只有10-15个表,当前总共最多50行(大多数表为空)。

我不确定,因为调试工具包仅显示单个查询(如果会话超时为3,则查询)花费可接受的时间(不到0.2秒),但计时器表示Controller.shutdown事件或Controller.startup事件的发生时间为30 000毫秒至58 000毫秒(!!)。

我的页面的每次加载需要30到60秒(!!!)。发现这是由于获取架构信息(getSchemaCollection(), typeMap())引起的。好的,我知道,开发设置使高速缓存仅可用2分钟左右,但是每次我重新加载页面时,它都需要30-60秒的时间。根本没有定义表关联。不,我没有运行异常复杂的程序,而是使用Auth组件和数据库Sessions ...

使用已定义的(深度)关联,它运行了很长时间,以致页面死于 HTTP 504网关超时 502错误的网关。根据cpanel,根本没有响应,并且该脚本仍在后台运行,阻止了我可用的输入过程之一和mysql用户登录。这意味着我什至无法开发页面,因为即使一次缓存也无法加载。在私有开发服务器上进行开发也无法正常工作:在最初的生产负载下,它还将尝试构建缓存。

通过调用Cache::disable()禁用缓存完全没有帮助。

我还注意到,有一个查询需要30-60秒才能在托管计划中包含的mysql服务器上运行,即SHOW SCHEMAS。我猜在第一次getSchemaCollection()被调用时,cakephp使用此查询。

此查询为您运行多长时间?我完全认为这是不能接受的,我应该要求重新发现还是立即修复?由于面包房每天有500位客户,因此我无法负担页面加载的时间,因此每次购买都将使用繁琐的sql等。

当前会话表:

Field   Type    Null    Key Default Extra
id  char(40)    NO  PRI NULL    
created timestamp   NO      CURRENT_TIMESTAMP   
updated timestamp   NO      CURRENT_TIMESTAMP   on update CURRENT_TIMESTAMP
data    blob    YES     NULL    
expries int(10) YES     NULL    
ipAdress    varchar(15) NO      NULL    
user_id char(36)    YES MUL NULL    

此表具有user_id作为用户表的PK(id)的外键。

SessionsTable.php:

class SessionsTable extends Table
{
    public static $uid = null;

    public function initialize(array $config)
    {
        parent::initialize($config);
        //$this->belongsTo('Users');
    }

    public function implementedEvents()
    {
        return array(
            'Model.beforeSave' => 'beforeSave',
        );
    }

    public function beforeSave(Event $event, EntityInterface $entity, $options = []) {
        $request = Router::getRequest();
        $request->trustProxy = true;
        $entity->set('ipAdress', $request->clientIp());
        if (!is_null(self::$uid)) $entity->set('user_id', self::$uid);
    }
}

更新我不是php配置文件方面的专家,但如果我不正确,则对应的有效值是PDOStatement-> execute(),它被94.13 self(?)/ incl。(? )

更新2 我收到了mochahost的迅速而令人满意的答复,称由于各种可以理解的性能原因,显示模式查询已被禁用。他们建议我使用SHOW SCHEMAS LIKE 'myuser_%',因为所有数据库名称均为'user_dbname'格式。所以我的问题是,我应该在哪里以及如何强制在cakephp中默认使用它?

2 个答案:

答案 0 :(得分:1)

听起来您知道问题所在。 SHOW SCHEMAS的加载时间不应超过30-60秒。在服务器级别上,这是一个问题,假设您尝试手动运行该查询并获得相同的结果(在PHP应用程序的上下文之外)。

CakePHP需要访问您的数据库模式才能发挥其魔力,因此我建议与您的托管服务提供商讨论此问题。

答案 1 :(得分:0)

我知道这个问题有点老了,但是从那时起,我一直在研究应用程序,设法解决了性能问题,并且做得很好。对于那些在那里遇到类似问题的人,我的想法全都是这样:

答案

  • 使用VPS 。这样,您就不必与其他用户(/ apps)共享对同一mysql服务器实例的访问权限。 注意,当您的应用达到每台服务器的用户参与度时,此解决方案还可以提供更好的性能。有关针对初学者进行扩展开发的更多信息,请访问this post

OR

  • 在开发计算机上构建数据库架构高速缓存,然后将高速缓存文件复制到生产(或即将上线/登台)的系统。之后,将Configure::config('default', false)设置为启用生产模式,从而禁用快速缓存失效(开发默认值为2分钟);或在app.php配置文件中手动设置缓存过期限制。 注意,您可能需要定期更新缓存文件及其过期以防止重建过程。

OR

  • 使用SHOW DATABASES LIKE '(your username)\_%'。这可能不会被禁用,但是在框架中实现这种更改可能非常困难。假设您正在开发一个小型Web应用程序,则可能不值得花时间进行开发。在大多数情况下,请使用上述解决方案。

但是

  • 如果您需要其他软件环境或工具的修复程序,例如 MySQL Workbench phpMyAdmin ,请稍后使用第三个选项查看解决方法示例。 注意仅适用,因为服务器上的所有架构名称都使用以下模式:(username)_(actual db name)

更长的版本,一些其他想法

如果托管是在共享(linux)环境上的实时计划,并且数据库也在共享环境中,则似乎提供程序(Mochahost)已禁用或受限制 一些< / em>查询(或至少 某种形式 ),例如:

  • SHOW DATABASES
  • SHOW SCHEMAS
  • information_schema上查询
  

“”请注意,为了获得最佳性能,我们使用单独的远程MySQL数据库服务器。(...)对我们(共享计划)帐户的MySQL数据库的访问受到限制,并且不允许执行SHOW DATABASESSHOW SCHEMAS命令。要查看数据库列表,应使用类似的查询:(请参阅下文)。如果需要远程访问MySQL并且正在使用(共享计划) )-您仍然可以这样做,但是由于mysql特权,您将无法使用上述命令。为了提高我们的MyQL服务器的整体性能以及提高正常运行时间和服务器安全性而应用了此限制。 / em>-托管提供商的2级技术支持。 (向他们大喊,这封电子邮件实际上非常有用。)

考虑到这一点,这是可理解的,我认为这是良好做法。 考虑一个查询来描述共享服务器或大型群集上的所有可用架构。这可能意味着数十个,数百个甚至更多的条目进行迭代并返回。另外请注意此处的安全问题,需要对结果进行过滤(使用更多资源),以免泄露有关其他用户的敏感数据。 是的,数据库名称是敏感数据。

对查询进行一些调整,以排除不相关的结果会产生更好的性能,并且显然更安全:SHOW DATABASES LIKE '(your username)\_%'再次注意,此变通办法仅能完成其工作,因为所有架构均以上述相同的模式命名。另外,您的提供商也可以禁用此功能。

使phpMyAdmin(或其他数据库管理软件)正常工作

$usr = 'YourUserName';
$cfg['Servers'][$i]['DisableIS'] = true;
$cfg['Servers'][$i]['ShowDatabasesCommand'] = "SHOW DATABASES LIKE '$usr\_%'";

或者phpMyAdmin配置中的此类代码应该可以完成这项工作。 注意:这不能保证正常工作,而是一种解决方法-但最好为您提供解决问题的思路。

就其他数据库管理软件而言,我只有MySQL Workbench的经验。不幸的是,该工具不支持调整,而是执行初始查询以获取模式。我要打开功能请求票证或进行某种排序并在此处发布更新。

请确保您选择的工具不会执行上述类似的初始查询,或者-至少-可以调整查询。

最后但并非最不重要

永远不要在公共生产环境中开发。永远不会。

尝试(测试)一个特定的开发快照是可以的。只要您将其立即删除。不要泄漏不稳定的软件。如果确实需要,请使用本地开发服务器(最好)或独立服务器或VPS作为开发服务器(考虑到安全性)。