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 PHP très populaire qui stocke des données dans MySQL.

Cet atelier de programmation sert de démonstration de faisabilité pour utiliser Cloud Spanner au lieu de MySQL dans le module "Catalogue". Il 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 Google Cloud entièrement gérée, professionnelle, distribuée et cohérente qui associe les avantages du modèle de base de données relationnelle à l'évolutivité horizontale non relationnelle. Il est conçu pour prendre en charge les déploiements mondiaux du traitement des transactions en ligne, la sémantique SQL, le scaling horizontal à disponibilité élevée et la cohérence transactionnelle. Spanner est capable de gérer d'importants volumes de données. Son utilisation ne se limite pas aux applications de grande taille, mais permet de standardiser un seul moteur de base de données pour toutes les charges de travail nécessitant un SGBDR. Spanner offre des temps d'arrêt nuls en cas de maintenance planifiée ou de défaillance d'une région, avec un contrat de niveau de service garantissant une disponibilité de 99,999%. Il est compatible avec les applications modernes grâce à une haute disponibilité et une évolutivité.

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 intégrer des applications PHP telles que Magento qui utilisent MySQL pour que le backend de la base de données fonctionne avec Spanner

Ce que vous allez faire

Cet atelier de programmation porte sur l'intégration de Magento à Spanner. Les blocs de code et les instructions de configuration vous sont fournis afin 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 sur laquelle Magento est installé
  • Installer l'émulateur Spanner
  • Installez l'outil HarbourBridge pour migrer les données de MySQL vers Spanner.
  • Modifier les collections Magento pour charger le catalogue de produits depuis Spanner

Prérequis

  • Un projet Google Cloud associé à un compte de facturation
  • La connaissance de la configuration de PHP, Linux et Apache est un plus.
  • L'expérience Magento peut être utile, mais ce n'est 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 la procédure indiquée ici.

Lors de la création de 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 conserver tous les paramètres par défaut, mais veillez à sélectionner "Autoriser le trafic HTTP" et "Allow HTTPS traffic", car nous allons exploiter l'interface Web de Magento.

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

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

Une fois le projet créé, 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 le logiciel prérequis

Pour pouvoir exécuter Magento, vous devez installer un logiciel préalable. Plus précisément, vous installerez 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. Plus tard, vous migrerez 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 suivantes:

  • Serveurs MySQL et Cluster
  • 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 à l'ensemble du site et de la boutique Magento.

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

  1. Installez la version 2.4.2 de Magento à l'aide de composer. Magento 2 nécessite la version 1.x de Composer. Des avertissements peuvent s'afficher pour vous informer que cette version ne sera bientôt plus prise en charge.
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
  1. Définir les autorisations des 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, puis 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 vous assurer que l'environnement local héberge le serveur, accédez au store à 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 locale Magento à l'aide des formats d'URL suivants:
  • http://&lt;GCEexternalIP&gt;/
  • http://&lt;GCEexternalIP&gt;/&lt;adminuri&gt;

Vous trouverez l'adresse IP GCEexternalIP dans la console Cloud:

3947f1164e1d5409.png

Pour modifier l'URI du panneau d'administration, localisez-le à l'aide de la commande suivante:

php bin/magento info:adminuri
  1. Désactiver le cache de page entière Pour des raisons de développement, vous pouvez désactiver le cache complet de la page de Magento2. Vous pourrez ainsi modifier les données dans Spanner et les voir apparaître sur le site Web sans être affectées par les valeurs mises en cache.
php bin/magento cache:disable full_page

Configurer Spanner

Installer l'émulateur Spanner

Cloud SDK fournit un émulateur local en mémoire qui vous permet de développer et de tester vos applications sans frais, sans créer de projet GCP ni de compte de facturation. Étant donné que l'émulateur ne stocke les données que dans la 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 en local, et non aux déploiements en production.

Veuillez cliquer sur 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 plonger dans l'intégration de Spanner, nous allons utiliser un outil appelé HarbourBridge pour convertir en Spanner la base de données MySQL créée dans le cadre de l'installation de Magento ci-dessus.

À la base, HarbourBridge fournit un workflow automatisé permettant de charger le contenu d'une base de données MySQL ou PostgreSQL existante dans Spanner. Il ne nécessite aucune configuration, c'est-à-dire aucun fichier manifeste ni mappage de données à écrire. À la place, il importe la base de données source, crée un schéma Spanner, crée une base de données Spanner contenant les données de cette base et génère un rapport d'évaluation détaillé. HarbourBridge est destiné à charger des bases de données jusqu'à quelques dizaines de Go à des fins d'évaluation, et non pour les migrations à grande échelle.

HarbourBridge lance la migration en amont vers Spanner à l'aide d'une base de données source MySQL ou PostgreSQL existante pour vous permettre d'être rapidement opérationnel sur Spanner. Il génère un rapport d'évaluation contenant un score global d'adéquation à 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.

HarbourBridge peut être utilisé avec l'émulateur Spanner ou directement avec une instance Spanner.

Le fichier README HarbourBridge contient un guide de démarrage rapide détaillé sur l'utilisation de l'outil avec une instance Spanner.

Installer HarbourBridge

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

# 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

Exécutez 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 utiliser Spanner

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

Pour convertir l'installation de Magento, procédez comme suit:

  • Clonez le projet magento-spanner-port.
  • Modifier la connexion à Spanner
  • Vérifier que les détails du catalogue sont renseignés à partir de Spanner

Cloner la copie du projet Magento

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

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

Votre répertoire d'accueil doit se présenter comme suit:

$ ls
go  harbourbridge  magento-spanner-port  magento2

magento2 est le codebase que nous allons modifier à l'aide du code de magento-spanner-port.

Modifier la connexion à Spanner

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

Reportez-vous au 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
  • Ajout d'un adaptateur Spanner pour créer une connexion à Spanner.
  • Configurez les informations sur l'instance et le serveur Spanner.
  • Ajout de SpannerInterface et Spanner dans l'adaptateur pour implémenter la connexion à Spanner.

Nous devons d'abord installer la bibliothèque PHP cloud-spanner à l'aide de Composer. Exécutez la commande suivante dans le répertoire magento2:

cd ~/magento2
composer require google/cloud-spanner

Nous ajoutons ensuite les fichiers de l'adaptateur Spanner du port magento-spanner-port à 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

À présent, modifiez le fichier DB/Adapter/Spanner/Spanner.php afin de saisir les informations de connectivité de 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();
    }

Modifier la classe AbstractDB dans Magento pour maintenant se connecter à Spanner à l'aide de la fonction de connexion récemment 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 remplacer la méthode de récupération des données de l'adaptateur MySQL par l'adaptateur Spanner . Modifiez la méthode _loadAttributes dans AbstractCollection pour vous connecter à Spanner et extraire 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);

...

Vérifier que les détails du catalogue sont renseignés à partir de Spanner

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

Par exemple, voici les entrées du catalogue pour des montres:

13b54ba4482408fc.png

Modifier les données Spanner via le terminal pour l'un des produits et interroger 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, actualisez l'écran pour vérifier que le nom de la montre est maintenant remplacé par "Aim Analog Spanner". mis à jour via le terminal Spanner.

63a9c7b065c7051f.png

4. Félicitations

Félicitations ! Vous avez connecté le module "Catalogue" de Magento pour qu'il fonctionne avec Spanner. Il ne s'agit pas d'une intégration complète, mais vous connaissez maintenant les éléments nécessaires pour connecter une application PHP telle que Magento à une instance Spanner.

Nettoyer

Une fois la configuration et la validation de la démonstration de faisabilité 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 décidez d'en utiliser une à la place de l'émulateur.

Étape suivante

Il ne s'agit que d'un prototype de modèle de démonstration de faisabilité pour Spanner.

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