You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel+Docker执行迁移填充时出现SQLSTATE[HY000] [2002]连接拒绝错误

Docker环境下Laravel Seeder批量插入数据时数据库连接拒绝问题解决

问题描述

在Docker环境中运行Laravel执行php artisan migrate:fresh --seed时,所有迁移和短时间数据填充可正常完成,但调用IBGE接口批量插入城市数据的CitySeeder因耗时较长,会抛出固定错误:

SQLSTATE[HY000] [2002] Connection refused (SQL: insert into `cities` (`state_id`, `name`, `iso`) values (16, Itajuípe, 2915502))

核心原因

  1. MariaDB连接超时:默认配置下,MariaDB会自动关闭长时间闲置的连接,Seeder在请求IBGE接口期间,数据库连接处于闲置状态,超过超时阈值后被主动断开,后续插入操作复用了失效连接。
  2. Laravel连接复用机制:Laravel的数据库连接池未自动处理失效连接,闲置过久的连接不会主动重连。

解决方案

方案1:延长MariaDB连接超时时间

修改docker-compose.yml中mysql服务的环境变量,增加超时相关配置:

mysql:
    container_name: mysql
    image: mariadb:latest
    restart: always
    environment: 
        MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
        MYSQL_DATABASE: ${DB_DATABASE}
        MYSQL_USER: ${DB_USERNAME}
        MYSQL_PASSWORD: ${DB_PASSWORD}
        # 延长连接超时参数
        MYSQL_WAIT_TIMEOUT: 3600
        MYSQL_INTERACTIVE_TIMEOUT: 3600
        MYSQL_CONNECT_TIMEOUT: 3600
    volumes: 
        - ./.docker/mariadb:/var/lib/mysql
    ports: 
        - "3306:3306"
    networks: 
        - backend

修改后重启mysql容器:

docker-compose down && docker-compose up -d mysql

方案2:Seeder中手动重连数据库

在请求IBGE接口前,手动检查并重建数据库连接,避免复用失效连接:

namespace Database\Seeders;

use App\Models\City;
use App\Models\State;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\DB;

class CitySeeder extends Seeder
{
    public function run()
    {
        $states = State::orderBy('name')->get();
        
        foreach($states as $state){
            // 检查连接有效性,失效则自动重连
            DB::connection()->getPdo();
            
            $apiCities = Http::get('https://servicodados.ibge.gov.br/api/v1/localidades/estados/'.$state->initials.'/municipios');

            foreach($apiCities->json() as $city){
                City::create([
                    'state_id'=>$state->id,
                    'name'=>$city['nome'],
                    'iso'=>$city['id'],
                ]);
            }
        }
    }
}

方案3:批量插入优化性能

将每个州的城市数据批量收集后一次性插入,减少数据库交互次数,同时避免连接闲置:

namespace Database\Seeders;

use App\Models\City;
use App\Models\State;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Http;

class CitySeeder extends Seeder
{
    public function run()
    {
        $states = State::orderBy('name')->get();
        
        foreach($states as $state){
            $apiCities = Http::get('https://servicodados.ibge.gov.br/api/v1/localidades/estados/'.$state->initials.'/municipios');
            
            $citiesData = [];
            foreach($apiCities->json() as $city){
                $citiesData[] = [
                    'state_id'=>$state->id,
                    'name'=>$city['nome'],
                    'iso'=>$city['id'],
                    'created_at' => now(),
                    'updated_at' => now()
                ];
            }
            
            // 批量插入,减少数据库请求次数
            City::insert($citiesData);
        }
    }
}

额外检查项

确认Laravel .env 文件中数据库主机配置为Docker服务名mysql,而非localhost或127.0.0.1:

DB_HOST=mysql
DB_PORT=3306

内容的提问来源于stack exchange,提问作者Fabricio Gwadera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:09:24