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