1. 簡介

將 Magento 與 Cloud Spanner 後端整合
Magento 是以 PHP 為基礎的熱門開放原始碼電子商務平台,可將資料儲存在 MySQL 中。
本程式碼實驗室是概念驗證,可針對目錄模組使用 Cloud Spanner,而非 MySQL。如果您有興趣整合、測試及部署 Magento 或其他 PHP 應用程式與 Spanner,這項功能就非常實用。
Spanner 是 Google Cloud 的全代管企業級分散式一致性資料庫,結合了關聯式資料庫模型和非關聯水平擴充技術的優點。這項服務的設計宗旨是支援全球線上交易處理部署作業、SQL 語意、高可用性的水平擴充功能和交易一致性。Spanner 能夠處理大量資料。不只適用於大型應用程式,還能為需要 RDBMS 的所有工作負載,提供單一資料庫引擎的標準化服務。Spanner 可在預定維護作業或區域故障期間維持零停機時間,並提供可用性達 99.999%的服務水準協議。這項服務提供高可用性和擴充性,可支援現代應用程式。
課程內容
- 如何在 GCE 上安裝 Magento
- 如何設定 Spanner 模擬器
- 如何使用 HarbourBridge 將現有 MySQL 結構定義遷移至 Spanner
- 如要整合使用 MySQL 做為資料庫後端的 Magento 等 PHP 應用程式,使其能與 Spanner 搭配運作,需要變更哪些項目
建構項目
本程式碼研究室著重於將 Magento 與 Spanner 整合。我們會提供程式碼區塊和設定操作說明,方便您複製及貼上,但不會詳細說明。
在本程式碼研究室中,您將開始整合 Magento 與 Spanner。您將學會以下內容:
- 設定已安裝 Magento 的 GCE 執行個體
- 安裝 Spanner 模擬器
- 安裝 HarbourBridge 工具,將資料從 MySQL 遷移至 Spanner
- 修改 Magento 集合,從 Spanner 載入產品目錄
軟硬體需求
- 已連結至帳單帳戶的 Google Cloud 專案。
- 具備 PHP、Linux 和 Apache 設定知識更佳。
- 具備 Magento 使用經驗會有幫助,但沒有也無妨。
2. 準備 GCE 執行個體
建立 GCE 執行個體
按照這裡所述步驟,在 Google Cloud Platform 中建立 Compute Engine 執行個體。
建立 GCE 執行個體時,請將執行個體類型變更為 e2-standard-2,並將開機磁碟大小變更為 20 GB。您可以保留所有預設設定,但請務必選取「允許 HTTP 流量」和「允許 HTTPS 流量」,因為我們會使用 Magento 的網頁介面。
這會產生 e2-standard-2 的機型,這不是共用核心執行個體,而是具有 2 個 vCPU、8 GB RAM 和 20 GB 磁碟空間。
作業系統為 Debian 10。建立執行個體可能需要幾分鐘的時間。
建立完成後,請在 Cloud 控制台中點選「SSH」登入:

系統會開啟新的瀏覽器視窗,並將您帶到終端機。
安裝必要軟體
執行 Magento 前,必須先安裝一些必要軟體。具體來說,您將安裝 PHP、Elastic、MySQL 和 Apache,詳情如下。
- 安裝部分必要套件。
sudo apt update sudo apt -y install lsb-release apt-transport-https ca-certificates wget git screen composer google-cloud-sdk-spanner-emulator gcc
- 安裝 Magento 必要的 PHP 模組。
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
- 安裝 Elasticsearch 並啟動服務
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
- 安裝 MySQL
您要安裝 MySQL,以便安裝預設的 Magento 結構定義。稍後,您將使用 HarbourBridge 將結構定義遷移至 Spanner。
wget https://dev.mysql.com/get/mysql-apt-config_0.8.13-1_all.deb sudo dpkg -i mysql-apt-config*
上述 dpkg 指令會顯示互動式提示,安裝 MySQL 5.7 伺服器。選取下列選項:
- MySQL 伺服器和叢集
- mysql-5.7
- 確定

sudo apt update && sudo apt -y install mysql-server # You will be prompted to enter a root password
- 安裝 Apache2
sudo apt -y install apache2 sudo a2enmod proxy_fcgi rewrite
安裝及設定 Magento2
Magento Commerce Cloud 雲端專案包含資料庫結構定義和服務,可完整存取 Magento 網站和商店。
如要安裝及執行這項工具,最簡單的方法就是按照 Magento 指示,使用 Composer 安裝:
- 使用 Composer 安裝 Magento 2.4.2 版。Magento 2 需要使用 Composer 1.x 版。您可能會看到一些警告,指出這個版本已淘汰。
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
- 設定資料夾權限
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 {} +
- 建立 /etc/apache2/sites-available/magento.conf,並包含下列內容,設定 Magento 虛擬主機。
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>
- 建立符號連結並重新啟動 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
- 在 MySQL 中建立 Magento 的資料庫和使用者
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/.
- 驗證本機工作區:如要驗證本機環境是否代管伺服器,請使用您在安裝指令中傳遞的基準網址存取商店。在本範例中,您可以使用下列網址格式存取本機 Magento 商店:
- http://<GCEexternalIP>/
- http://<GCEexternalIP>/<adminuri>
您可以在 Cloud 控制台中找到 GCEexternalIP:

如要變更管理面板的 URI,請使用下列指令找出該 URI:
php bin/magento info:adminuri
- 停用整頁快取:為進行開發,您可以停用 Magento2 的整頁快取。這樣一來,您就能修改 Spanner 中的資料,並在網站上反映這些變更,而不會受到快取值影響。
php bin/magento cache:disable full_page
設定 Spanner
安裝 Spanner 模擬器
Cloud SDK 提供記憶體內的本機模擬器,您可以使用這個模擬器免費開發及測試應用程式,不必建立 GCP 專案或帳單帳戶。由於模擬器只會在記憶體中儲存資料,因此重新啟動後,所有狀態 (包括資料、結構定義和設定) 都會遺失。模擬器提供的 API 與 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
將 Magento MySQL 遷移至 Spanner
在深入瞭解如何整合 Spanner 之前,我們會使用名為 HarbourBridge 的工具,將上述 Magento 安裝程序建立的 MySQL 資料庫轉換為 Spanner。
HarbourBridge 的核心功能是提供自動化工作流程,將現有 MySQL 或 PostgreSQL 資料庫的內容載入 Spanner。完全不需要設定,也不必編寫資訊清單或資料對應。而是匯入來源資料庫、建構 Spanner 結構定義、建立新的 Spanner 資料庫 (其中填入來源資料庫的資料),並產生詳細的評估報告。HarbourBridge 適用於載入幾十 GB 的資料庫進行評估,不適用於大規模遷移。
HarbourBridge 會使用現有的 MySQL 或 PostgreSQL 來源資料庫,啟動 Spanner 的早期遷移作業,協助您快速在 Spanner 上運作。這項工具會產生評估報告,其中包含 Spanner 的整體遷移適用性分數、類型對應的資料表分析,以及來源資料庫中使用的功能清單 (Spanner 不支援這些功能)。
HarbourBridge 可搭配 Spanner 模擬器使用,也可以直接搭配 Spanner 執行個體使用。
HarbourBridge README 包含快速入門指南,逐步說明如何搭配 Spanner 執行個體使用這項工具。
安裝 HarbourBridge
將工具下載至電腦並安裝。您必須安裝 golang,這項功能才能運作。如果沒有預先設定 Go,在新執行個體上安裝所有必要模組可能需要一段時間。
# 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
遷移資料
使用下列指令將 Magento 資料庫遷移至 Spanner:
mysqldump --user='root' --password=$ROOT_PASSWORD magento | go run github.com/cloudspannerecosystem/harbourbridge -driver=mysqldump -dbname=magento
設定 spanner-cli 工具
go install github.com/cloudspannerecosystem/spanner-cli@latest
3. 將 Magento 轉換為與 Spanner 搭配使用
現在 Magento 已經開始運作,且已建立 Spanner 執行個體並遷移 Magento 資料庫,接下來我們要修改 Magento,以便使用 Spanner 中儲存的資料。
系統會執行下列步驟來轉換 Magento 安裝:
- 複製 magento-spanner-port 專案
- 變更與 Spanner 的連線
- 確認系統已從 Spanner 填入 Catalog 詳細資料
複製 Magento 專案的分支
從下方提及的 Git 網址,複製 Magento 的 PHP 應用程式程式碼,其中包含目錄、願望清單和購物車模組的修改內容。
cd ~ git clone https://github.com/searceinc/magento-spanner-port
您的主目錄應如下所示:
$ ls go harbourbridge magento-spanner-port magento2
其中 magento2 是我們要修改的程式碼集,使用來自 magento-spanner-port 的程式碼。
變更與 Spanner 的連線
如要檢查程式碼修改是否反映在 UI 中,請按照下列步驟操作:
如需實作範例,請參閱 Github 連結 https://github.com/searceinc/magento-spanner-port。
- 需要 google/cloud-spanner PHP 用戶端程式庫
- 新增 Spanner 介面卡,建立與 Spanner 的連線。
- 設定 Spanner 執行個體和伺服器資訊。
- 在 Adapter 中新增 SpannerInterface 和 Spanner,實作與 Spanner 的連線。
首先,我們需要使用 Composer 安裝 cloud-spanner PHP 程式庫。在 magento2 目錄中,執行下列指令:
cd ~/magento2 composer require google/cloud-spanner
接著,我們將 magento-spanner-port 中的 Spanner 轉接頭檔案新增至 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
現在,請修改 DB/Adapter/Spanner/Spanner.php 檔案,輸入 $project_id、$instance 和 $database 的 Spanner 連線資訊:
$ 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();
}
修改 Magento 中的 AbstractDB 類別,現在即可使用 Spanner Adapter 中新建立的連線函式連線至 Spanner。在檔案中的白線後方新增綠線。請參閱 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;
}
...
連線建立後,我們需要將資料擷取方法從 MySQL 介面卡修改為 Spanner 介面卡。修改 AbstractCollection 中的 _loadAttributes 方法,連線至 Spanner 並從 Spanner 擷取資料。將紅線取代為綠線。
請參閱 /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);
...
確認系統已從 Spanner 填入 Catalog 詳細資料
大功告成!現在,您可以在瀏覽器中前往 Magento 安裝位置,並確認資料是否正在載入。
舉例來說,以下是手錶的目錄項目:

透過終端機修改其中一項產品的 Spanner 資料,並透過終端機查詢資料,確認 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)
現在重新載入畫面,確認手錶名稱已變更為「Aim Analog Spanner」,這是透過 Spanner 終端機更新的名稱。

4. 恭喜
恭喜!您已成功連結 Magento 的目錄模組,可與 Spanner 搭配使用。這並非完整整合,但您現在已瞭解如何將 Magento 等 PHP 應用程式連線至 Spanner 執行個體。
正在清除所用資源
完成 POC 設定和驗證後,您可能想刪除在此程序中建立的 GCP 資源。這包括 Compute Engine 虛擬機器,以及您決定使用 Cloud Spanner 執行個體 (而非模擬器) 時的執行個體。
後續步驟
這只是 Spanner POC 的原型模型。
如要進一步瞭解如何使用 Spanner,以及我們在本程式碼研究室中採用的技術,請參閱下列額外資源: