【问题标题】:I get a 504 timeout error when importing excel to a db (Laravel)将 excel 导入数据库时​​出现 504 超时错误(Laravel)
【发布时间】:2020-06-02 20:40:18
【问题描述】:

我正在尝试使用 Laravel 中的库“Maatwebsite / Laravel-Excel”在 excel 中导入 10,000 条记录,但是在导入 10,000 条记录时,页面返回 504 超时错误(奇怪的是它一直在之后的分贝)。那么,我给你看我的代码,看看你能不能帮助我,谢谢。

这是导入清单,我在其中编写了我应该对要导入数据库的数据执行的所有操作。

class InventarioImport implements ToCollection, WithChunkReading
{
    use Importable;
    /**
     * @param array $row
     *
     * @return User|null
     */

    public function chunkSize(): int
    {
        return 250;
    }


    public function collection(collection $rows)
    {
         foreach ($rows as $row)
        {

        $almacenes = Almacen::where('tienda_id', \Session::get('tienda_id'))->get();
        $codigos = Codigo::where('tienda_id', \Session::get('tienda_id'))->get();
        $contc=-1;
        $conta=0;

        foreach ($codigos as $codigo) {
            $contc++;
        }
        foreach ($almacenes as $almacen) {
            $conta++;
        }
        if($row[$contc+1]=="DESCRIPCION") {
                continue 1;

            }

        $idmarca = Marca::where('nombre_marca', $row[$contc+2])->where('tienda_id', \Session::get('tienda_id'))->first();

        if ($idmarca==null) {
           $marcaid= Marca::create([
           'nombre_marca'     => $row[$contc+2],
           'tienda_id'     => \Session::get('tienda_id'),
           'estado'     => "A",

        ])->id;
}
else {
  $marcaid = $idmarca->id;
}
$buscarcategoria = Categoria::where('nombre_categoria', $row[$contc+3])->where('tienda_id', \Session::get('tienda_id'))->first();
        if ($buscarcategoria==null) {
           Categoria::create([
           'nombre_categoria'     => $row[$contc+3],
           'tienda_id'     => \Session::get('tienda_id'),
           'estado'     => "A",

        ]);
}
$i=0;
       $buscaritem = Item::where('nombre_item', $row[$contc+1])->where('tienda_id', \Session::get('tienda_id'))->first();

 $buscarunidad = Unidad::where('nombre_unidad', $row[$contc+4])->first();


   $buscarmoneda = ConfiguracionMoneda::where('abreviacion_moneda', $row[$conta+3+$contc+4])->where('tienda_id', \Session::get('tienda_id'))->first();
    $itemid= Item::create([
            'marca_id' => $marcaid,
           'nombre_item'     => $row[$contc+1],
           'unidad_id'     => $buscarunidad->id,
           'stock_minimo'     => $row[$conta+1+$contc+4],
           'stock_maximo'     => $row[$conta+2+$contc+4],
           'moneda_id'     => $buscarmoneda->id,
           'precio'     => $row[$conta+4+$contc+4],
           'impuesto'     => $row[$conta+5+$contc+4],
           'margen_final'     => $row[$conta+6+$contc+4],
           'margen_inicio'     => $row[$conta+7+$contc+4],
           'notas'     => $row[$conta+8+$contc+4],
           'estado'     => "A",
           'tienda_id'     => \Session::get('tienda_id'),

        ])->id;
        $a=$contc+4;
        $j=$a+1;
        foreach ($almacenes as $almacen) {

       $buscaralmacen = Almacen::where('nombre_almacen', $almacen->nombre_almacen)->where('tienda_id', \Session::get('tienda_id'))->first();

          ItemStock::create([
           'item_id'     => $itemid,
           'almacen_id' => $buscaralmacen->id,
           'detalle' => "Saldo Inicial",
            'cantidad' => $row[$j],
            'tipo' => "M",

           'tienda_id'     => \Session::get('tienda_id'),
           'estado'     => "A",
        ]);


        $kardex = new Kardex();
                $kardex->item_id = $itemid;
                $kardex->fecha = date("Y/m/d");
                $kardex->operacion = "Inicial";
 $kardex->tipo = "";
 $kardex->serie = "";
 $kardex->numero = "";

                $kardex->almacen_id = $buscaralmacen->id;
                $kardex->tienda_id = \Session::get('tienda_id');
                $kardex->saldocantidad = $row[$j];
                $kardex->saldocosto = $row[$conta+4+$contc+4];
                $kardex->saldototal = $row[$conta+4+$contc+4]*$row[$j];

                $kardex->save();
                $j++;
 }

  foreach ($codigos as $codigo) {

       $buscarcodigo = Codigo::where('nombre_codigo', $codigo->nombre_codigo)->where('tienda_id', \Session::get('tienda_id'))->first();
       $buscaritem = Item::where('nombre_item', $row[$contc+1])->where('tienda_id', \Session::get('tienda_id'))->first();

          ItemCodigo::create([
           'item_codigo'     => $row[$i],
           'codigo_id' => $buscarcodigo->id,
           'item_id' => $buscaritem->id,
           'tienda_id'     => \Session::get('tienda_id'),
           'estado'     => "A",
        ]);
        $i++;


 }


    }
    }
}

这是我在 Controller 中的函数,我按照前面脚本中的说明进行导入。

public function subirinventario(Request $request)
    {
        $title = 'Inventario subido';

        $contarr= $request->contarr;
  $arrayitems = Excel::import(new InventarioImport, $request->path);
        return view('item.finalizar', compact('contarr','title'));
    }

就这样,我错过了路线和视图,但是记录很少,我必须强调我增加了nginx的运行时间,重新启动并没有。

This is an image with the preview of the data and columns, only 10 are shown, but more than 10 thousand were detected.

【问题讨论】:

  • 长时间运行的脚本(例如大型插入)最好通过命令行完成或卸载到队列中。即使脚本仍在运行,服务器或 Web 浏览器也会返回超时。
  • 您好,感谢您的回复,我对这台服务器有点新手,如果我在我的服务器上配置了 20 分钟的运行时间,而对于 10,000 条记录,它甚至不需要 5 分钟,为什么超时出来?我不明白。
  • 你能发布你的 nginx 和 vhost 配置吗?以及与 fastcgi_* 和 proxy_* 指令相关的任何内容。
  • 另外,该代码需要重构——查询的数量和效率低下会导致它需要很长时间来处理。您可以尝试拆分文档,将其排队等待处理,分批读取等。但无论您最终在 nginx 中使用什么设置,有时它们都无济于事,因为此过程需要 10 分钟完成 50k 行。所以你需要优化代码。从队列开始,然后是批处理。然后想办法在界面中显示进度。

标签: php mysql laravel nginx server


【解决方案1】:

您可以尝试将这两行放在方法/函数的开头:

    ini_set('memory_limit','1024M');
    set_time_limit(3000000); //You can use 0 to remove limits

如上所述,您可以在 set_time_limit 方法中使用 0,但我不建议这样做,因为在大多数情况下,失去对执行的所有控制是不值得的

希望它有效!

【讨论】:

  • 好的,肯定是因为你在导入类的collection方法中所做的所有foreach,你有没有试过把这些行放在里面?
  • 是的,我把它放在 Importer 和 Controller 中,但我仍然收到错误 504。
  • Ups,对不起,没有读到你正在使用 nginx... ^.^' stackoverflow.com/questions/16002268/… 也许这个帖子的最佳答案可以帮助?
  • 感谢您继续与我合作,我仍然无法使其工作,我已将 nginx 配置为帖子中提到的所有内容,重新启动后什么也没有。 = (
猜你喜欢
  • 1970-01-01
  • 2017-04-26
  • 2019-07-05
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 2018-12-05
  • 2017-08-31
相关资源
最近更新 更多