【问题标题】:too many connections using eloquent orm and mysql使用 eloquent orm 和 mysql 的连接太多
【发布时间】:2015-08-13 03:48:52
【问题描述】:

我将 SLIM Framework 与 Laravel 的 Eloquent ORM 一起用于 REST API。最近遇到了too many connections的问题。

在一个请求 URI 期间,我需要对 mySql DB 进行多次GetSet 调用。这会打开我所做的每个数据库事务的连接。我想避免这种情况。目前mysql连接池有200个线程。

我的 API 预计会有超过 1000 个并发调用,在当前环境下,40% 的调用会失败(使用 jMeter 测试)。

我的想法是,对于一个 API 调用,我的应用程序应该只使用一个连接线程,并将 MySql 连接池增加到大约 1000 到 1500 。 这是一种不好的方法吗?

使用 Eloquent ORM,我的数据库连接由 Capsule 管理。 我是否应该使用Singleton 方法建立第一个连接,并且对于API 请求中的任何后续调用,都应该使用相同的线程?

这是我的数据库连接管理器:

    use Illuminate\Database\Capsule\Manager as Capsule;
    /**
     * Configure the database and boot Eloquent
     */
    $capsule = new Capsule;

    $capsule->addConnection($databaseConfig['mysql']);

    // Set the event dispatcher used by Eloquent models... (optional)
    use Illuminate\Events\Dispatcher;
    use Illuminate\Container\Container;

    $dispatcher = new Dispatcher(new Container);
    $capsule->setEventDispatcher($dispatcher);

    $capsule->setAsGlobal();
    $capsule->bootEloquent();

解决这个问题的最佳方法是什么?

更新

我正在尝试另一种建立持久连接的方法。但是在调用完成后,持久连接仍然没有关闭。即使拨打DB::Disconnect 也无济于事。

    <?php

    use Illuminate\Database\Capsule\Manager as Capsule;
    use Illuminate\Events\Dispatcher;
    use Illuminate\Container\Container;

    /**
     * Configure the database and boot Eloquent
     */
    $app->hook('slim.before', function() use ($app) {
        try {

    //        pr('', $app->settings['databaseConfig']['mysql'], 1);
            /*
             * Register Eloquent as singleton to slim container
             * since we will use the same instance across the request cycle
             */
            $app->container->singleton('db', function() {
                return new Capsule;
            });

            $app->db->addConnection($app->settings['databaseConfig']['mysql']);

            $dispatcher = new Dispatcher(new Container);
            $app->db->setEventDispatcher($dispatcher);

            if (isset($app->settings['databaseConfig']['profiler']) && $app->settings['databaseConfig']['profiler']) {
                $dispatcher->listen('illuminate.query', function($sql, $params, $time, $conn) {

                    dd(array($sql, $params, $time, $conn));
                });
            }

            $app->db->setAsGlobal();
            $app->db->bootEloquent();
        } catch (PDOException $e) {
            /** Do some stuff to handle exception */
            echoResponse(501, array('No DB Connections'));
        }
    });

【问题讨论】:

  • 最后试过DB::disconnect();
  • SET GLOBAL max_connections = &lt;new value&gt;; ?
  • 我应该把这个放在哪里??您能否具体说明一下操作名称...?
  • 这些语句将在索引文件中用于进行全局设置以覆盖 php.ini 设置。我正在努力减少数字。正在使用的线程。如果我可以一个线程,那就没有了。
  • 我从来没有经历过这种行为——每个请求有几个连接——所以你问题的根源可能是你设置 Eloquent 的地方。你是从你的 index.php 或类似的东西做一次吗?

标签: php mysql orm eloquent slim


【解决方案1】:

您应该对所有查询使用相同的数据库连接。最简单的方法是连接到 DI 容器中的数据库,因为您可以在每次需要时再次将其拉出。

使用 Slim 3,它看起来像这样:

$container = $app->getContainer();

$container['db'] = function ($container) {
    $capsule = new \Illuminate\Database\Capsule\Manager;
    $capsule->addConnection($container['settings']['db']);

    $capsule->setAsGlobal();
    $capsule->bootEloquent();

    return $capsule;
};

您现在可以在可调用的路由中使用:

$app->get('/list', function ($request, $response) {
    $table = $this->get('db')->table('table_name');
    $data = $table->get();

    // do something with data
    $response->write(print_r($data, true));

    return $response;

});

这里的文档中的完整详细信息:http://www.slimframework.com/docs/cookbook/database-eloquent.html

【讨论】:

    猜你喜欢
    • 2022-12-05
    • 2013-11-12
    • 2013-07-21
    • 2021-01-17
    • 2017-12-27
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    相关资源
    最近更新 更多