MySQL
挂了, 然后导致整个服务崩塌, Redis
在前面完全没分担任何压力
.redis
中获取数据, 有则返回redis
无数据, 去MySQL
查询数据redis
redis
当然不会有问题, 问题是在第二步的时候MySQL
查询数据,数据库服务已经宕机, 这时候请求阻塞住MySQL
,无限阻塞,把业务服务器也拖垮MySQL
宕机强制缓存空数据到redis
,允许部分页面为空.而不是无法提供服务MySQL
连接超时时间 mysqlnd.net_read_timeout = 3
BaseModel
, 其它所有模型继承这个模型, 并重写newEloquentBuilder
方法<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BaseModel extends Model
{
public function newEloquentBuilder($query)
{
return new MysqlCustomBuilder($query);
}
}
MysqlCustomBuilder
<?php
namespace App\Models\Database;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
class MysqlCustomBuilder extends Builder
{
public function get($columns = ['*'])
{
try {
return parent::get($columns);
} catch (\Exception $e) {
// 根据 laravel 重连的错误码
$message = $e->getMessage();
if (Str::contains($message, [
'server has gone away',
'no connection to the server',
'Lost connection',
'is dead or not enabled',
'Error while sending',
'decryption failed or bad record mac',
'server closed the connection unexpectedly',
'SSL connection has been closed unexpectedly',
'Error writing data to the connection',
'Resource deadlock avoided',
])) {
// 记录日志, 通知xxx
// Log::error($e);
// 强制返回空集合
return Collection::make();
}
// 如果不在处理的范围内, 继续抛出异常
throw $e;
}
}
}