Интеграция Magento с Cloud Spanner

1. Введение

424db48d9db91638.png

Интеграция Magento с бэкэндом Cloud Spanner.

Magento — это широко популярная платформа электронной коммерции с открытым исходным кодом, основанная на PHP, которая хранит данные в MySQL.

Данный практический пример демонстрирует возможность использования Cloud Spanner вместо MySQL для модуля Catalog. Он будет полезен всем, кто заинтересован в интеграции, тестировании и развертывании Magento или других PHP-приложений с помощью Spanner.

Spanner — это полностью управляемая, распределенная и согласованная база данных корпоративного уровня от Google Cloud, которая сочетает в себе преимущества реляционной модели баз данных с горизонтальной масштабируемостью нереляционных баз данных. Она разработана для поддержки глобальных развертываний обработки онлайн-транзакций, семантики SQL, высокой доступности, горизонтального масштабирования и транзакционной согласованности. Spanner способна обрабатывать большие объемы данных. Ее использование не ограничивается приложениями большого размера, но позволяет стандартизировать единый механизм базы данных для всех рабочих нагрузок, требующих СУБД. Spanner обеспечивает нулевое время простоя при плановом техническом обслуживании или региональных сбоях, с соглашением об уровне обслуживания (SLA) доступности 99,999% . Она поддерживает современные приложения, обеспечивая высокую доступность и масштабируемость.

Что вы узнаете

  • Как установить Magento на GCE
  • Как настроить эмулятор гаечного ключа
  • Как перенести существующую схему MySQL в Spanner с помощью HarbourBridge
  • Что нужно изменить, чтобы интегрировать PHP-приложения, такие как Magento, использующие MySQL в качестве базы данных, в Spanner?

Что вы построите

Данный практический урок посвящен интеграции Magento со Spanner. Предоставляются блоки кода и инструкции по настройке, которые вы можете скопировать и вставить, но подробно они не рассматриваются.

В этом практическом занятии вы начнёте интегрировать Magento со Spanner. Вы:

Что вам понадобится

  • Проект Google Cloud, подключенный к платежному аккаунту.
  • Знание PHP, Linux и конфигурации Apache является преимуществом.
  • Опыт работы с Magento будет полезен, но не обязателен.

2. Подготовка экземпляра GCE

Создайте экземпляр GCE.

Создайте экземпляр Compute Engine в Google Cloud Platform, следуя инструкциям, приведенным здесь .

При создании экземпляра GCE измените тип экземпляра на e2-standard-2 и размер загрузочного диска на 20 ГБ. Вы можете оставить все значения по умолчанию, но обязательно выберите «Разрешить HTTP-трафик» и «Разрешить HTTPS-трафик», поскольку мы будем использовать веб-интерфейс Magento.

В результате получается машина типа e2-standard-2 , которая не является экземпляром с общим ядром и имеет 2 виртуальных процессора, 8 ГБ оперативной памяти и 20 ГБ дискового пространства.

Операционная система — Debian 10. Создание экземпляра может занять одну-две минуты.

После создания учетной записи войдите в систему, нажав кнопку «SSH» в консоли Cloud Console :

4bf915ef8d37c942.png

Это откроет новое окно браузера и переведет вас в терминал.

Установите необходимое программное обеспечение.

Для запуска Magento потребуется установить некоторое необходимое программное обеспечение. В частности, вам нужно будет установить PHP, Elastic, MySQL и Apache, как описано ниже.

  1. Установите необходимые пакеты.
sudo apt update

sudo apt -y install lsb-release apt-transport-https ca-certificates wget git screen composer google-cloud-sdk-spanner-emulator gcc
  1. Установите необходимые для Magento модули PHP.
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg

echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list

sudo apt update

sudo apt -y install php7.4-fpm php7.4-common php7.4-mysql php7.4-gmp php7.4-curl php7.4-intl php7.4-mbstring php7.4-xmlrpc php7.4-gd php7.4-xml php7.4-cli php7.4-zip php7.4-bcmath php7.4-soap php7.4-grpc
  1. Установите Elasticsearch и запустите службу.
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list

