שילוב Magento עם Cloud Spanner

1. מבוא

424db48d9db91638.png

שילוב Magento עם קצה עורפי של Cloud Spanner

Magento היא פלטפורמת מסחר אלקטרוני בקוד פתוח פופולרית שמבוססת על PHP, שמאחסנת נתונים ב-MySQL.

ה-Codelab הזה הוא הוכחת קונספט לשימוש ב-Cloud Spanner במקום ב-MySQL בשביל המודול של Catalog. זו שיטה שימושית לכל מי שרוצה לשלב, לבדוק ולפרוס את Magento או אפליקציות PHP אחרות עם Spanner.

Spanner הוא מסד נתונים מנוהל, ברמת הארגון, מבוזר ועקבי ב-Google Cloud שמשלב את היתרונות של מודל מסד הנתונים הרלציוני עם מדרגיות אופקית לא יחסית. הוא תוכנן לתמוך בפריסות גלובליות של עיבוד עסקאות אונליין, בסמנטיקה של SQL, בהתאמה לעומס (scaling) אופקית עם זמינות גבוהה ובעקביות עסקאות. Spanner מסוגל לטפל בנפח גדול של נתונים. השימוש בו לא מוגבל לאפליקציות גדולות, אבל הוא מאפשר סטנדרטיזציה של מנוע מסד נתונים יחיד לכל עומסי העבודה שדורשים RDBMS. Spanner מספק זמן השבתה לצורך תחזוקה מתוכננות או כשלים באזור, עם הסכם רמת שירות לזמינות של 99.999%. הוא תומך בזמינות גבוהה ומדרגיות באפליקציות מודרניות.

מה תלמדו

  • איך להתקין את Magento ב-GCE
  • איך להגדיר את אמולטור Spanner
  • איך להעביר סכימת MySQL קיימת ל-Spanner באמצעות HarbourBiger
  • מה צריך לשנות כדי לשלב אפליקציות PHP כמו Magento שמשתמשות ב-MySQL לקצה העורפי של מסד הנתונים כדי לפעול עם Spanner

מה תפַתחו

ב-codelab הזה נסביר איך לשלב את Magento עם Spanner. בלוקים של קוד והוראות הגדרה ניתנים להעתקה ולהדבקה, אבל אין הסבר מפורט עליהם.

ב-Codelab הזה, אתם עומדים להתחיל לשלב את Magento עם Spanner. אתם:

מה נדרש

  • פרויקט ב-Google Cloud שמקושר לחשבון לחיוב.
  • יתרון נוסף הוא ידע בתצורה של PHP,‏ Linux ו-Apache.
  • השימוש ב-Magento יהיה שימושי, אבל לא חובה.

2. הכנת מכונת GCE

יצירת המכונה ב-GCE

יוצרים מכונה של Compute Engine ב-Google Cloud Platform לפי השלבים שמפורטים כאן.

כשיוצרים את המכונה ב-GCE, משנים את סוג המכונה ל-e2-standard-2 ואת גודל דיסק האתחול ל-20GB. אפשר להשאיר את כל ההגדרות כברירת מחדל, אבל חשוב לבחור באפשרויות 'Allow HTTP traffic' ו-'Allow HTTPs traffic', כי נשתמש בממשק האינטרנט של Magento.

התוצאה היא סוג מכונה מסוג e2-standard-2, שהיא לא מכונה עם ליבה משותפת ויש לה 2vCPU,‏ 8GB של RAM ו-20GB של נפח דיסק.

מערכת ההפעלה היא Debian 10. יצירת המכונה עשויה להימשך דקה או שתיים.

לאחר היצירה, לוחצים על 'SSH' במסוף Cloud כדי להתחבר:

4bf915ef8d37c942.png

פעולה זו תפתח חלון דפדפן חדש ותעביר אותך למסוף.

התקנת תוכנות קודמות

כדי שנוכל להריץ את Magento, נצטרך להתקין תוכנות מסוימות שנדרשות ל-Magento. באופן ספציפי, יש להתקין את PHP, Elastic, MySQL ו-Apache כמפורט למטה.

  1. מתקינים כמה חבילות נדרשות.
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. התקנת מודולים של PHP שנדרשים ל-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. התקנת 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
  1. התקנת MySQL

התקנתם את MySQL כדי להתקין את הסכימה שמוגדרת כברירת מחדל ב-Magento. לאחר מכן, תעבירו את הסכימה ל-Spanner באמצעות HarbourBiger.

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
  • mysql-5.7
  • אישור

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. התקנת Apache2
sudo apt -y install apache2

sudo a2enmod proxy_fcgi rewrite

התקנה והגדרה של Magento2

הפרויקט Magento Commerce Cloud כולל סכימה של מסד נתונים ושירותים כדי לקבל גישה מלאה לאתר ולחנות של Magento.

הדרך הקלה ביותר להתקין ולהפעיל את התוסף הזה היא לפעול לפי ההוראות של Magento להתקנה באמצעות 'מלחין':

  1. מתקינים את גרסה 2.4.2 של Magento באמצעות המלחין. כדי להשתמש ב-Magento 2, נדרשת גרסת composer 1.x. יכול להיות שיופיעו אזהרות לגבי הוצאה משימוש של התמיכה בגרסת ה-API הזו.
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.2 magento2
  1. הגדרת הרשאות ברמת התיקייה
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. מגדירים את המארח הווירטואלי של Magento על ידי יצירת הקובץ /etc/apache2/sites-available/magento.conf עם התוכן הבא.
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. יוצרים את הקישורים הלא היררכיים ומפעילים מחדש את 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. יצירה של מסד הנתונים והמשתמש של Magento ב-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. אימות סביבת העבודה המקומית: כדי לוודא שהסביבה המקומית מארחת את השרת, נכנסים לחנות באמצעות כתובת ה-URL הבסיסית שהעברתם בפקודת ההתקנה. בדוגמה הזו, אפשר לגשת לחנות Magento המקומית באמצעות פורמטים של כתובות URL הבאים:
  • http://<GCEexternalIP>/
  • http://<GCEexternalIP>/<adminuri>

אפשר למצוא את GCEexternalIP במסוף Cloud:

3947f1164e1d5409.png

כדי לשנות את ה-URI של חלונית הניהול, משתמשים בפקודה הבאה כדי לאתר אותו:

php bin/magento info:adminuri
  1. השבתת המטמון של הדף המלא: למטרות פיתוח, אפשר להשבית את המטמון של הדף המלא ב-Magento2. כך תהיה לך אפשרות לשנות את הנתונים ב-Spanner ולהציג אותם באתר בלי שתהיה לכך השפעה על ערכים שנשמרו במטמון.
php bin/magento cache:disable full_page

הגדרת Spanner

התקנת Spanner Emulator

Cloud SDK מספק אמולטור מקומי בזיכרון, שבעזרתו אפשר לפתח ולבדוק אפליקציות בחינם, בלי ליצור פרויקט GCP או חשבון לחיוב. מכיוון שהאמולטור מאחסן נתונים רק בזיכרון, כל המצבים, כולל נתונים, סכימה והגדרות, אובדים בהפעלה מחדש. בסימולטור מוצעים אותם ממשקי API כמו בשירות Spanner בסביבת הייצור, והוא מיועד לפיתוח ולבדיקה מקומיים, ולא לפריסות בסביבת הייצור.

בקישור הבא אפשר למצוא מידע נוסף על התקנה, שימוש ופריסה של המהדר:

שימוש באמולטור 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 כדי להמיר את מסד הנתונים של MySQL שנוצר כחלק מההתקנה של Magento שלמעלה ל-Spanner.

בבסיס, HarbourBridge מספק תהליך עבודה אוטומטי לטעינת התוכן של מסד נתונים קיים של MySQL או PostgreSQL ל-Spanner. אין צורך לקבוע הגדרות אישיות בשביל זה – אין מניפסטים או מפות נתונים לצורך כתיבה. במקום זאת, הכלי מייבא את מסד הנתונים של המקור, יוצר סכימה של Spanner, יוצר מסד נתונים חדש של Spanner שמאוכלס בנתונים ממקור הנתונים ויוצר דוח הערכה מפורט. HarbourBiger מיועד לטעינת מסדי נתונים עד כמה עשרות GB למטרות הערכה, ולא להעברות בקנה מידה מלא.

מעבר ל-HarbourBiger shoes העברה בשלב מוקדם אל Spanner באמצעות מסד נתונים קיים של מקור MySQL או PostgreSQL, כדי לאפשר לך להתחיל לעבוד במהירות ב-Spanner. היא יוצרת דוח הערכה עם ציון התאמה כולל להעברה ל-Spanner, ניתוח טבלה של מיפויי הסוגים ורשימה של התכונות שנמצאות בשימוש במסד הנתונים של המקור שלא נתמכות על ידי Spanner.

אפשר להשתמש ב-HarbourBiger באמצעות האמולטור Spanner או ישירות באמצעות המכונה של Spanner.

הקובץ HarbourBig 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

שכפול ההסתעפות של פרויקט Magento

מעתיקים את קוד האפליקציה של PHP ל-Magento, שמכיל את השינויים במודולים 'קטלוג', 'רשימת משאלות' ו'עגלת קניות', מכתובת ה-URL של Git שמופיעה בהמשך.

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

ספריית הבית אמורה להיראות כך:

$ ls
go  harbourbridge  magento-spanner-port  magento2

כאשר magento2 הוא ה-codebase שנשנה, באמצעות קוד מ-magento-spanner-port.

שינוי החיבור ל-Spanner

כדי לבדוק אם השינויים בקוד משתקפים בממשק המשתמש, אפשר לפעול לפי השלבים הבאים:

להטמעה לדוגמה, אפשר לעיין בקישור של GitHub https://github.com/searceinc/magento-spanner-port.

  • נדרשת ספריית הלקוח google/cloud-spanner PHP
  • מוסיפים את Spanner Adapter ליצירת חיבור ל-Spanner.
  • מגדירים את המכונה של Spanner ואת פרטי השרת.
  • צריך להוסיף את SpannerInterface ו-Spanner במתאם כדי להטמיע את החיבור ל-Spanner.

ראשית, עלינו להתקין את ספריית ה-PHP עם מפתח הברגים בענן באמצעות המלחין. בספרייה magento2, מריצים את הפקודה הבאה:

cd ~/magento2
composer require google/cloud-spanner

לאחר מכן מוסיפים את הקבצים במתאם Spanner מ-magento-spanner-port ל-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

עכשיו משנים את הקובץ DB/Adapter/Spanner/Spanner.php כדי להזין את פרטי הקישוריות של Spanner עבור $project_id,‏ $instance ו-$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();
    }

משנים את המחלקה AbstractDB ב-Magento כדי להתחבר ל-Spanner באמצעות פונקציית החיבור החדשה שנוצרה במתאם 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 . משנים את השיטה _loadAttributes ב-AbstractCollection כדי להתחבר ל-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

זהו! עכשיו אפשר לעבור ל-Magento בדפדפן ולבדוק אם הנתונים נטענים.

לדוגמה, רשומות הקטלוג של שעונים הם:

13b54ba4482408fc.png

משנים את נתוני 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.

63a9c7b065c7051f.png

4. מזל טוב

מזל טוב, חיברת בהצלחה את מודול הקטלוג של Magento כדי לעבוד עם Spanner! זה לא שילוב מלא, אבל עכשיו אתם מכירים את הרכיבים שנדרשים כדי לחבר אפליקציית PHP כמו Magento למכונה של Spanner.

מנקה

לאחר השלמת ההגדרה והאימות של ה-POC, כדאי למחוק את משאבי ה-GCP שנוצרו במהלך התהליך. הפריטים האלה יכללו את המכונה הווירטואלית של Compute Engine וגם את המכונה של Cloud Spanner, אם תחליטו להשתמש במכונה הווירטואלית במקום ב-Eמולטור.

מה השלב הבא?

זהו רק מודל אב טיפוס של איש קשר ב-Spanner.

מידע נוסף על עבודה עם Spanner ועל הטכנולוגיות שהשתמשנו בהן ב-codelab הזה זמין במקורות המידע הבאים: