Como integrar o Magento ao Cloud Spanner

1. Introdução

424db48d9db91638.png

Como integrar o Magento a um back-end do Cloud Spanner

O Magento é uma plataforma de e-commerce de código aberto baseada em PHP muito conhecida que armazena dados no MySQL.

Este codelab é uma prova de conceito para aproveitar o Cloud Spanner em vez do MySQL para o módulo de catálogo. Isso é útil para quem quer integrar, testar e implantar o Magento ou outros aplicativos PHP com o Spanner.

O Spanner é o banco de dados consistente, de nível empresarial, totalmente gerenciado do Google Cloud. Ele combina os benefícios do modelo de banco de dados relacional com a escalonabilidade horizontal não relacional. Ele foi projetado para dar suporte a implantações globais de processamento de transações on-line, semânticas de SQL, escalonamento horizontal altamente disponível e consistência transacional. O Spanner é capaz de lidar com grandes volumes de dados. O uso não se limita a aplicativos de grande porte, mas permite a padronização de um único mecanismo de banco de dados para todas as cargas de trabalho que exigem RDBMS. O Spanner oferece inatividade zero para manutenção planejada ou falhas de região, com um SLA de disponibilidade de 99,999%. Ele oferece suporte a aplicativos modernos, oferecendo alta disponibilidade e escalonabilidade.

O que você vai aprender

  • Como instalar o Magento no GCE
  • Como configurar o Spanner Emulator
  • Como migrar um esquema MySQL atual para o Spanner usando o HarbourBridge
  • O que você precisa mudar para integrar aplicativos PHP como o Magento, que usam MySQL como back-end do banco de dados para funcionar com o Spanner

O que você vai criar

O foco deste codelab é a integração do Magento com o Spanner. Os blocos de código e as instruções de configuração são fornecidos para você copiar e colar, mas não são abordados em detalhes.

Neste codelab, você vai começar a integrar o Magento ao Spanner. Você vai:

O que é necessário

  • Um projeto do Google Cloud conectado a uma conta de faturamento.
  • Conhecimento sobre a configuração de PHP, Linux e Apache é um diferencial.
  • A experiência com o Magento será útil, mas não é obrigatória.

2. Como preparar a instância do GCE

Crie a instância do GCE

Crie uma instância do Compute Engine na Plataforma Google Cloud seguindo as etapas mencionadas aqui.

Ao criar a instância do GCE, mude o tipo de instância para e2-standard-2 e o tamanho do disco de inicialização para 20 GB. Você pode deixar tudo como padrão, mas não se esqueça de selecionar "Allow HTTP traffic" e "Allow HTTPs traffic", já que vamos usar a interface da Web do Magento.

Isso resulta em um tipo de máquina e2-standard-2, que não é uma instância de núcleo compartilhado e tem 2 vCPUs, 8 GB de RAM e 20 GB de espaço em disco.

O sistema operacional é o Debian 10. A criação da instância pode levar um ou dois minutos.

Depois da criação, faça login clicando em "SSH" no Console do Cloud:

4bf915ef8d37c942.png

Uma nova janela do navegador será aberta e você será colocado em um terminal.

Instalar o software de pré-requisito

O Magento vai precisar de alguns pré-requisitos de software para ser executado. Mais especificamente, você vai instalar o PHP, o Elastic, o MySQL e o Apache, conforme detalhado abaixo.

  1. Instale alguns pacotes necessários.
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. Instale os módulos PHP necessários para o 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. Instalar o Elasticsearch e iniciar o serviço
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. Instalar o MySQL

Você está instalando o MySQL para instalar o esquema padrão do Magento. Mais tarde, você vai migrar o esquema para o Spanner usando o HarbourBridge.

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

sudo dpkg -i mysql-apt-config*

O comando dpkg acima vai abrir um prompt interativo para instalar o servidor MySQL 5.7. Selecione as opções:

  • Servidor e cluster do 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. Instalar o Apache2
sudo apt -y install apache2

sudo a2enmod proxy_fcgi rewrite

Instalar e configurar o Magento2

O projeto do Magento Commerce Cloud inclui um esquema de banco de dados e serviços para acessar totalmente o site e a loja do Magento.

A maneira mais fácil de instalar e executar isso é seguindo as instruções do Magento para instalar usando o composer:

  1. Instale a versão 2.4.2 do Magento usando o composer. O Magento 2 requer a versão do Composer 1.x. Talvez você receba alguns avisos sobre a descontinuação do suporte a essa versão.
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
  1. Definir permissões de pasta
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. Configure o host virtual do Magento criando /etc/apache2/sites-available/magento.conf com o conteúdo abaixo.
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. Crie os links simbólicos e reinicie o 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. Criar o banco de dados e o usuário do Magento no 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. Verifique seu espaço de trabalho local Para verificar se o ambiente local está hospedando o servidor, acesse o armazenamento usando o URL base que você transmitiu no comando de instalação. Neste exemplo, você pode acessar a loja local do Magento usando os seguintes formatos de URL:
  • http://&lt;GCEexternalIP&gt;/
  • http://&lt;GCEexternalIP&gt;/&lt;adminuri&gt;

O GCEexternalIP pode ser encontrado no Console do Cloud:

3947f1164e1d5409.png

Para alterar o URI do painel do administrador, use este comando para localizá-lo:

php bin/magento info:adminuri
  1. Desative o cache de página completa Para fins de desenvolvimento, você pode desativar o cache de página completa do Magento2. Assim, é possível modificar os dados no Spanner e fazer com que eles apareçam no site sem ser afetado pelos valores armazenados em cache.
php bin/magento cache:disable full_page

Configurar o Spanner

Instalar o emulador do Spanner

O SDK Cloud fornece um emulador local na memória, que pode ser usado para desenvolver e testar os aplicativos sem custo financeiro sem criar um projeto do GCP ou uma conta de faturamento. Como o emulador armazena dados apenas na memória, todo o estado, incluindo dados, esquema e configurações, é perdido na reinicialização. O emulador oferece as mesmas APIs que o serviço de produção do Spanner e destina-se ao desenvolvimento e teste locais, não para implantações de produção.

Use o link abaixo para consultar mais informações sobre a instalação, o uso e a implantação do emulador:

Como usar o emulador do 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

Migrar o Magento MySQL para o Spanner

Antes de começar a integrar o Spanner, vamos usar uma ferramenta chamada HarbourBridge para converter o banco de dados do MySQL criado como parte da instalação do Magento acima para o Spanner.

Em sua essência, o HarbourBridge fornece um fluxo de trabalho automatizado para carregar o conteúdo de um banco de dados MySQL ou PostgreSQL no Spanner. Não requer configuração, nem manifestos ou mapas de dados para gravar. Em vez disso, ele importa o banco de dados de origem, cria um esquema do Spanner, cria um novo banco de dados do Spanner preenchido com dados do banco de origem e gera um relatório de avaliação detalhado. O HarbourBridge é destinado ao carregamento de bancos de dados de até algumas dezenas de GB para fins de avaliação, não para migrações em grande escala.

O HarbourBridge inicia a migração inicial para o Spanner usando um banco de dados de origem MySQL ou PostgreSQL para que você possa começar a usar o Spanner rapidamente. Ele gera um relatório de avaliação com uma pontuação geral de compatibilidade de migração para o Spanner, uma análise de tabela por tabela dos mapeamentos de tipo e uma lista de recursos usados no banco de dados de origem que não têm suporte do Spanner.

O HarbourBridge pode ser usado com o Spanner Emulator ou diretamente com uma instância do Spanner.

O README do HarbourBridge contém um guia de início rápido passo a passo para usar a ferramenta com uma instância do Spanner.

Instalar o HarbourBridge

Faça o download da ferramenta na sua máquina e instale-a. É necessário instalar o golang para que isso funcione. A instalação de todos os módulos necessários em uma nova instância sem configuração prévia do Go pode demorar um pouco.

# 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

Migrar os dados

Use o seguinte comando para migrar o banco de dados do Magento para o Spanner:

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

Configurar a ferramenta spanner-cli

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

3. Converter o Magento para funcionar com o Spanner

Agora que o Magento está em execução e a instância do Spanner criada com o banco de dados do Magento foi migrada, vamos modificar o Magento para trabalhar com os dados armazenados no Spanner.

Siga estas etapas para converter a instalação do Magento:

  • Clone o projeto magento-spanner-port.
  • Alterar a conexão com o Spanner
  • Validar se os detalhes do catálogo são preenchidos pelo Spanner

Clonar a bifurcação do projeto Magento

Clone o código do aplicativo PHP para Magento, que contém as modificações para os módulos "Catálogo", "Lista de desejos" e "Carrinho" do URL Git mencionado abaixo.

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

O diretório principal será parecido com este:

$ ls
go  harbourbridge  magento-spanner-port  magento2

Em que magento2 é a base de código que vamos modificar, usando o código de magento-spanner-port.

Alterar a conexão com o Spanner

Para verificar se as modificações no código são refletidas na interface, siga as etapas abaixo:

Consulte o link do GitHub https://github.com/searceinc/magento-spanner-port (link em inglês) para conferir um exemplo de implementação.

  • Exigir a biblioteca de cliente PHP google/cloud-spanner
  • Adicione o Spanner Adapter para criar uma conexão com o Spanner.
  • Configurar as informações da instância e do servidor do Spanner.
  • Adicione o SpannerInterface e o Spanner no adaptador para implementar a conexão com o Spanner.

Primeiro, precisamos instalar a biblioteca PHP do Cloud Spanner usando o Composer. No diretório magento2, execute este comando:

cd ~/magento2
composer require google/cloud-spanner

Depois, adicionamos os arquivos do adaptador do Spanner de magento-spanner-port à nossa base de código 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

Agora, modifique o arquivo DB/Adapter/Spanner/Spanner.php para inserir as informações de conectividade do Spanner para $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();
    }

Modifique a classe AbstractDB no Magento para se conectar ao Spanner usando a função de conexão recém-criada no adaptador Spanner. Adicione as linhas verdes após as linhas brancas no arquivo. Consulte 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;
    }
...

Depois que a conexão for estabelecida, precisamos modificar o método de busca de dados do adaptador do MySQL para o adaptador do Spanner . Modifique o método _loadAttributes em PersistentVolumeCollection para se conectar ao Spanner e buscar os dados dele. Substitua a linha vermelha pelas linhas verdes.

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

...

Validar se os detalhes do catálogo são preenchidos pelo Spanner

Pronto! Acesse sua instalação do Magento no navegador e verifique se os dados estão sendo carregados.

Por exemplo, estas são as entradas de catálogo para relógios:

13b54ba4482408fc.png

Modifique os dados do Spanner pelo terminal de um dos produtos e consulte os dados pelo terminal para confirmar a modificação no 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)

Agora, recarregue a tela para confirmar se o nome do relógio foi alterado para "Aim Analog Spanner", conforme atualizado pelo terminal do Spanner.

63a9c7b065c7051f.png

4. Parabéns

Parabéns! Você conectou o módulo de catálogo do Magento para trabalhar com o Spanner. Ela não é uma integração completa, mas agora você conhece os elementos necessários para conectar um aplicativo PHP como o Magento a uma instância do Spanner.

Limpar

Quando a configuração e a validação do POC forem concluídas, exclua os recursos do GCP criados durante o processo. Isso inclui a máquina virtual do Compute Engine e uma instância do Cloud Spanner, se você decidir usar uma delas em vez do emulador.

A seguir

Este é apenas um modelo de protótipo para um POC do Spanner.

Se você quiser saber mais sobre como trabalhar com o Spanner e as tecnologias que usamos neste codelab, veja mais alguns recursos: