Integracja Magento z Cloud Spanner

1. Wprowadzenie

424db48d9db91638.png

Integracja Magento z backendem Cloud Spanner

Magento to popularna platforma e-commerce typu open source oparta na PHP, która przechowuje dane w MySQL.

To ćwiczenie to dowód koncepcji wykorzystania Cloud Spanner zamiast MySQL w module katalogu. Jest to przydatne dla wszystkich osób zainteresowanych integracją, testowaniem i wdrażaniem Magento lub innych aplikacji PHP w usłudze Spanner.

Spanner to usługa w pełni zarządzana, klasy biznesowej, rozproszona i spójna baza danych Google Cloud, która łączy zalety relacyjnego modelu bazy danych z nierelacyjną skalowalnością poziomą. Została ona zaprojektowana z myślą o globalnych wdrożeniach przetwarzania transakcji online, semantyce SQL, wysoce dostępnym skalowaniu poziomym i spójności transakcyjnej. Spanner może obsługiwać duże ilości danych. Jego użycie nie ogranicza się do aplikacji o dużych rozmiarach, ale umożliwia standaryzację jednego silnika bazy danych dla wszystkich zadań wymagających RDBMS. Spanner zapewnia brak przestojów w przypadku planowanych prac konserwacyjnych lub awarii regionu, a gwarancja jakości usług w zakresie dostępności wynosi 99,999%. Obsługuje nowoczesne aplikacje, zapewniając wysoką dostępność i skalowalność.

Czego się nauczysz

  • Jak zainstalować Magento w GCE
  • Jak skonfigurować emulator Spanner
  • Migracja istniejącego schematu MySQL do Spannera za pomocą HarbourBridge
  • Co musisz zmienić, aby zintegrować aplikacje PHP, takie jak Magento, które używają MySQL jako backendu bazy danych, ze Spannerem

Co utworzysz

To ćwiczenie koncentruje się na integracji Magento z usługą Spanner. Bloki kodu i instrukcje konfiguracji można skopiować i wkleić, ale nie są one szczegółowo omawiane.

W tym ćwiczeniu z programowania rozpoczniesz integrację Magento z usługą Spanner. W ramach ćwiczenia:

Czego potrzebujesz

  • Projekt Google Cloud połączony z kontem rozliczeniowym.
  • Znajomość konfiguracji PHP, Linuxa i Apache jest dodatkowym atutem.
  • Znajomość platformy Magento będzie przydatna, ale nie jest wymagana.

2. Przygotowywanie instancji GCE

Tworzenie instancji GCE

Utwórz instancję Compute Engine w Google Cloud Platform, wykonując czynności opisane tutaj.

Podczas tworzenia instancji GCE zmień typ instancji na e2-standard-2, a rozmiar dysku rozruchowego na 20 GB. Możesz pozostawić wszystkie ustawienia domyślne, ale pamiętaj, aby wybrać opcje „Zezwalaj na ruch HTTP” i „Zezwalaj na ruch HTTPS”, ponieważ będziemy korzystać z interfejsu internetowego Magento.

W rezultacie otrzymasz typ maszyny e2-standard-2, który nie jest instancją ze współdzielonym rdzeniem i ma 2 procesory wirtualne, 8 GB pamięci RAM i 20 GB miejsca na dysku.

System operacyjny to Debian 10. Tworzenie instancji może potrwać minutę lub dwie.

Po utworzeniu instancji zaloguj się, klikając „SSH” w konsoli Cloud:

4bf915ef8d37c942.png

Spowoduje to otwarcie nowego okna przeglądarki i przejście do terminala.

Zainstaluj wymagane oprogramowanie

Aby można było uruchomić Magento, należy zainstalować pewne wymagane oprogramowanie. Zainstaluj PHP, Elastic, MySQL i Apache zgodnie z poniższymi instrukcjami.

  1. Zainstaluj wymagane pakiety.
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. Zainstaluj moduły PHP wymagane przez Magento.
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. Zainstaluj Elasticsearch i uruchom usługę.
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. Instalowanie MySQL

Instalujesz MySQL, aby zainstalować domyślny schemat Magento. Później przeniesiesz schemat do usługi Spanner za pomocą narzędzia HarbourBridge.

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

sudo dpkg -i mysql-apt-config*

Powyższe polecenie dpkg wyświetli interaktywny znak zachęty, w którym możesz zainstalować serwer MySQL 5.7. Wybierz opcje:

  • Serwer i klaster MySQL
  • mysql-5.7
  • OK

a018bfc2ee00bdf5.png 1a126e452ca7312e.png ae39c6f4bbe3be74.png

sudo apt update && sudo apt -y install mysql-server
# You will be prompted to enter a root password
  1. Instalowanie Apache2
sudo apt -y install apache2

sudo a2enmod proxy_fcgi rewrite

Instalowanie i konfigurowanie Magento2

Projekt Magento Commerce Cloud zawiera schemat bazy danych i usługi, które umożliwiają pełny dostęp do witryny i sklepu Magento.

Najprostszym sposobem zainstalowania i uruchomienia tego narzędzia jest wykonanie instrukcji Magento dotyczących instalacji za pomocą narzędzia Composer:

  1. Zainstaluj Magento w wersji 2.4.2 za pomocą narzędzia Composer. Magento 2 wymaga wersji 1.x narzędzia Composer. Możesz zobaczyć ostrzeżenia o wycofaniu obsługi tej wersji.
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
  1. Ustawianie uprawnień do folderów
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. Skonfiguruj wirtualny host Magento, tworząc plik /etc/apache2/sites-available/magento.conf z poniższą zawartością.
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. Utwórz linki symboliczne i ponownie uruchom 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. Utwórz bazę danych i użytkownika Magento w 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. Weryfikacja lokalnego obszaru roboczego Aby sprawdzić, czy serwer jest hostowany w środowisku lokalnym, otwórz sklep za pomocą podstawowego adresu URL przekazanego w poleceniu instalacji. W tym przykładzie możesz uzyskać dostęp do lokalnego sklepu Magento, używając adresów URL w tych formatach:
  • http://<GCEexternalIP>/
  • http://<GCEexternalIP>/<adminuri>

Wartość GCEexternalIP znajdziesz w konsoli Cloud:

3947f1164e1d5409.png

Aby zmienić identyfikator URI panelu administracyjnego, użyj tego polecenia, aby go znaleźć:

php bin/magento info:adminuri
  1. Wyłącz pamięć podręczną całej strony Na potrzeby programowania możesz wyłączyć pamięć podręczną całej strony Magento2. Dzięki temu możesz modyfikować dane w Spannerze, a zmiany będą widoczne w witrynie bez wpływu wartości zapisanych w pamięci podręcznej.
php bin/magento cache:disable full_page

Konfigurowanie usługi Spanner

Instalowanie emulatora Spanner

Pakiet Cloud SDK udostępnia lokalny emulator w pamięci, którego możesz używać do bezpłatnego tworzenia i testowania aplikacji bez tworzenia projektu GCP ani konta rozliczeniowego. Emulator przechowuje dane tylko w pamięci, więc po ponownym uruchomieniu wszystkie stany, w tym dane, schematy i konfiguracje, zostaną utracone. Emulator udostępnia te same interfejsy API co usługa produkcyjna Spanner i jest przeznaczony do lokalnego programowania i testowania, a nie do wdrożeń produkcyjnych.

Aby dowiedzieć się więcej o instalowaniu, używaniu i wdrażaniu emulatora, kliknij link poniżej:

Korzystanie z emulatora 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

Migracja Magento MySQL do Spannera

Zanim przejdziemy do integracji Spannera, użyjemy narzędzia HarbourBridge, aby przekonwertować bazę danych MySQL utworzoną w ramach instalacji Magento na Spannera.

HarbourBridge zapewnia automatyczny przepływ pracy, który umożliwia wczytywanie zawartości istniejącej bazy danych MySQL lub PostgreSQL do Spannera. Nie wymaga konfiguracji – nie musisz pisać manifestów ani map danych. Zamiast tego importuje bazę danych źródłową, tworzy schemat Spanner, tworzy nową bazę danych Spanner wypełnioną danymi z bazy danych źródłowej i generuje szczegółowy raport oceny. HarbourBridge służy do wczytywania baz danych o rozmiarze do kilkudziesięciu gigabajtów na potrzeby oceny, a nie do migracji na pełną skalę.

HarbourBridge przyspiesza migrację do Spannera na wczesnym etapie, korzystając z istniejącej źródłowej bazy danych MySQL lub PostgreSQL, aby szybko rozpocząć pracę w Spannerze. Generuje on raport oceny z ogólną oceną przydatności do migracji do Spannera, analizą mapowań typów w poszczególnych tabelach oraz listą funkcji używanych w bazie danych źródłowych, które nie są obsługiwane przez Spannera.

Narzędzie HarbourBridge można używać z emulatorem Spanner lub bezpośrednio z instancją Spanner.

W pliku README narzędzia HarbourBridge znajdziesz szczegółowy przewodnik dla początkujących dotyczący korzystania z tego narzędzia w przypadku instancji Spanner.

Instalowanie HarbourBridge

Pobierz narzędzie na komputer i zainstaluj je. Aby to działało, musisz zainstalować golang. Zainstalowanie wszystkich wymaganych modułów na nowej instancji, na której nie skonfigurowano wcześniej Go, może zająć trochę czasu.

# 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

Migracja danych

Aby przenieść bazę danych Magento do Spannera, użyj tego polecenia:

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

Konfigurowanie narzędzia spanner-cli

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

3. Konwertowanie Magento do pracy z usługą Spanner

Magento jest już uruchomione, a instancja Spannera została utworzona i zawiera przeniesioną bazę danych Magento. Teraz zmodyfikujemy Magento, aby działało z danymi przechowywanymi w Spannerze.

Aby przekonwertować instalację Magento, wykonaj te czynności:

  • Sklonuj projekt magento-spanner-port.
  • Zmień połączenie ze Spannerem
  • Sprawdź, czy szczegóły katalogu są wypełnione danymi z usługi Spanner.

Sklonuj rozwidlenie projektu Magento.

Sklonuj kod aplikacji PHP dla Magento, który zawiera modyfikacje modułów Katalog, Lista życzeń i Koszyk, z podanego poniżej adresu URL Git.

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

Katalog główny powinien wyglądać mniej więcej tak:

$ ls
go  harbourbridge  magento-spanner-port  magento2

gdzie magento2 to baza kodu, którą będziemy modyfikować, używając kodu z magento-spanner-port.

Zmień połączenie ze Spannerem

Aby sprawdzić, czy modyfikacje kodu są widoczne w interfejsie, wykonaj te czynności:

Przykładową implementację znajdziesz pod tym linkiem do GitHuba: https://github.com/searceinc/magento-spanner-port.

  • Wymagaj biblioteki klienta PHP google/cloud-spanner
  • Dodaj adapter Spannera, aby utworzyć połączenie z usługą Spanner.
  • Skonfiguruj instancję Spanner i informacje o serwerze.
  • Dodaj SpannerInterface i Spanner w Adapterze, aby zaimplementować połączenie z Spannerem.

Najpierw musimy zainstalować bibliotekę PHP cloud-spanner za pomocą narzędzia Composer. W katalogu magento2 uruchom to polecenie:

cd ~/magento2
composer require google/cloud-spanner

Następnie dodajemy pliki adaptera Spanner z repozytorium magento-spanner-port do bazy kodu 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

Teraz zmodyfikuj plik DB/Adapter/Spanner/Spanner.php, aby wprowadzić informacje o połączeniu ze Spannerem w przypadku zmiennych $project_id, $instance i $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();
    }

Zmodyfikuj klasę AbstractDB w Magento, aby łączyła się z Spannerem za pomocą nowo utworzonej funkcji Connection w Spanner Adapter. Dodaj zielone linie po białych liniach w pliku. Zapoznaj się z plikami 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;
    }
...

Po nawiązaniu połączenia musimy zmienić metodę pobierania danych z adaptera MySQL na adapter Spanner . Zmodyfikuj metodę _loadAttributes w klasie AbstractCollection, aby połączyć się z usługą Spanner i pobrać z niej dane. Zastąp czerwoną linię zielonymi.

Zobacz /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);

...

Sprawdź, czy szczegóły katalogu są wypełnione danymi z usługi Spanner.

To wszystko. Teraz możesz otworzyć instalację Magento w przeglądarce i sprawdzić, czy dane się wczytują.

Oto na przykład wpisy w katalogu dotyczące zegarków:

13b54ba4482408fc.png

Zmodyfikuj dane Spanner za pomocą terminala dla jednego z produktów i wyślij zapytanie o dane za pomocą terminala, aby potwierdzić modyfikację w 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)

Teraz ponownie załaduj ekran, aby potwierdzić, że nazwa zegarka została zmieniona na „Aim Analog Spanner” zgodnie z aktualizacją wprowadzoną w terminalu Spanner.

63a9c7b065c7051f.png

4. Gratulacje

Gratulacje, udało Ci się połączyć moduł katalogu Magento z Spannerem. Nie jest to pełna integracja, ale znasz już elementy, które pozwolą Ci połączyć aplikację PHP, taką jak Magento, z instancją Spanner.

Czyszczę dane

Po zakończeniu konfiguracji i weryfikacji testu możesz usunąć zasoby GCP utworzone w tym procesie. Obejmuje to maszynę wirtualną Compute Engine, a także instancję Cloud Spanner, jeśli zdecydujesz się jej użyć zamiast emulatora.

Co dalej?

To tylko model prototypowy na potrzeby testu koncepcyjnego Spannera.

Jeśli chcesz dowiedzieć się więcej o Spannerze i technologiach, których użyliśmy w tym ćwiczeniu, zapoznaj się z tymi dodatkowymi materiałami: