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 laboratorium programistyczne to dowód koncepcji wykorzystania usługi Cloud Spanner zamiast MySQL w module katalogu. Jest to przydatne dla wszystkich zainteresowanych integracją, testowaniem i wdrażaniem Magento lub innych aplikacji w języku PHP za pomocą Spannera.

Spanner to w pełni zarządzana, rozproszona i spójna baza danych klasy korporacyjnej w Google Cloud, która łączy zalety modelu relacyjnej bazy danych z możliwościami skalowania poziomego nierelacyjnego. Opracowano go z myślą o obsłudze globalnych wdrożeń przetwarzania transakcji online, semantyki SQL, wysokiej dostępności skalowania w poziomie oraz spójności transakcji. Usługa Spanner może obsługiwać duże ilości danych. Można go używać nie tylko do aplikacji o dużych rozmiarach, ale umożliwia standaryzację jednego silnika bazy danych dla wszystkich zadań wymagających RDBMS. Spanner zapewnia zerową liczbę przestojów w przypadku planowanych konserwacji lub awarii w regionie. Gwarancja jakości usług w zakresie dostępności wynosi 99,999%. Obsługuje nowoczesne aplikacje dzięki wysokiej dostępności i skalowalności.

Czego się nauczysz

  • Jak zainstalować Magento w GCE
  • Konfigurowanie emulatora Spanner
  • Jak za pomocą HarbourBridge przenieść istniejący schemat MySQL do Spannera
  • Co należy zmienić, aby zintegrować aplikacje PHP (np. Magento), które korzystają z MySQL na potrzeby backendu bazy danych i współpracują z usługą Spanner

Co utworzysz

Ćwiczenie w Codelabs koncentruje się na integracji Magento z usługą Spanner. Podane bloki kodu oraz instrukcje konfiguracji umożliwiają kopiowanie i wklejanie, ale nie są one szczegółowo omawiane.

W ramach tego ćwiczenia w Codelabs zaczniesz integrować Magento z usługą Spanner. W ramach ćwiczenia:

Czego potrzebujesz

  • projekt Google Cloud połączony z kontem rozliczeniowym.
  • Znajomość PHP, systemu Linux i konfiguracji Apache jest mile widziana.
  • Znajomość Magento pomoże, 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 i rozmiar dysku rozruchowego na 20 GB. Możesz pozostawić wszystkie ustawienia domyślne, ale koniecznie wybierz „Zezwalaj na ruch HTTP” i „Zezwalaj na ruch HTTP”, ponieważ będziemy korzystać z interfejsu internetowego Magento.

W efekcie powstaje maszyna typu e2-standard-2, która nie jest instancją ze współużytkowanym rdzeniem i ma 2 procesory wirtualne, 8 GB pamięci RAM oraz 20 GB miejsca na dysku.

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

Gdy zostanie utworzony, zaloguj się, klikając „SSH” w konsoli Google Cloud:

4bf915ef8d37c942.png

Spowoduje to otwarcie nowego okna przeglądarki i umieszczenie Cię w terminalu.

Zainstaluj oprogramowanie wstępne

Aby uruchomić Magento, musisz najpierw zainstalować wymagane oprogramowanie. Przede wszystkim zainstalujesz PHP, Elastic, MySQL i Apache w sposób opisany poniżej.

  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. Instalowanie Elasticsearch i uruchamianie usługi
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 użyjesz narzędzia HarbourBridge do przeniesienia schematu do usługi Spanner.

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 spowoduje wyświetlenie interaktywnego promptu dotyczącego instalacji serwera 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. Zainstaluj Apache2
sudo apt -y install apache2

sudo a2enmod proxy_fcgi rewrite

Instalowanie i konfigurowanie Magento2

Projekt Magento Commerce Cloud obejmuje schemat bazy danych i usługi zapewniające pełny dostęp do strony i sklepu Magento.

Najprostszym sposobem zainstalowania i uruchomienia tej wersji jest wykonanie instrukcji instalacji za pomocą narzędzia composer:

  1. Zainstaluj Magento w wersji 2.4.2 za pomocą narzędzia composer. Magento 2 wymaga wersji composer 1.x. Mogą się wyświetlać ostrzeżenia o wycofaniu 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 hosta wirtualnego Magento, tworząc plik /etc/apache2/sites-available/magento.conf z poniższą treś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 dowiązania 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 dla 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. Sprawdź lokalny obszar roboczy. Aby sprawdzić, czy środowisko lokalne hostuje serwer, uzyskaj dostęp do sklepu za pomocą podstawowego adresu URL przekazanego w poleceniu instalacji. W tym przykładzie możesz uzyskać dostęp do lokalnego sklepu Magento za pomocą tych formatów adresów URL:
  • http://&lt;GCEexternalIP&gt;/
  • http://<GCEexternalIP>/<adminuri>

Adres GCEexternalIP znajdziesz w konsoli Cloud:

3947f1164e1d5409.png

Aby zmienić identyfikator URI panelu administracyjnego, znajdź go przy użyciu tego polecenia:

php bin/magento info:adminuri
  1. Wyłącz pełną pamięć podręczną strony Na potrzeby programowania możesz wyłączyć pełną pamięć podręczną strony Magento2. Dzięki temu możesz modyfikować dane w Spannerze i odzwierciedlać je w witrynie bez wpływu wartości z pamięci podręcznej.
php bin/magento cache:disable full_page

Skonfiguruj usługę Spanner

Instalowanie emulatora Spanner

Pakiet SDK Cloud udostępnia lokalny emulator pamięci, którego możesz używać do bezpłatnego tworzenia i testowania aplikacji bez konieczności tworzenia projektu GCP czy konta rozliczeniowego. Ponieważ emulator przechowuje dane tylko w pamięci, po restarcie traci wszystkie stany, w tym dane, schemat i konfiguracje. Emulator oferuje te same interfejsy API co usługa produkcyjna Spannera. Jest on przeznaczony do lokalnego programowania i testowania, a nie do wdrożeń produkcyjnych.

Aby uzyskać więcej informacji o instalowaniu, używaniu i wdrażaniu emulatora, kliknij ten link:

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 MySQL z Magento do Spannera

Zanim przejdziemy do integracji usługi Spanner, użyjemy narzędzia o nazwie HarbourBridge, aby przekonwertować bazę danych MySQL utworzoną w ramach powyższej instalacji Magento do przekonwertowania na Spannera.

W podstawie HarbourBridge zapewnia zautomatyzowany przepływ pracy umożliwiający załadowanie zawartości dotychczasowej bazy danych MySQL lub PostgreSQL do usługi Spanner. Nie wymaga konfiguracji – nie można zapisywać plików manifestu ani map danych. Zamiast tego importuje bazę danych źródłową, tworzy schemat usługi Spanner, tworzy nową bazę danych usługi Spanner wypełnioną danymi z bazy danych źródłowej i generuje szczegółowy raport oceny. HarbourBridge jest przeznaczony do ładowania baz danych o rozmiarze do kilkudziesiąt GB na potrzeby oceny, a nie do migracji na pełną skalę.

HarbourBridge inicjuje wstępną migrację do usługi Spanner za pomocą istniejącej bazy danych źródłowej MySQL lub PostgreSQL, aby umożliwić Ci szybkie uruchomienie usługi Spanner. Generuje raport oceny z ogólnym wynikiem dopasowania do migracji w Spanner, analizą mapowania typów w poszczególnych tabelach oraz listą funkcji używanych w źródłowej bazie danych, które nie są obsługiwane przez Spanner.

HarbourBridge można używać z emulatorem usługi Spanner lub bezpośrednio z instancją usługi Spanner.

Plik HarbourBridge README zawiera szczegółowy krótki przewodnik dotyczący używania tego narzędzia z instancją Spannera.

Instalowanie HarbourBridge

Pobierz narzędzie na swój komputer i zainstaluj je. Aby to zadziałało, należy zainstalować golang. Instalacja wszystkich wymaganych modułów w nowej instancji bez uprzedniego skonfigurowania Go może trochę potrwać.

# 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

Użyj tego polecenia, aby przenieść bazę danych Magento do Spannera:

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 na wersję współpracującą z usługą Spanner

Teraz, gdy Magento działa, a instancja Spannera została utworzona z przeniesioną bazą danych Magento, zaczniemy modyfikować 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 na usługę Spanner
  • Sprawdź, czy szczegóły katalogu pochodzą ze Spannera

Sklonuj fork projektu Magento.

Skopiuj kod aplikacji PHP dla Magento, który zawiera modyfikacje modułów Catalog, Wishlist i Cart ze znajdującego się poniżej adresu URL Git.

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

Twój 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.

Zmiana połączenia z usługą Spanner

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

Przykładową implementację znajdziesz na stronie https://github.com/searceinc/magento-spanner-port.

  • Wymagaj biblioteki klienta google/cloud-spanner w PHP
  • Dodaj adapter Spannera do tworzenia połączenia z usługą Spanner.
  • Skonfiguruj informacje o instancji i serwerze Spannera.
  • Aby zaimplementować połączenie z usługą Spanner, dodaj interfejs SpannerInterface i klasę Spanner w pliku Adapter.

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

cd ~/magento2
composer require google/cloud-spanner

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

Zmodyfikuj plik DB/Adapter/Spanner/Spanner.php tak, by zawierał informacje o połączeniach Spannera z projektami $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 teraz łączyć się z usługą Spanner za pomocą nowo utworzonej funkcji połączenia w adapterze Spanner. Dodaj zielone linie po białymi liniach w pliku. Więcej informacji znajdziesz na stronie 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 zmodyfikować 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ę liniami na zielono.

Zapoznaj się z plikiem /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 pochodzą ze Spannera

Znakomicie. Teraz możesz przejść do instalacji Magento w przeglądarce i sprawdzić, czy dane się ładują.

Oto przykłady wpisów w katalogu dotyczących zegarków:

13b54ba4482408fc.png

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

Załaduj ponownie ekran, aby sprawdzić, czy nazwa zegarka została zmieniona w terminalu Spannera na „Aim Analog Spanner”.

63a9c7b065c7051f.png

4. Gratulacje

Gratulacje! Moduł katalogu Magento został połączony z usługą Spanner. Nie jest to pełna integracja, ale znasz już elementy umożliwiające połączenie aplikacji PHP, takiej jak Magento, z instancją Spannera.

Czyszczę dane

Po zakończeniu konfigurowania i weryfikacji POC możesz usunąć zasoby GCP utworzone podczas tego procesu. Obejmuje to maszynę wirtualną Compute Engine oraz instancję Cloud Spanner, jeśli zamiast emulatora zdecydujesz się użyć tej usługi.

Co dalej?

To jest tylko prototypowy model osoby kontaktowej w usłudze Spanner.

Jeśli chcesz dowiedzieć się więcej o pracy ze Spannerem i technologiami, których używamy w ramach tego ćwiczenia z programowania, skorzystaj z tych dodatkowych materiałów: