В очереди Laravel не хватает памяти на сервере, но не на локальном хосте, даже если выделенная память больше на серверах - PullRequest
0 голосов
/ 13 января 2019

Я пытаюсь сбросить данные в базу данных из CSV. Это отнимает много времени, поэтому я решил пойти с очередью Laravel.

Главное странное различие между сервером и локальным хостом здесь:

$insertJob = (new StoreUser($data))->delay(Carbon::now()->addSeconds(3)); 
        dispatch($insertJob);
        $msg = [
            'status' => '1'
        ];
        echo json_encode($msg);
        exit();

Здесь, в вышеприведенном случае, в localhost, как только задание отправляется, оно отправляет status - 1. Таким образом, появляется всплывающее сообщение «Вы получите уведомление по электронной почте после завершения работы». Но на сервере он продолжает отображать панель загрузки, т. Е. Не возвращает статус обратно.

И через некоторое время появляется внутренняя ошибка сервера.

ЖУРНАЛ ОШИБКИ PHP:

27351#27351: *114475 FastCGI sent in stderr: “PHP message: PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 20480....)

Я не получаю его даже на локальном хосте. Я выделяю 128 МБ, а на сервере - около 1 ГБ.

Журнал супервизора:

2019-01-08 15:48:01,121 CRIT Supervisor running as root (no user in config file)
2019-01-08 15:48:01,122 WARN No file matches via include “/etc/supervisor/conf.d/*.conf”
2019-01-08 15:48:01,134 INFO RPC interface ‘supervisor’ initialized
2019-01-08 15:48:01,134 CRIT Server ‘unix_http_server’ running without any HTTP authentication checking
2019-01-08 15:48:01,134 INFO supervisord started with pid 2947
2019-01-08 16:17:45,836 INFO spawnerr: can’t find command ‘/home/forge/site_address/php’
2019-01-08 16:17:46,837 INFO spawnerr: can’t find command ‘/home/forge/site_address/php’
2019-01-08 16:17:48,841 INFO spawnerr: can’t find command ‘/home/forge/site_address/php’
2019-01-08 16:17:51,845 INFO spawnerr: can’t find command ‘/home/forge/site_address/php’
2019-01-08 16:17:51,846 INFO gave up: project_queue entered FATAL state, too many start retries too quickly
2019-01-10 16:14:18,566 INFO spawned: ‘project_queue’ with pid 25817
2019-01-10 16:14:19,591 INFO success: project_queue entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

На случай, если вам интересно, что именно там находится внутри StoreUser

$db_header_obj = new Class_user();
$db_header = $db_header_obj->getTableColumns();

$base_user_header = new Base_user();
$base_user_columns = $base_user_header->getTableColumns();

$csv_file_path = storage_path('app/files/class_user/').$filename;
if (!ini_get("auto_detect_line_endings")) {
    ini_set("auto_detect_line_endings", TRUE);
}
$csv = Reader::createFromPath($csv_file_path, 'r');

$csv->setOutputBOM(Reader::BOM_UTF8);

$csv->addStreamFilter('convert.iconv.ISO-8859-15/UTF-8');
$csv->setHeaderOffset(0); 
$csv_header = $csv->getHeader();    


$error_arr = array();
$row_number = array();
$error_row_numbers = array();


$loop = true;

while($loop){


$rec_arr = array();
$records = array();
$records_arr = array();

        $stmt = (new Statement())
        ->offset($offset)
        ->limit($limit)
        ;

        $records = $stmt->process($csv);

        foreach ($records as $record) 
        {
            $rec_arr[] = array_values($record);
        }

        $records_arr = $service->trimArray($rec_arr);

        if(count($records_arr)>0)
        {
            foreach($records_arr as $ck => $cv){

                $existing = NULL;
                $class_user_arr = array();

                //format datatype and check either the column should be inserted or not
                foreach ($map_data as $mk => $mv) {
                    if(isset($mv)){
                        $data_type = $service->getDatabaseColumnType($table,$mv);
                        if($data_type == 'date' || $data_type == 'datetime' || $data_type == 'timestamp'){
                            $datetime =  (array)$cv[$mk];
                            $dt = array_shift($datetime);
                            $dt = date('Y-m-d h:i:s', strtotime($dt));
                            $class_user_arr[$mv] = $dt;
                        }else{
                            $class_user_arr[$mv] = $cv[$mk];
                        }  

                    }
                }

                //setting some boolean variable
                $updated_base = false;
                $updated_class = false;
                $error_encountered = false;
                $base_user_table_id = NULL;


                $base_user_arr = array();
                foreach($class_user_arr as $cvk => $cvv){
                    if(in_array($cvk,$base_user_columns))
                    {
                        $base_user_arr[$cvk] = $cvv;
                    }
                }

                DB::beginTransaction();


                //trying to insert into base or first table
                try{
                        $base_user_row = Base_user::updateOrCreate(
                            ['base_id' => $base_user_arr['base_id']],
                            $base_user_arr
                        );
                        if ($base_user_row->wasRecentlyCreated === true) {
                            $base_user_row->created_by = $this->data['user_id'];
                        }else{
                            $base_user_row->updated_by = $this->data['user_id'];
                        }
                        $base_user_row->save();
                        $base_user_table_id = $base_user_row->id;
                        $updated_base = true;
                    } catch (\Exception $e) {
                        $error_encountered = true;
                         $error_arr[] = $e->getMessage();
                         $error_row_numbers[] = $row_no; 
                    }


                //Using row id from first table inserting data into table number 2
                if($error_encountered == false){

                    try{
                            $class_user_row = class_user::updateOrCreate(
                                ['base_user_id' => $base_user_table_id],
                                $class_user_arr
                            );
                            if ($class_user_row->wasRecentlyCreated === true) {
                                $class_user_row->created_by = $this->data['user_id'];
                            }else{
                                $class_user_row->updated_by = $this->data['user_id'];
                            }
                            $class_user_row->save();
                        } catch (\Exception $e) {
                            $error_encountered = true;
                             $error_arr[] = $e->getMessage();
                             $error_row_numbers[] = $row_no; 
                             DB::rollback();
                        }

                }


                DB::commit();
                $row_no = $row_no + 1;

            }

            $offset = $offset + $limit;

        }else{

            $activity = new Activity();
            $activity->url = $this->data['url'];
            $activity->action = 'store';
            $activity->description = $table;
            $activity->user_id = $this->data['user_id'];
            $activity->created_at = date('Y-m-d H:i:s');
            $activity->save();

            $arr_data = [
                    'filename' => $filename,
                    'user_name' => $this->data['user_name'],
                    'error' => $error_arr,
                    'error_row_numbers' => $error_row_numbers
                ];

            //informing to the user about the completion of job    
            Mail::to($this->data['user_email'])->send(new CSVImportJobComplete($arr_data));

            $loop = false;
        }

}


if (!ini_get("auto_detect_line_endings")) {
    ini_set("auto_detect_line_endings", FALSE);
}

Я не в курсе, в чем может быть причина. Дайте мне знать, если вам нужна дополнительная информация.

UPDATE: production.ERROR: Allowed memory size of 2147483648 bytes exhausted (tried to allocate 20480 bytes) Я почти уверен, что обновление выделения памяти не является решением. Поскольку я успешно справляюсь с этим на локальном сервере с 128 МБ, а не на сервере даже с 2 ГБ

1 Ответ

0 голосов
/ 04 февраля 2019

После долгих поисков я обнаружил, что это из-за одной простой разницы в файле .env.

Мне нужно обновить

QUEUE_DRIVER=sync

до

QUEUE_DRIVER=database

на сервере.

...