Intégrer Magento à Cloud Spanner

1. Introduction

424db48d9db91638.png

Intégrer Magento à un backend Cloud Spanner

Magento est une plate-forme d'e-commerce Open Source basée sur PHP, très populaire, qui stocke les données dans MySQL.

Cet atelier de programmation est une preuve de concept visant à utiliser Cloud Spanner au lieu de MySQL pour le module de catalogue. Cette ressource est utile pour toute personne souhaitant intégrer, tester et déployer Magento ou d'autres applications PHP avec Spanner.

Spanner est la base de données entièrement gérée, pensée pour les entreprises, distribuée et cohérente de Google Cloud, qui associe les avantages du modèle de base de données relationnelle à une évolutivité horizontale non relationnelle. Il est conçu pour prendre en charge les déploiements de traitement des transactions en ligne à l'échelle mondiale, la sémantique SQL, le scaling horizontal à disponibilité élevée et la cohérence transactionnelle. Spanner est capable de gérer de grands volumes de données. Son utilisation n'est pas limitée aux applications de grande taille, mais elle permet de standardiser un seul moteur de base de données pour toutes les charges de travail nécessitant un SGBDR. Spanner fait disparaître les temps d'arrêt pour les opérations de maintenance planifiées ou les défaillances de région, il est associé à un contrat de niveau de service garantissant une disponibilité de 99,999 %. Il est parfaitement adapté aux applications modernes, car il offre à la fois haute disponibilité et évolutivité optimale.

Points abordés

  • Installer Magento sur GCE
  • Configurer l'émulateur Spanner
  • Migrer un schéma MySQL existant vers Spanner à l'aide de HarbourBridge
  • Ce que vous devez modifier pour que les applications PHP comme Magento, qui utilisent MySQL pour le backend de la base de données, fonctionnent avec Spanner

Ce que vous allez faire

Cet atelier de programmation est consacré à l'intégration de Magento à Spanner. Des blocs de code et des instructions de configuration vous sont fournis pour que vous puissiez les copier et les coller, mais ils ne sont pas abordés en détail.

Dans cet atelier de programmation, vous allez commencer à intégrer Magento à Spanner. Vous découvrirez comment :

  • Configurer une instance GCE avec Magento installé
  • Installez l'émulateur Spanner .
  • Installer l'outil HarbourBridge pour migrer des données de MySQL vers Spanner
  • Modifier les collections Magento pour charger le catalogue de produits depuis Spanner

Prérequis

  • Projet Google Cloud associé à un compte de facturation.
  • Une connaissance de la configuration de PHP, Linux et Apache est un plus.
  • Une expérience avec Magento est utile, mais pas obligatoire.

2. Préparer l'instance GCE

Créer l'instance GCE

Créez une instance Compute Engine dans Google Cloud Platform en suivant les étapes décrites ici.

Lorsque vous créez l'instance GCE, définissez le type d'instance sur e2-standard-2 et la taille du disque de démarrage sur 20 Go. Vous pouvez laisser tous les paramètres par défaut, mais veillez à sélectionner "Autoriser le trafic HTTP" et "Autoriser le trafic HTTPS", car nous allons utiliser l'interface Web de Magento.

Cela donne un type de machine e2-standard-2, qui n'est pas une instance à cœur partagé et qui dispose de deux processeurs virtuels, de 8 Go de RAM et de 20 Go d'espace disque.

Le système d'exploitation est Debian 10. La création d'une instance peut prendre une ou deux minutes.

Une fois l'instance créée, connectez-vous en cliquant sur "SSH" dans la console Cloud :

4bf915ef8d37c942.png

Une nouvelle fenêtre de navigateur s'ouvre et vous êtes redirigé vers un terminal.

Installer les logiciels prérequis

Magento nécessite l'installation de certains logiciels prérequis avant de pouvoir être exécuté. Plus précisément, vous allez installer PHP, Elastic, MySQL et Apache, comme indiqué ci-dessous.

  1. Installez certains packages requis.
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. Installez les modules PHP requis pour 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. Installer Elasticsearch et démarrer le service
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. Installer MySQL

Vous installez MySQL pour installer le schéma Magento par défaut. Vous migrerez ensuite le schéma vers Spanner à l'aide de HarbourBridge.

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

sudo dpkg -i mysql-apt-config*