sudo apt update && sudo apt -y install elasticsearch

echo "-Xms1g
-Xmx1g" | sudo tee /etc/elasticsearch/jvm.options.d/jvm.options

sudo systemctl start elasticsearch.service
  1. Установите MySQL

Вы устанавливаете MySQL, чтобы получить схему Magento по умолчанию. Позже вы перенесете эту схему в Spanner с помощью HarbourBridge.

wget https://dev.mysql.com/get/mysql-apt-config_0.8.13-1_all.deb

sudo dpkg -i mysql-apt-config*

Приведенная выше команда dpkg откроет интерактивную командную строку для установки сервера MySQL 5.7. Выберите следующие параметры:

  • Сервер и кластер MySQL
  • mysql-5.7
  • Хорошо

a018bfc2ee00bdf5.png1a126e452ca7312e.pngae39c6f4bbe3be74.png

sudo apt update && sudo apt -y install mysql-server
# You will be prompted to enter a root password
  1. Установите Apache2
sudo apt -y install apache2

sudo a2enmod proxy_fcgi rewrite

Установите и настройте Magento2.

Проект Magento Commerce Cloud включает в себя схему базы данных и сервисы для полного доступа к сайту и магазину Magento.

Самый простой способ установить и запустить это — следовать инструкциям Magento по установке с помощью Composer:

  1. Установите Magento версии 2.4.2 с помощью Composer. Для Magento 2 требуется версия Composer 1.x. Возможно, вы увидите предупреждения о том, что поддержка этой версии устарела.
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
  1. Установить права доступа к папке
cd magento2

find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +

find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +
  1. Для настройки виртуального хоста Magento создайте файл /etc/apache2/sites-available/magento.conf со следующим содержимым.
sudo nano /etc/apache2/sites-available/magento.conf

<VirtualHost *:80>
        ServerAdmin admin@local-magento.com
        DocumentRoot /var/www/html/magento/

        <Directory /var/www/html/magento/>
                Options Indexes FollowSymlinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        <FilesMatch \.php$>
               SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"
        </FilesMatch>

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
  1. Создайте символические ссылки и перезапустите apache2.
cd ~/magento2
sudo ln -s $(pwd) /var/www/html/magento 
sudo ln -s /etc/apache2/sites-available/magento.conf  /etc/apache2/sites-enabled/magento.conf
sudo rm /etc/apache2/sites-enabled/000-default.conf

sudo systemctl restart apache2
  1. Создайте базу данных и учетную запись пользователя для Magento в MySQL.
export ROOT_PASSWORD="<root password from installation>"
export GCE_INSTANCE_IP="<GCE instance IP>"
mysql -uroot -p$ROOT_PASSWORD -e "create database magento"

bin/magento sampledata:deploy

bin/magento setup:install --base-url=http://$GCE_INSTANCE_IP/ --db-host=localhost \
--db-name=magento --db-user=root --db-password=$ROOT_PASSWORD --admin-firstname=admin \
--admin-lastname=demo --admin-email=good@example.com --admin-user=admin \
--admin-password=magento123 --language=en_US --currency=USD --timezone=America/Chicago \
--use-rewrites=1

sudo chown -R :www-data ~/magento2/. 
  1. Проверьте локальное рабочее пространство. Чтобы убедиться, что сервер размещен в локальной среде, получите доступ к магазину, используя базовый URL-адрес, указанный в команде установки. В этом примере вы можете получить доступ к локальному магазину Magento, используя следующие форматы URL-адресов:
  • http://<GCEexternalIP>/
  • http://<GCEexternalIP>/<adminuri>

Адрес GCEexternalIP можно найти в Cloud Console :

3947f1164e1d5409.png

Чтобы изменить URI панели администратора, используйте следующую команду для ее определения местоположения:

php bin/magento info:adminuri
  1. Отключение кэширования всей страницы. В целях разработки вы можете отключить кэширование всей страницы в Magento2. Это позволит вам изменять данные в Spanner, и эти изменения будут отображаться на веб-сайте без влияния кэшированных значений.
php bin/magento cache:disable full_page

Гаечный ключ для установки

Установите эмулятор гаечного ключа.

Cloud SDK предоставляет локальный эмулятор в оперативной памяти, который можно использовать для бесплатной разработки и тестирования приложений без создания проекта GCP или платёжного аккаунта. Поскольку эмулятор хранит данные только в памяти, всё состояние, включая данные, схему и конфигурации, теряется при перезапуске. Эмулятор предлагает те же API, что и производственный сервис Spanner, и предназначен для локальной разработки и тестирования, а не для развертывания в производственной среде.

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

Использование эмулятора гаечного ключа

# Set up a new configuration to use the emulator
gcloud config configurations create emulator
gcloud config set auth/disable_credentials true
gcloud config set project magento
gcloud config set api_endpoint_overrides/spanner http://localhost:9020/

# Start emulator in a screen session
screen -S magento
gcloud emulators spanner start &
gcloud spanner instances create magento-instance --config=emulator-config --description='Magento Instance' --nodes=1

# Detach from screen 
ctrl+a+d

export SPANNER_EMULATOR_HOST=localhost:9010

Перенос MySQL из Magento в Spanner

Прежде чем приступить к интеграции Spanner, мы воспользуемся инструментом HarbourBridge для преобразования базы данных MySQL, созданной в рамках описанной выше установки Magento, в формат Spanner.

По своей сути, HarbourBridge предоставляет автоматизированный рабочий процесс для загрузки содержимого существующей базы данных MySQL или PostgreSQL в Spanner. Он не требует никакой настройки — не нужно писать манифесты или карты данных. Вместо этого он импортирует исходную базу данных, создает схему Spanner, создает новую базу данных Spanner, заполненную данными из исходной базы данных, и генерирует подробный отчет об оценке. HarbourBridge предназначен для загрузки баз данных размером до нескольких десятков гигабайт в целях оценки, а не для полномасштабной миграции.

HarbourBridge инициализирует миграцию на Spanner на начальном этапе, используя существующую базу данных MySQL или PostgreSQL, чтобы быстро запустить систему на Spanner. Он генерирует отчет об оценке с общей оценкой пригодности Spanner для миграции, анализом сопоставления типов для каждой таблицы и списком функций, используемых в исходной базе данных, которые не поддерживаются Spanner.

HarbourBridge можно использовать с эмулятором Spanner или напрямую с экземпляром Spanner.

В файле README HarbourBridge содержится пошаговое руководство по быстрому запуску инструмента с использованием экземпляра Spanner.

Установите HarbourBridge

Загрузите инструмент на свой компьютер и установите его. Для работы необходимо установить Golang. Установка всех необходимых модулей на новом компьютере без предварительно установленного Go может занять некоторое время.

# Install golang
cd ~
wget https://golang.org/dl/go1.17.2.linux-amd64.tar.gz
sudo tar -zxvf go1.17.2.linux-amd64.tar.gz -C /usr/local
rm go1.17.2.linux-amd64.tar.gz

echo 'export GOROOT=/usr/local/go' | sudo tee -a /etc/profile
echo 'export PATH=/usr/local/go/bin:$HOME/go/bin:$PATH' | sudo tee -a /etc/profile
source /etc/profile

# Install harbourbridge
git clone https://github.com/cloudspannerecosystem/harbourbridge
cd harbourbridge
go run github.com/cloudspannerecosystem/harbourbridge help

Перенесите данные

Для переноса базы данных Magento в Spanner используйте следующую команду:

mysqldump --user='root' --password=$ROOT_PASSWORD magento | go run github.com/cloudspannerecosystem/harbourbridge -driver=mysqldump -dbname=magento

Настройте инструмент spanner-cli

go install github.com/cloudspannerecosystem/spanner-cli@latest

3. Преобразуйте Magento для работы со Spanner.

Теперь, когда Magento запущен и создан экземпляр Spanner с перенесенной базой данных Magento, мы займемся модификацией Magento для работы с данными, хранящимися в Spanner.

Для преобразования установленной системы Magento будут выполнены следующие шаги:

  • Клонируйте проект magento-spanner-port
  • Измените соединение на Spanner.
  • Убедитесь, что данные каталога заполнены из Spanner.

Клонируйте форк проекта Magento.

Клонируйте код PHP-приложения для Magento, содержащий изменения для модулей «Каталог», «Список желаний» и «Корзина», по указанной ниже ссылке в Git .

cd ~
git clone https://github.com/searceinc/magento-spanner-port

Ваша домашняя директория должна выглядеть примерно так:

$ ls
go  harbourbridge  magento-spanner-port  magento2

Где magento2 — это кодовая база, которую мы будем модифицировать, используя код из magento-spanner-port .

Измените соединение на Spanner.

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

Пример реализации можно посмотреть по ссылке на Github : https://github.com/searceinc/magento-spanner-port .

  • Подключите PHP-библиотеку google/cloud-spanner.
  • Добавьте адаптер Spanner для создания соединения со Spanner.
  • Настройте экземпляр Spanner и информацию о сервере.
  • Добавьте SpannerInterface и Spanner в адаптер, чтобы реализовать подключение к Spanner.

Сначала нам нужно установить PHP-библиотеку cloud-spanner с помощью Composer. В каталоге Magento2 выполните следующую команду:

cd ~/magento2
composer require google/cloud-spanner

Затем мы добавляем файлы адаптера Spanner из репозитория magento-spanner-port в наш код Magento2 :

~/magento2$ cp -r ../magento-spanner-port/lib/internal/Magento/Framework/DB/Adapter/Spanner vendor/magento/framework/DB/Adapter/.
~/magento2$ ls -l vendor/magento/framework/DB/Adapter/Spanner
total 16
-rw-r--r-- 1 derekdowney derekdowney 10378 Nov  9 21:03 Spanner.php
-rw-r--r-- 1 derekdowney derekdowney  2948 Nov  9 21:03 SpannerInterface.php

Теперь измените файл DB/Adapter/Spanner/Spanner.php , чтобы ввести информацию о подключении к Spanner для переменных $project_id, $instance и $database :

$ nano vendor/magento/framework/DB/Adapter/Spanner/Spanner.php

class Spanner implements SpannerInterface
{
    /**
     * Google cloud project id
     * @var string
     */
    private $project_id = 'magento';

    /**
     * Google cloud instance name
     * @var string
     */
    private $instance  = 'magento-instance';

    /**
     * Cloud Spanner database name
     * @var string
     */
    private $database  = 'magento';

    /**
     * Is Cloud Spanner emulator
     * @var bool
     */
    private $is_emulator = true;
...
   /**
    * Set database connection adapter
    *
    * @param \Magento\Framework\DB\Adapter\AdapterInterface $conn
    * @return $this
    * @throws \Magento\Framework\Exception\LocalizedException
    */
   public function setConnection(\Magento\Framework\DB\Adapter\AdapterInterface $conn)
   {
       $this->_conn = $conn;
       $this->_select = $this->_conn->select();
       $this->_isOrdersRendered = false;
       return $this;
   }


   /**
     * Set Cloud Spanner database connection adapter
     *
     * @return void
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    private function setSpannerConnection()
    {
        $this->_spanner_conn = new Spanner();
    }

Измените класс AbstractDB в Magento, чтобы теперь он подключался к Spanner с помощью новой функции Connection в адаптере Spanner. Добавьте зеленые строки после белых строк в файле. См. vendor/magento/framework/Data/Collection/AbstractDb.php

$ nano vendor/magento/framework/Data/Collection/AbstractDb.php
...
use Psr\Log\LoggerInterface as Logger;
use Magento\Framework\DB\Adapter\Spanner\Spanner;
...
    protected $_conn;

    /**
     * Cloud Spanner connection
     *
     * @var \Magento\Framework\DB\Adapter\Spanner\SpannerAdapterInterface
     */
    protected $_spanner_conn;
...
       if ($connection !== null) {
            $this->setConnection($connection);
        }
        $this->setSpannerConnection();
        $this->_logger = $logger;
...
   /**
     * Retrieve connection object
     *
     * @return AdapterInterface
     */
    public function getConnection()
    {
        return $this->_conn;
    }

   /**
     * Retrieve connection object
     *
     * @return SpannerAdapterInterface
     */
    public function getSpannerConnection()
    {
        return $this->_spanner_conn;
    }
...

После установления соединения необходимо изменить метод получения данных из адаптера MySQL на адаптер Spanner. Измените метод _loadAttributes в AbstractCollection, чтобы он подключался к Spanner и получал данные из Spanner. Замените красную строку строками, выделенными зеленым.

См. файл /app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php

$ nano ./vendor/magento/module-eav/Model/Entity/Collection/AbstractCollection.php

use Magento\Framework\Exception\LocalizedException;
use Google\Cloud\Spanner\SpannerClient;

...
               try {
                    if (is_array($selects)) {
                        $select = implode(' UNION ALL ', $selects);
                    } else {
                        $select = $selects;
                    }
                   $values = $this->getConnection()->fetchAll($select);
                   $con = $this->getSpannerConnection();

                    /**
                     * Cloud Spanner follows strict type so cast the columns in common type
                     */
                    $select = $con->addCast($select, "`t_d`.`value`", 'string');
                    $select = $con->addCast($select, "`t_s`.`value`", 'string');
                    $select = $con->addCast($select, "IF(t_s.value_id IS NULL, t_d.value, t_s.value)", 'string');
                    
                    $values = $con->fetchAll($select);

...

Убедитесь, что данные каталога заполнены из Spanner.

Вот и всё! Теперь вы можете зайти в свою установку Magento в браузере и проверить, загружаются ли данные.

Например, вот описания часов в каталоге:

13b54ba4482408fc.png

Измените данные в Spanner через терминал для одного из продуктов и запросите подтверждение изменений в Spanner через терминал.

$ spanner-cli -pmagento -i magento-instance -d magento
spanner> SELECT * FROM catalog_product_entity_varchar WHERE value LIKE "Aim Analog%";
+----------+--------------+----------+-----------+--------------------+
| value_id | attribute_id | store_id | entity_id | value              |
+----------+--------------+----------+-----------+--------------------+
| 390      | 73           | 0        | 36        | Aim Analog Watch |
+----------+--------------+----------+-----------+--------------------+
1 rows in set (80.711542ms)

spanner> UPDATE catalog_product_entity_varchar SET value = "Aim Analog Spanner" WHERE value_id=390;
Query OK, 1 rows affected (0.19 sec)

spanner> SELECT * FROM catalog_product_entity_varchar WHERE value_id=390;
+----------+--------------+----------+-----------+--------------------+
| value_id | attribute_id | store_id | entity_id | value              |
+----------+--------------+----------+-----------+--------------------+
| 390      | 73           | 0        | 36        | Aim Analog Spanner |
+----------+--------------+----------+-----------+--------------------+
1 rows in set (80.711542ms)

Теперь обновите экран, чтобы убедиться, что название часов изменилось на "Aim Analog Spanner", как было обновлено через терминал Spanner.

63a9c7b065c7051f.png

4. Поздравляем!

Поздравляем, вы успешно подключили модуль «Каталог» Magento к Spanner! Это не полная интеграция, но теперь вы знаете, какие элементы необходимы для подключения PHP-приложения, такого как Magento, к экземпляру Spanner.

Уборка

После завершения настройки и проверки прототипа вы можете удалить ресурсы GCP, созданные в процессе. Это включает в себя виртуальную машину Compute Engine, а также экземпляр Cloud Spanner, если вы решили использовать его вместо эмулятора.

Что дальше?

Это всего лишь прототип модели для проверки концепции с помощью гаечного ключа.

Если вы хотите узнать больше о работе со Spanner и технологиях, которые мы использовали в этом практическом занятии, вот несколько дополнительных ресурсов: