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 w Codelabs stanowi model koncepcyjny umożliwiający wykorzystanie w module katalogu Cloud Spanner, a nie MySQL. 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 Google Cloud przeznaczona dla firm, która łączy zalety modelu relacyjnej bazy danych z bezrelacyjną skalowalnością poziomą. 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. Spanner jest w stanie obsłużyć 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 brak przestojów w przypadku planowanej konserwacji lub awarii regionu z gwarancją dostępności na poziomie 99, 999%. Obsługuje nowoczesne aplikacje dzięki wysokiej dostępności i skalowalności.

Czego się nauczysz

  • Instalowanie Magento w GCE
  • Jak skonfigurować emulator Spannera
  • Jak przenieść istniejący schemat MySQL do Spannera za pomocą HarbourBridge
  • 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.
  • Dodatkową zaletą jest znajomość języków PHP, Linux i Apache.
  • Znajomość Magento pomoże, ale nie jest wymagana.

2. Przygotowuję instancję 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ć wszystko domyślne, ale wybierz „Zezwalaj na ruch HTTP” i „Zezwalaj na ruch HTTPs”, 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.

Po utworzeniu połączenia zaloguj się, klikając „SSH” W konsoli Cloud:

4bf915ef8d37c942.png

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

Zainstaluj oprogramowanie wstępne

Zanim system Magento zostanie uruchomiony, należy zainstalować odpowiednie oprogramowanie wstępne. 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 przeniesiesz schemat do usługi Spanner za pomocą 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 spowoduje wyświetlenie interaktywnego promptu dotyczącego instalacji serwera MySQL 5.7. Wybierz opcje:

  • Serwer MySQL Klaster
  • 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 na zainstalowanie i uruchomienie tego narzędzia jest wykonanie instrukcji instalacji Magento 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. Możesz zobaczyć 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. Tworzenie bazy 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. 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 dostęp do lokalnego sklepu Magento można uzyskać, używając adresu URL w tych formatach:
  • http://&lt;GCEexternalIP&gt;/
  • http://&lt;GCEexternalIP&gt;/&lt;adminuri&gt;

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 będzie można modyfikować dane w usłudze Spanner i wyświetlać je w witrynie bez wpływu na wartości przechowywane w pamięci podręcznej.
php bin/magento cache:disable full_page

Skonfiguruj usługę Spanner

Instalowanie emulatora Spannera

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, podczas ponownego uruchamiania tracony jest cały stan, w tym dane, schemat i konfiguracje. Emulator oferuje te same interfejsy API co usługa produkcyjna Spannera. Jest przeznaczony do lokalnego programowania i testowania, a nie do wdrożeń produkcyjnych.

Skorzystaj z poniższego linku, aby dowiedzieć się więcej o instalacji, używaniu i wdrażaniu emulatora:

Używanie emulatora Spannera

# 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.

HarbourBridge zapewnia zautomatyzowany przepływ pracy wczytywania zawartości istniejącej bazy danych MySQL lub PostgreSQL do Spannera. Nie wymaga konfiguracji – nie można zapisywać plików manifestu ani map danych. Zamiast tego importuje źródłową bazę danych, tworzy schemat Spannera, tworzy nową bazę danych Spannera wypełnioną danymi ze źródłowej bazy danych i generuje szczegółowy raport z oceny. HarbourBridge jest przeznaczony do ładowania baz danych o rozmiarze do kilkudziesiąt GB w celu oceny, a nie do migracji na pełną skalę.

HarbourBridge uruchamia migrację na wczesnym etapie do Spannera z użyciem istniejącej źródłowej bazy danych MySQL lub PostgreSQL, aby szybko zacząć korzystać z usługi Spanner. Generuje raport oceny zawierający ogólny wynik migracji usługi Spanner, analizę mapowania typów w tabeli po kolei oraz listę funkcji używanych w źródłowej bazie danych, które nie są obsługiwane przez usługę Spanner.

Platformy HarbourBridge można używać z emulatorem Spannera lub bezpośrednio z instancją Spannera.

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

Zainstaluj 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. Konwersja Magento do współpracy ze Spannerem

Po uruchomieniu Magento i utworzonej instancji Spannera z użyciem bazy danych Magento możemy wprowadzić zmiany w Magento, aby obsługiwać dane przechowywane w usłudze Spanner.

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

  • Klonowanie projektu magento-spanner-port
  • Zmień połączenie na usługę Spanner
  • Sprawdź, czy szczegóły katalogu pochodzą ze Spannera

Sklonowanie rozwidlenia 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 oznacza bazę kodu, którą będziemy modyfikować za pomocą kodu z magento-spanner-port.

Zmień połączenie na usługę Spanner

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

Skorzystaj z linku GitHub https://github.com/searceinc/magento-spanner-port, aby zobaczyć przykładową implementację.

  • Wymagaj biblioteki klienta PHP na google/cloud-spanner
  • Dodaj adapter Spannera do tworzenia połączenia z usługą Spanner.
  • Skonfiguruj informacje o instancji i serwerze Spannera.
  • Dodaj do adaptera usługi SpannerInterface i Spanner, aby wdrożyć połączenie z usługą Spanner.

Najpierw musimy zainstalować bibliotekę PHP Cloud Spanner, używając narzędzia composer. W katalogu magento2 uruchom to polecenie:

cd ~/magento2
composer require google/cloud-spanner

Następnie do bazy kodu magento2 dodajemy pliki usługi Spanner Adapter z portu magento-spanner-port:

~/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 aby 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 umożliwić połączenie z usługą Spanner za pomocą nowo utworzonej funkcji połączenia w usłudze Spanner Adapter. 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 zmienić metodę pobierania danych z adaptera MySQL na adapter Spannera . Zmodyfikuj metodę _loadAttributes w AbstractCollection, aby połączyć się z usługą Spanner i pobrać dane z tej usługi. Zastąp czerwoną linię liniami na zielono.

Więcej informacji znajdziesz na stronie /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 w katalogu dla zegarków:

13b54ba4482408fc.png

Zmodyfikuj dane usługi Spanner przez terminal jednej z usług i wyślij do nich zapytanie, 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)

Teraz załaduj ponownie ekran, aby sprawdzić, czy nazwa zegarka zmieniła się na „Aim Analog Spanner” zaktualizowany za pomocą terminala Spannera.

63a9c7b065c7051f.png

4. Gratulacje

Gratulacje! Udało Ci się połączyć moduł katalogu Magento 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.

Czyszczenie

Po zakończeniu konfigurowania i weryfikacji POC możesz usunąć zasoby GCP utworzone podczas tego procesu. Jeśli zdecydujesz się użyć maszyny wirtualnej Compute Engine, a nie emulatora, będzie to obejmować zarówno maszynę wirtualną Compute Engine, jak i instancję Cloud Spanner.

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óre wykorzystaliśmy w ramach tego ćwiczenia z programowania, skorzystaj z tych dodatkowych materiałów: