Соединение с БД в PHP Socket Server - PullRequest
0 голосов
/ 29 апреля 2018

Я запускаю консольное приложение Yii2, которое запускает службу чата websocket. Что все работает нормально и как положено, но через некоторое время бездействия я получаю SQLSTATE[HY000]: General error: 2006 MySQL server has gone away. Я пытался увеличить время ожидания, установить для пользователя abort значение false и установить PDO::ATTR_PERSISTENT => true в конструкторе PDO, но это все еще происходит.

Есть ли способ проверить, активно ли еще соединение с базой данных или нет, как повторно подключиться к БД. Либо в чистом php, либо лучше с фреймворком Yii2.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

У меня была похожая проблема, и я решил ее, создав собственный класс для подключения к БД, который гарантирует, что подключение будет активным до фактического запроса.

class DbConnection extends \yii\db\Connection {

    private $stamp;

    /**
     * {@inheritdoc}
     */
    public function createCommand($sql = null, $params = []) {
        try {
            // send ping on every 10 seconds
            if ($this->stamp < time()) {
                $this->stamp = time() + 10;
                parent::createCommand('SELECT 1')->execute();
            }
        } catch (\yii\db\Exception $e) {
            // if ping fail, reconnect
            $this->close();
            $this->open();
        }
        return parent::createCommand($query);
    }
}

Один раз каждые 10 секунд отправляет запрос ping перед созданием команды. В случае сбоя проверки связи (соединение было прервано), он пытается восстановить соединение.

Это не помешает отсоединению, но оно автоматически восстановит соединение в случае, если соединение было прервано. Это может быть сложно, если вы используете транзакции - если соединение прерывается в середине транзакции, транзакция будет неявно откатываться БД, а приведенный выше код будет неявно переподключаться, так что вы даже не заметите, что ваша транзакция была откатом в некоторых случаях. точка.

Также я не тестировал его в конфигурации «ведущий-ведомый». Но в моем случае это прекрасно работало (подключение только для чтения к одному серверу), поэтому вы можете использовать его в качестве базы и настроить его для своих нужд с помощью дополнительных проверок транзакций или соединений master / slave.

0 голосов
/ 29 апреля 2018

Не уверен, куда именно вам следует обратиться именно для этого кода, но соответствующий код, чтобы проверить, является ли соединение активным, можно использовать следующие методы в yii\db\Connection классе

getIsActive(): возвращает значение, указывающее, установлено ли соединение с БД. установлено.

и для переподключения вы можете использовать

open(): устанавливает соединение с БД. Ничего не делает, если БД соединение уже установлено.

if(Yii::$app->db->isActive === FALSE){
     Yii::$app->db->open();
}
...