Престашоп фоновый импорт сыпучих продуктов - PullRequest
0 голосов
/ 16 октября 2018

Я пытаюсь эффективно импортировать 15K + продуктов периодически в электронную коммерцию Prestashop, анализируя файл ASCII (3,5 МБ) и используя только API Prestashop.

Все запускаются под докером, с официальными изображениями из докера.

Если товара с таким же справочным полем не существует, мне придется вставить новый товар, если он есть, чтобы обновить его.Я разработал модуль, который делает это с помощью щелчка мышью на пользовательской вкладке администратора, и он работает, но вся система зависает до завершения или завершения процесса: (почти 77 минут).Я также попытался разбить (не очень) большой файл на куски по 500, 100, 50, но время на обработку уменьшается линейно, это не очень помогает:

  • 153 секунд за500 элементов
  • 31 средняя секунда для 100 элементов
  • 15 средняя секунда для 50 элементов

Я мог бы точно настроить крон каждые 90 секунд для обработки 50 элементов, изавершите весь импорт за 7-8 ночных часов, но это кажется очень плохим компромиссом: 15 секунд в автономном режиме каждые 90.

Я не могу использовать pthreads , так как это будет производственный веб-сервер.

Я пытался настроить Apache, увеличивая memory_limit, max_input_vars, max_execution_time, но без каких-либо различий: БД использует от 450 МБ до 550 МБ ОЗУ и сервер практически идентичен.

Linux # 1 SMP Debian 4.9.110-3 + deb9u6 (2018-10-08) x86_64

Versione Software Del Server: Apache / 2.4.10 (Debian)

Versione di PHP: 5.6.35

memory_limit = 2048M

max_input_vars = 1000000

max_execution_time = 600000

MySQL: 5.6.40

Неправильно ли я столкнулся с проблемой, или API Prestashop не выполнен и сделандля массового (и производительного) импорта продукта?

public function batchImportAllProductsFromFile($productsToBeInserted){
    foreach ($productsToBeInserted as $key => $customProduct ) {

        $productIDs = $this->getProductIDsByReference($customProduct->MS_CODMAG);
        if (sizeof($productIDs) == 0) {
            $product = new Product();
        } else if (sizeof($productIDs) == 1) {
            $product = new Product($productIDs[0]);
        } else {
            continue;
        }

        $product->reference = $customProduct->MS_CODMAG;
        $product->name = trim($customProduct->MS_DESCRIZIONE);
        $product->price = $customProduct->MS_PREZZO_1;
        $product->out_of_stock = ($customProduct ->MS_ESAURITO === "S" ? true : false);

        $category = null;

        $msGruppoConverted = $this->buildSubGroupCode($customProduct->MS_GRUPPO, $customProduct->MS_SGRUPPO);

        if ($customProduct->MS_GRUPPO !== 0 && $msGruppoConverted !== 0) {
            $product->id_category = [$customProduct->MS_GRUPPO, $msGruppoConverted];
        } else if ($customProduct->MS_GRUPPO === 0 && $msGruppoConverted !== 0) {
            $product->id_category = [$msGruppoConverted];
        } else if ($customProduct ->MS_GRUPPO !== 0 && $msGruppoConverted === 0) {
            $product->id_category = [$customProduct->MS_GRUPPO];
        }
        try {
            if (sizeof($productIDs) == 0) {
                if ($product->add()) {
                    $product->updateCategories($product->category);
                    $product->addFeatureProductImport($product->id, 1, $customProduct->MS_FAM);
                    //StockAvailable::setQuantity((int)$product->id, 0, $product->quantity, Context::getContext()->shop->id);
                }
            } else if (sizeof($productIDs) == 1) {
                if ($product->update()) {
                    $product->updateCategories($product->category);
                    $alreadySavedFeatures = $product->getFeaturesStatic($productIDs[0]);
                    if (sizeof($alreadySavedFeatures) != 1 || $alreadySavedFeatures[0] != $customProduct->MS_FAM) {
                        $product->deleteProductFeatures();
                        $product->addFeatureProductImport($product->id, 1, $customProduct->MS_FAM);
                    }
                }
            }
        } catch (Exception $e) {
            var_dump("Errore: ", $e, $product);
        }
    }
}

РЕДАКТИРОВАТЬ 22/10/2018:

Обновление до PHP7.2 и использование MariaDB 10.3.10 не принесло мне никаких изменений: время было все ещетот же самый.Что принесло пользу, так это монтирование FS (EXT4), где БД хранит информацию с опцией barrers = 0 в / etc / fstab : производительность улучшена с 153 до 35 секунд для 500 элементов, что в итоге составило около 18 минут (было 77).

Проблема, которая остается открытой, заключается в том, что система перестала отвечать при импорте.

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Что действительно решило мою проблему застревания Prestashop при импорте продуктов, так это переместило мой код из ModuleAdminController в WebserviceSpecificManagementInterface : таким образом, импорт идет в фоновом режиме без насыщения системы.

0 голосов
/ 17 октября 2018

Вы должны убедиться, что ваши продукты нуждаются в обновлении, прежде чем обновлять его.

Вот что я делаю (очень упрощенно) при импорте объектов в Prestashop:

<?php

class myProductImporter {
    protected $products;
    protected $products_checksum;

    public function __construct($products) {
        // Your products from the csv file
        $this->products = $products;
        // Here you get an associative array of products references and checksums
        // ex: array('REF01158' => '489f9ze4f4ze9f49ze8', 'REF15616' => '48949844561233132')
        $this->products_checksum = getProductsChecksum();
    }

    public function run() {
        foreach ($this->products as $product) {
            // If the product ref is present in my checksum list, then its an update
            if (isset($this->products_checksum[$product['reference']])) {
                // If the checksum is different, the product needs an update
                if ($this->products_checksum[$product['reference']] != $this->getChecksum($product)) {
                    $this->updateProduct($product);
                }
            // Else it's a new product
            } else {
                $this->addProduct($product);
            }
        }
    }

    protected function updateProduct($product) {
        $PSProduct = getProductByReferebce($product['reference']);
        // Update your product and save its new checksum
    }

    protected function addProduct($product) {
        $PSProduct = new Product();
        // Create the product and save its checksum
    }

    protected function getChecksum($product) {
        // Create a string containing all your product properties
        $checksum = $product['reference'];
        $checksum .= $product['name'];
        $checksum .= $product['description'];
        $checksum .= $product['id_category'];
        return md5($checksum);
    }
}

Когда нет измененийваш импорт будет немедленно завершен, потому что запросы не обрабатываются.

Что касается зависаний в вашей установке, то это похоже на проблему с Docker и не связано с Prestashop.

Как упоминается @ bruno-leveque вы должны рассмотреть возможность обновления до PHP7.

...