>  기사  >  백엔드 개발  >  mysql 연결이 중단되었을 때 자동으로 다시 연결하는 방법

mysql 연결이 중단되었을 때 자동으로 다시 연결하는 방법

jacklove
jacklove원래의
2018-06-08 23:11:422244검색

PHP를 백그라운드 실행 프로그램(대량 SMS 등)으로 사용하고 PHP를 CLI 모드에서 실행하면 루프에서 데이터베이스 처리를 수행하려면 PHP가 MySQL에 연결되어야 합니다.
mysql 연결이 중단되면 이후 루프 실행이 실패합니다.

후속 프로그램이 정상적으로 실행될 수 있도록 mysql 연결이 끊길 때 자동으로 다시 연결할 수 있는 방법을 설계해야 합니다.

1. 테스트 데이터 테이블 만들기

CREATE TABLE `user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2. 테스트 데이터 삽입

insert into user(name) values('fdipzone'),('xfdipzone'),('terry');mysql> select * from user;
+----+-----------+| id | name      |
+----+-----------+|  1 | fdipzone  |
|  2 | xfdipzone ||  3 | terry     |
+----+-----------+

3. 백그라운드에서 실행 중인 PHP 파일

db.php

<?php// 数据库操作类class DB{
    // 保存数据库连接
    private static $_instance = null;    // 连接数据库
    public static function get_conn($config){
        if(isset(self::$_instance) && !empty(self::$_instance)){            return self::$_instance;
        }        $dbhost = $config[&#39;host&#39;];        $dbname = $config[&#39;dbname&#39;];        $dbuser = $config[&#39;user&#39;];        $dbpasswd = $config[&#39;password&#39;];        $pconnect = $config[&#39;pconnect&#39;];        $charset = $config[&#39;charset&#39;];        $dsn = "mysql:host=$dbhost;dbname=$dbname;";        try {            $h_param = array(
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            );            if ($charset != '') {                $h_param[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset; //設置默認編碼
            }            if ($pconnect) {                $h_param[PDO::ATTR_PERSISTENT] = true;
            }            $conn = new PDO($dsn, $dbuser, $dbpasswd, $h_param);
        } catch (PDOException $e) {            throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);
        }        self::$_instance = $conn;        return $conn;
    }    // 执行查询
    public static function query($dbconn, $sqlstr, $condparam){
        $sth = $dbconn->prepare($sqlstr);        try{            $sth->execute($condparam);
        } catch (PDOException $e) {            echo $e->getMessage().PHP_EOL;
        }        $result = $sth->fetchAll(PDO::FETCH_ASSOC);        return $result;
    }
}?>

test.php

<?phprequire &#39;db.php&#39;;// 数据库设定$config = array(    &#39;host&#39; => 'localhost',    'dbname' => 'user',    'user' => 'root',    'password' => '',    'pconnect' => 0,    'charset' => '');// 循环执行while(true){    // 创建数据连接
    $dbconn = DB::get_conn($config);    // 执行查询
    $sqlstr = 'select * from user where id=?';    $condparam = array(mt_rand(1,3));    $data = DB::query($dbconn, $sqlstr, $condparam);
    print_r($data);    // 延时10秒
    echo 'sleep 10'.PHP_EOL.PHP_EOL;
    sleep(10);
}?>

4 실행 단계

php cli 모드에서 test.php를 실행한 후 즉시 mysql.server stop 및 mysql.server start를 실행하여 플래시 중단을 시뮬레이션합니다

mysql.server stopShutting down MySQL
.. SUCCESS! 
mysql.server start
Starting MySQL
 SUCCESS!

플래시 중단 후 데이터베이스를 다시 연결할 수 없는 것을 확인할 수 있으며, 후속 프로그램을 실행할 수 없습니다.

Array
(
    [0] => Array
        (
            [id] => 3
            [name] => terry
        )
)
sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Array
(
)
sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Array
(
)
sleep 10...

5. 재연결 메커니즘 추가

if(isset(self::$_instance) && !empty(self::$_instance)){    return self::$_instance;
}

중단 후 self::$_instance 값이 존재하므로 get_conn을 호출하면 다시 연결되지 않지만 저장된 연결을 사용하여 처리합니다.

실제로는 연결이 존재하면 mysql 연결을 다시 생성할 필요가 없으므로 mysql 연결 수가 줄어듭니다.

그러므로 생성되었으나 실패한 데이터베이스 연결을 사용하지 않고 다음에 연결을 다시 얻을 수 있도록 중단 후 self::$_instance 값을 지워야 합니다.

개선 사항은 다음과 같습니다.
오류 발생 시 호출되는 reset_connect 메소드를 추가합니다. 오류가 MySQL 서버가 사라졌습니다인 경우 기존 데이터베이스 연결이 지워지고 다음에 MySQL이 다시 연결됩니다.

수정된 php 파일은 다음과 같습니다.
db.php

<?php// 数据库操作类class DB{
    // 保存数据库连接
    private static $_instance = null;    // 连接数据库
    public static function get_conn($config){
        if(isset(self::$_instance) && !empty(self::$_instance)){            return self::$_instance;
        }        $dbhost = $config[&#39;host&#39;];        $dbname = $config[&#39;dbname&#39;];        $dbuser = $config[&#39;user&#39;];        $dbpasswd = $config[&#39;password&#39;];        $pconnect = $config[&#39;pconnect&#39;];        $charset = $config[&#39;charset&#39;];        $dsn = "mysql:host=$dbhost;dbname=$dbname;";        try {            $h_param = array(
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            );            if ($charset != '') {                $h_param[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $charset; //設置默認編碼
            }            if ($pconnect) {                $h_param[PDO::ATTR_PERSISTENT] = true;
            }            $conn = new PDO($dsn, $dbuser, $dbpasswd, $h_param);
        } catch (PDOException $e) {            throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);
        }        self::$_instance = $conn;        return $conn;
    }    // 执行查询
    public static function query($dbconn, $sqlstr, $condparam){
        $sth = $dbconn->prepare($sqlstr);        try{            $sth->execute($condparam);
        } catch (PDOException $e) {            echo $e->getMessage().PHP_EOL;            self::reset_connect($e->getMessage()); // 出错时调用重置连接
        }        $result = $sth->fetchAll(PDO::FETCH_ASSOC);        return $result;
    }    // 重置连接
    public static function reset_connect($err_msg){
        if(strpos($err_msg, 'MySQL server has gone away')!==false){            self::$_instance = null;
        }
    }
}?>

6. 플래시 실행을 다시 수행해 보세요

플래시 이후 현재 실행은 실패하지만 후속 실행은 가능해지는 개선된 효과를 보실 수 있습니다. 새 연결을 다시 만들고 실행을 계속합니다.

Array(
    [0] => Array
        (
            [id] => 2
            [name] => xfdipzone
        )
)
sleep 10SQLSTATE[HY000]: General error: 2006 MySQL server has gone awayArray(
)
sleep 10Array(
    [0] => Array
        (
            [id] => 1
            [name] => fdipzone
        )
)
sleep 10...

이 기사에서는 mysql 연결이 중단되었을 때 자동으로 다시 연결하는 방법에 대한 관련 지식을 설명합니다. 더 많은 관련 내용을 보려면 PHP 중국어 웹사이트를 참고하세요.

관련 권장사항:

php는 HTML 엔터티 숫자와 비ASCII 문자열을 변환하기 위한 클래스를 구현합니다.

php는 자동 증가 ID를 기반으로 고유한 숫자 클래스를 생성합니다.

mysql 정보 현재 보기 사용된 구성 파일 my.CNF 방법 설명

위 내용은 mysql 연결이 중단되었을 때 자동으로 다시 연결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.