La commande dpkg ci-dessus affichera une invite interactive pour installer le serveur MySQL 5.7. Sélectionnez les options :

  • Serveur et 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. Installer Apache2
sudo apt -y install apache2

sudo a2enmod proxy_fcgi rewrite

Installer et configurer Magento2

Le projet Magento Commerce Cloud inclut un schéma de base de données et des services permettant d'accéder entièrement au site et à la boutique Magento.

Le moyen le plus simple d'installer et d'exécuter cette fonctionnalité est de suivre les instructions Magento pour l'installer à l'aide de Composer :

  1. Installez Magento version 2.4.2 à l'aide de Composer. Magento 2 nécessite la version 1.x de Composer. Des avertissements peuvent s'afficher concernant l'arrêt de l'assistance pour cette version.
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
  1. Définir des autorisations pour les dossiers
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. Configurez l'hôte virtuel Magento en créant /etc/apache2/sites-available/magento.conf avec le contenu ci-dessous.
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. Créez les liens symboliques et redémarrez 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. Créer la base de données et l'utilisateur pour Magento dans 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. Vérifiez votre espace de travail local. Pour vérifier que l'environnement local héberge le serveur, accédez au magasin à l'aide de l'URL de base que vous avez transmise dans la commande d'installation. Dans cet exemple, vous pouvez accéder à la boutique Magento locale en utilisant les formats d'URL suivants :
  • http://<GCEexternalIP>/
  • http://<GCEexternalIP>/<adminuri>

Vous trouverez l'adresse GCEexternalIP dans la console Cloud :

3947f1164e1d5409.png

Pour modifier l'URI du panneau d'administration, utilisez la commande suivante pour le localiser :

php bin/magento info:adminuri
  1. Désactiver le cache de page entière Pour les besoins du développement, vous pouvez désactiver le cache de page entière de Magento2. Cela vous permettra de modifier les données dans Spanner et de les voir reflétées sur le site Web sans être affecté par les valeurs mises en cache.
php bin/magento cache:disable full_page

Configurer Spanner

Installer l'émulateur Spanner

Le SDK Cloud fournit un émulateur local en mémoire, que vous pouvez utiliser pour développer et tester vos applications sans frais sans avoir à créer de projet GCP ni de compte de facturation. Étant donné que l'émulateur stocke les données uniquement en mémoire, tous les états, y compris les données, le schéma et les configurations, sont perdus au redémarrage. L'émulateur propose les mêmes API que le service de production Spanner. Il est destiné au développement et aux tests locaux, et non aux déploiements en production.

Veuillez utiliser le lien ci-dessous pour en savoir plus sur l'installation, l'utilisation et le déploiement de l'émulateur :

Utiliser l'émulateur 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

Migrer Magento MySQL vers Spanner

Avant de nous lancer dans l'intégration de Spanner, nous allons utiliser un outil appelé HarbourBridge pour convertir la base de données MySQL créée lors de l'installation de Magento en base de données Spanner.

HarbourBridge fournit un workflow automatisé permettant de charger le contenu d'une base de données MySQL ou PostgreSQL existante dans Spanner. Aucune configuration n'est requise : vous n'avez pas besoin d'écrire de fichiers manifestes ni de mappages de données. Au lieu de cela, il importe la base de données source, crée un schéma Spanner, crée une base de données Spanner remplie avec les données de la base de données source et génère un rapport d'évaluation détaillé. HarbourBridge est conçu pour charger des bases de données de quelques dizaines de Go à des fins d'évaluation, et non pour des migrations à grande échelle.

HarbourBridge amorce la migration vers Spanner en utilisant une base de données source MySQL ou PostgreSQL existante pour vous permettre de vous lancer rapidement sur Spanner. Il génère un rapport d'évaluation avec un score global d'aptitude à la migration pour Spanner, une analyse table par table des mappages de types et une liste des fonctionnalités utilisées dans la base de données source qui ne sont pas compatibles avec Spanner.

Vous pouvez utiliser HarbourBridge avec l'émulateur Spanner ou directement avec une instance Spanner.

Le fichier README de HarbourBridge contient un guide de démarrage rapide qui explique comment utiliser l'outil avec une instance Spanner.

Installer HarbourBridge

Téléchargez l'outil sur votre ordinateur et installez-le. Vous devez installer Go pour que cela fonctionne. L'installation de tous les modules requis sur une nouvelle instance sans Go peut prendre un certain temps.

# 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

Migrer les données

Utilisez la commande suivante pour migrer la base de données Magento vers Spanner :

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

Configurer l'outil spanner-cli

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

3. Convertir Magento pour qu'il fonctionne avec Spanner

Maintenant que Magento est en cours d'exécution et que l'instance Spanner a été créée avec la base de données Magento migrée, nous allons modifier Magento pour qu'il fonctionne avec les données stockées dans Spanner.

Les étapes suivantes seront effectuées pour convertir l'installation Magento :

  • Clonez le projet magento-spanner-port.
  • Modifier la connexion à Spanner
  • Valider que les informations du catalogue sont renseignées à partir de Spanner

Cloner le fork du projet Magento

Clonez le code de l'application PHP pour Magento, qui contient les modifications apportées aux modules Catalog, Wishlist et Cart à partir de l'URL Git mentionnée ci-dessous.

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

Votre répertoire personnel devrait se présenter comme suit :

$ ls
go  harbourbridge  magento-spanner-port  magento2

magento2 est la codebase que nous allons modifier, en utilisant le code de magento-spanner-port.

Modifier la connexion à Spanner

Pour vérifier si les modifications du code se reflètent dans l'UI, nous pouvons suivre les étapes ci-dessous :

Consultez le lien GitHub https://github.com/searceinc/magento-spanner-port pour obtenir un exemple d'implémentation.

  • Exiger la bibliothèque cliente PHP google/cloud-spanner
  • Ajoutez l'adaptateur Spanner pour créer une connexion à Spanner.
  • Configurez l'instance Spanner et les informations sur le serveur.
  • Ajoutez SpannerInterface et Spanner dans l'adaptateur pour implémenter la connexion à Spanner.

Tout d'abord, nous devons installer la bibliothèque PHP cloud-spanner à l'aide de Composer. Dans le répertoire magento2, exécutez la commande suivante :

cd ~/magento2
composer require google/cloud-spanner

Nous ajoutons ensuite les fichiers de l'adaptateur Spanner depuis magento-spanner-port dans notre codebase 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

Modifiez maintenant le fichier DB/Adapter/Spanner/Spanner.php pour saisir les informations de connectivité Spanner pour $project_id, $instance et $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();
    }

Modifiez la classe AbstractDB dans Magento pour qu'elle se connecte désormais à Spanner à l'aide de la fonction de connexion nouvellement créée dans l'adaptateur Spanner. Ajoutez les lignes vertes après les lignes blanches dans le fichier. Consultez 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;
    }
...

Une fois la connexion établie, nous devons modifier la méthode de récupération des données de l'adaptateur MySQL vers l'adaptateur Spanner . Modifiez la méthode _loadAttributes dans AbstractCollection pour vous connecter à Spanner et récupérer les données de Spanner. Remplacez la ligne rouge par les lignes vertes.

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

...

Valider que les informations du catalogue sont renseignées à partir de Spanner

Et voilà ! Vous pouvez maintenant accéder à votre installation Magento dans le navigateur et vérifier que les données se chargent.

Voici, par exemple, les entrées de catalogue pour les montres :

13b54ba4482408fc.png

Modifiez les données Spanner via le terminal pour l'un des produits, puis interrogez les données via le terminal pour confirmer la modification dans 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)

Maintenant, rechargez l'écran pour confirmer que le nom de la montre est désormais "Aim Analog Spanner", comme indiqué dans le terminal Spanner.

63a9c7b065c7051f.png

4. Félicitations

Félicitations, vous avez réussi à connecter le module de catalogue de Magento à Spanner. Il ne s'agit pas d'une intégration complète, mais vous connaissez désormais les éléments nécessaires pour connecter une application PHP telle que Magento à une instance Spanner.

Nettoyer

Une fois la configuration et la validation du POC terminées, vous pouvez supprimer les ressources GCP créées au cours du processus. Cela inclut la machine virtuelle Compute Engine, ainsi qu'une instance Cloud Spanner si vous avez décidé d'en utiliser une au lieu de l'émulateur.

Étape suivante

Il s'agit simplement d'un modèle prototype pour un POC Spanner.

Si vous souhaitez en savoir plus sur l'utilisation de Spanner et des technologies que nous avons utilisées dans cet atelier de programmation, voici quelques ressources supplémentaires :