Integrazione di Magento con Cloud Spanner

1. Introduzione

424db48d9db91638.png

Integrazione di Magento con un backend Cloud Spanner

Magento è una piattaforma di e-commerce open source basata su PHP molto apprezzata che archivia i dati in MySQL.

Questo codelab è una prova di concetto per utilizzare Cloud Spanner anziché MySQL per il modulo Catalog. È utile per chiunque voglia integrare, testare ed eseguire il deployment di Magento o di altre applicazioni PHP con Spanner.

Spanner è il database Google Cloud completamente gestito, di livello aziendale, distribuito e coerente che combina i vantaggi del modello di database relazionale con la scalabilità orizzontale non relazionale. È progettato per supportare distribuzioni di elaborazione delle transazioni online globali, la semantica SQL, la scalabilità orizzontale ad alta disponibilità e la coerenza transazionale. Spanner è in grado di gestire grandi volumi di dati. Non è limitato ad applicazioni di grandi dimensioni, ma consente la standardizzazione di un singolo motore del database per tutti i carichi di lavoro che richiedono RDBMS. Spanner offre tempi di inattività pari a zero per la manutenzione pianificata o gli errori di regione, con uno SLA (accordo sul livello del servizio) di disponibilità del 99,999%. Supporta applicazioni moderne offrendo disponibilità elevata e scalabilità.

Obiettivi didattici

  • Come installare Magento su GCE
  • Come configurare l'emulatore di Spanner
  • Come eseguire la migrazione di uno schema MySQL esistente a Spanner utilizzando HarbourBridge
  • Che cosa è necessario cambiare per integrare le applicazioni PHP come Magento che utilizzano MySQL per far funzionare il backend del database con Spanner

Cosa creerai

Questo codelab è incentrato sull'integrazione di Magento con Spanner. I blocchi di codice e le istruzioni di configurazione sono forniti per essere copiati e incollati, ma non sono descritti in dettaglio.

In questo codelab, inizierai a integrare Magento con Spanner. Imparerai a:

Che cosa ti serve

  • Un progetto Google Cloud collegato a un account di fatturazione.
  • La conoscenza della configurazione di PHP, Linux e Apache è un vantaggio.
  • L'esperienza Magento sarà utile, ma non obbligatoria.

2. Preparazione dell'istanza GCE in corso...

Crea l'istanza GCE

Crea un'istanza di Compute Engine nella piattaforma Google Cloud seguendo i passaggi indicati qui.

Quando crei l'istanza GCE, imposta il tipo di istanza su e2-standard-2 e le dimensioni del disco di avvio su 20 GB. Puoi lasciare tutte le impostazioni predefinite, ma assicurati di selezionare le opzioni "Consenti traffico HTTP" e "Consenti traffico HTTPS", poiché sfrutteremo l'interfaccia web di Magento.

Ne consegue un tipo di macchina e2-standard-2, che non è un'istanza con core condiviso e ha 2 vCPU, 8 GB di RAM e 20 GB di spazio su disco.

Il sistema operativo è Debian 10. La creazione dell'istanza può richiedere un paio di minuti.

Dopo averlo creato, accedi facendo clic su "SSH" nella console Cloud:

4bf915ef8d37c942.png

Si aprirà una nuova finestra del browser e ti sposterai in un terminale.

Installa il software necessario

Magento avrà bisogno di installare alcuni software prerequisiti prima di poter eseguire Magento. Nello specifico, installerai PHP, Elastic, MySQL e Apache come descritto di seguito.

  1. Installa alcuni pacchetti richiesti.
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. Installa i moduli PHP richiesti per 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. Installa Elasticsearch e avvia il servizio
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. Installa MySQL

Stai installando MySQL per installare lo schema Magento predefinito. Successivamente, eseguirai la migrazione dello schema a Spanner utilizzando HarbourBridge.

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

sudo dpkg -i mysql-apt-config*

Il comando dpkg riportato sopra visualizzerà un prompt interattivo per installare il server MySQL 5.7. Seleziona le opzioni:

  • Server e cluster 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. Installa Apache2
sudo apt -y install apache2

sudo a2enmod proxy_fcgi rewrite

Installa e configura Magento 2

Il progetto Magento Commerce Cloud include uno schema di database e servizi per accedere completamente al sito e al negozio Magento.

Il modo più semplice per installare e utilizzare questo componente è seguire le istruzioni di Magento per l'installazione utilizzando Composer:

  1. Installa Magento versione 2.4.2 utilizzando Composer. Magento 2 richiede la versione 1.x di Composer. Potresti visualizzare alcuni avvisi relativi al supporto di questa versione che verrà deprecata.
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
  1. Impostare le autorizzazioni per le cartelle
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. Configura l'host virtuale di Magento creando /etc/apache2/sites-available/magento.conf con i contenuti di seguito.
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. Crea i link simbolici e riavvia 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. Crea il database e l'utente per Magento in 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. Verifica l'area di lavoro locale Per verificare che l'ambiente locale ospiti il server, accedi allo store utilizzando l'URL di base trasmesso nel comando di installazione. Ad esempio, puoi accedere al negozio Magento locale utilizzando i seguenti formati di URL:
  • http://<GCEexternalIP>/
  • http://&lt;GCEexternalIP&gt;/&lt;adminuri&gt;

Il GCEexternalIP è disponibile nella console Cloud:

3947f1164e1d5409.png

Per modificare l'URI del pannello di amministrazione, utilizza questo comando per individuarlo:

php bin/magento info:adminuri
  1. Disattiva la cache completa della pagina Per scopi di sviluppo, puoi disattivare la cache completa della pagina di Magento 2. In questo modo potrai modificare i dati in Spanner e fare in modo che si riflettano sul sito web senza che ciò influisca sui valori memorizzati nella cache.
php bin/magento cache:disable full_page

Configura Spanner

Installa l'emulatore Spanner

Cloud SDK fornisce un emulatore in memoria locale che puoi utilizzare per sviluppare e testare le tue applicazioni senza costi senza creare un progetto Google Cloud o un account di fatturazione. Poiché l'emulatore memorizza i dati solo in memoria, tutto lo stato, inclusi dati, schema e configurazioni, viene perso al riavvio. L'emulatore offre le stesse API del servizio di produzione Spanner ed è destinato allo sviluppo e ai test locali, non ai deployment di produzione.

Usa il link di seguito per fare ulteriore riferimento per l'installazione, l'utilizzo e la distribuzione dell'emulatore:

Utilizzo dell'emulatore di 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

Esegui la migrazione di MySQL in Magento a Spanner

Prima di iniziare a integrare Spanner, utilizzeremo uno strumento chiamato HarbourBridge per convertire il database MySQL creato nell'ambito dell'installazione di Magento sopra in Spanner.

Di base, HarbourBridge fornisce un flusso di lavoro automatizzato per il caricamento dei contenuti di un database MySQL o PostgreSQL esistente in Spanner. Non richiede alcuna configurazione: nessun manifest o mappa di dati da scrivere. Importa invece il database di origine, crea uno schema Spanner, un nuovo database Spanner compilato con i dati del database di origine e genera un report di valutazione dettagliato. HarbourBridge è progettato per caricare database fino a qualche decina di GB a scopo di valutazione, non per migrazioni complete.

HarbourBridge esegue il bootstrap della migrazione in fase iniziale a Spanner utilizzando un database di origine MySQL o PostgreSQL esistente per consentirti di iniziare a utilizzare Spanner rapidamente. Genera un report di valutazione con un punteggio complessivo di idoneità alla migrazione per Spanner, un'analisi tabella per tabella delle mappature dei tipi e un elenco di funzionalità utilizzate nel database di origine non supportate da Spanner.

HarbourBridge può essere utilizzato con l'emulatore Spanner o direttamente con un'istanza Spanner.

Il file README di HarbourBridge contiene una guida rapida passo passo per l'utilizzo dello strumento con un'istanza Spanner.

Installa HarbourBridge

Scarica lo strumento sul tuo computer e installalo. Affinché questo comando funzioni, è necessario installare golang. L'installazione di tutti i moduli richiesti su un'istanza nuova senza che Go sia stato configurato in precedenza può richiedere un po' di tempo.

# 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

Esegui la migrazione dei dati

Utilizza il comando seguente per eseguire la migrazione del database Magento in Spanner:

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

Configura lo strumento Spanner-interfaccia a riga di comando

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

3. Converti Magento per farlo funzionare con Spanner

Ora che Magento è in esecuzione e l'istanza Spanner creata con il database Magento è stata migrata, lavoreremo per modificare Magento in modo che funzioni con i dati archiviati in Spanner.

Per convertire l'installazione di Magento, verranno eseguiti i seguenti passaggi:

  • Clona il progetto magento-spanner-port
  • Cambia la connessione a Spanner
  • Verifica che i dettagli del catalogo siano compilati da Spanner

Clona il fork del progetto Magento

Clona il codice dell'applicazione PHP per Magento, che contiene le modifiche per i moduli Catalog, Wishlist e Cart dall'URL Git indicato di seguito.

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

La tua home directory dovrebbe avere un aspetto simile al seguente:

$ ls
go  harbourbridge  magento-spanner-port  magento2

Dove magento2 è il codebase che modificheremo, utilizzando il codice di magento-spanner-port.

Cambia la connessione a Spanner

Per verificare se le modifiche al codice si riflettono nell'interfaccia utente, puoi seguire i passaggi riportati di seguito:

Fai riferimento al link GitHub https://github.com/searceinc/magento-spanner-port per un'implementazione di esempio.

  • Richiedi la libreria client PHP di google/cloud-spanner
  • Aggiungi l'adattatore Spanner per creare una connessione a Spanner.
  • Configura le informazioni sull'istanza e sul server Spanner.
  • Aggiungi SpannerInterface e Spanner nell'adattatore per implementare la connessione a Spanner.

Innanzitutto, dobbiamo installare la libreria PHP cloud-spanner utilizzando Composer. Nella directory magento2, esegui questo comando:

cd ~/magento2
composer require google/cloud-spanner

Aggiungiamo quindi i file dell'adattatore Spanner da magento-spanner-port al nostro codice di base 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

Ora modifica il file DB/Adapter/Spanner/Spanner.php per inserire le informazioni di connettività Spanner per $project_id, $instance e $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();
    }

Modifica la classe AbstractDB in Magento in modo che si connetta a Spanner utilizzando la funzione Connection appena creata all'interno di Spanner Adapter. Aggiungi le linee verdi dopo le linee bianche nel file. Fai riferimento a 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;
    }
...

Una volta stabilita la connessione, dobbiamo modificare il metodo di recupero dei dati dall'adattatore MySQL all'adattatore Spanner. Modifica il metodo _loadAttributes in AbstractCollection per connetterti a Spanner e recuperare i dati da Spanner. Sostituisci la linea rossa con le linee verdi.

Fai riferimento a /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);

...

Verifica che i dettagli del catalogo siano compilati da Spanner

È tutto. Ora puoi accedere all'installazione di Magento nel browser e verificare che i dati vengano caricati.

Ad esempio, queste sono le voci di catalogo per gli orologi:

13b54ba4482408fc.png

Modifica i dati di Spanner tramite il terminale per uno dei prodotti ed esegui query sui dati tramite il terminale per confermare la modifica in 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)

Ora ricarica lo schermo per verificare che il nome dello smartwatch sia ora impostato su "Aim Analog Spanner", come aggiornato tramite il terminale Spanner.

63a9c7b065c7051f.png

4. Complimenti

Congratulazioni, hai collegato correttamente il modulo Catalog di Magento per funzionare con Spanner. Non si tratta di un'integrazione completa, ma ora conosci gli elementi per connettere un'applicazione PHP come Magento a un'istanza Spanner.

Pulizia

Al termine della configurazione e della convalida del POC, ti consigliamo di eliminare le risorse Google Cloud create durante la procedura. Sono inclusi la macchina virtuale Compute Engine e un'istanza di Cloud Spanner, se decidi di utilizzarne una al posto dell'emulatore.

Passaggi successivi

Questo è solo un modello di prototipo per un POC di Spanner.

Se vuoi saperne di più sull'utilizzo di Spanner e delle tecnologie che abbiamo utilizzato in questo codelab, ecco alcune risorse aggiuntive: