دمج Magento مع Cloud Spanner

1. مقدمة

424db48d9db91638.png

دمج Magento مع خلفية Cloud Spanner

Magento هي منصة مفتوحة المصدر للتجارة الإلكترونية تستند إلى PHP وتخزّن البيانات في MySQL.

هذا الدرس التطبيقي حول الترميز هو عبارة عن إثبات صحة المفهوم للاستفادة من Cloud Spanner بدلاً من MySQL لوحدة "الفهرس". هذا البرنامج مفيد لأي شخص مهتم بدمج Magento أو تطبيقات PHP الأخرى واختبارها ونشرها باستخدام Spanner.

‫Spanner هي قاعدة بيانات موزّعة ومتّسقة ومُدارة بالكامل على Google Cloud ومصمَّمة للمؤسسات، وتجمع بين مزايا نموذج قاعدة البيانات الارتباطية وإمكانية التوسّع الأفقي غير الارتباطي. وهي مصمَّمة لدعم عمليات نشر عالمية لمعالجة المعاملات على الإنترنت، ودلالات لغة الاستعلامات البنيوية (SQL)، والتوسّع الأفقي العالي التوفّر، والاتساق في المعاملات. يمكن لخدمة Spanner التعامل مع كميات كبيرة من البيانات. ولا يقتصر استخدامه على التطبيقات الكبيرة الحجم، بل يتيح توحيد محرك قاعدة بيانات واحد لجميع أحمال العمل التي تتطلّب نظام إدارة قواعد البيانات العلائقية. توفّر Spanner إمكانية عدم التوقف عن العمل أثناء الصيانة المجدولة أو حالات تعذُّر الوصول إلى المنطقة، وذلك من خلال اتفاقية مستوى الخدمة (SLA) الخاصة بمدى التوفّر بنسبة%99.999. وهي تتيح استخدام التطبيقات الحديثة من خلال توفير مستوى عالٍ من التوفّر وقابلية التوسّع.

أهداف الدورة التعليمية

  • كيفية تثبيت Magento على GCE
  • كيفية إعداد "محاكي Spanner"
  • كيفية نقل مخطّط MySQL حالي إلى Spanner باستخدام HarbourBridge
  • التغييرات التي يجب إجراؤها لدمج تطبيقات PHP، مثل Magento، التي تستخدم MySQL كبرنامج خلفي لقاعدة البيانات مع Spanner

ما ستنشئه

يركّز هذا الدرس التطبيقي حول الترميز على دمج Magento مع Spanner. يتم توفير مجموعات الرموز وتعليمات الإعداد لتتمكّن من نسخها ولصقها، ولكن لا يتم شرحها بالتفصيل.

في هذا الدرس التطبيقي حول الترميز، ستبدأ في دمج Magento مع Spanner. عليك إجراء ما يلي:

المتطلبات

  • مشروع على السحابة الإلكترونية من Google Cloud مرتبط بحساب الفوترة.
  • يُفضّل أن يكون لديك معرفة بإعدادات PHP وLinux وApache.
  • ستكون الخبرة في Magento مفيدة، ولكنّها ليست مطلوبة.

2. إعداد مثيل GCE

إنشاء مثيل GCE

أنشئ جهاز Compute Engine افتراضيًا في Google Cloud Platform باتّباع الخطوات المذكورة هنا.

عند إنشاء مثيل GCE، غيِّر نوع المثيل إلى e2-standard-2 وحجم قرص التمهيد إلى 20 غيغابايت. يمكنك ترك كل شيء على الإعدادات التلقائية، ولكن احرص على اختيار "السماح بالزيارات من HTTP" و "السماح بالزيارات من HTTPs"، لأنّنا سنستفيد من واجهة الويب في Magento.

يؤدي ذلك إلى إنشاء نوع آلة e2-standard-2، وهو ليس مثيلاً بنواة مشتركة ويتضمّن وحدتَي معالجة مركزية افتراضيتَين وذاكرة وصول عشوائي سعتها 8 غيغابايت ومساحة تخزين على القرص تبلغ 20 غيغابايت.

نظام التشغيل هو Debian 10. قد يستغرق إنشاء الجهاز الافتراضي دقيقة أو دقيقتَين.

بعد إنشاء المفتاح، سجِّل الدخول من خلال النقر على "SSH" في Cloud Console:

4bf915ef8d37c942.png

سيؤدي ذلك إلى فتح نافذة متصفّح جديدة ونقلك إلى نافذة طرفية.

تثبيت البرامج المطلوبة

يجب تثبيت بعض البرامج الأساسية قبل أن نتمكّن من تشغيل 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 باستخدام HarbourBridge.

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
  • حسنًا

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 للتثبيت باستخدام composer:

  1. ثبِّت الإصدار 2.4.2 من Magento باستخدام Composer. يتطلّب Magento 2 الإصدار 1.x من Composer. قد تظهر لك بعض التحذيرات بشأن إيقاف الدعم لهذا الإصدار نهائيًا.
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 Console:

3947f1164e1d5409.png

لتغيير معرّف الموارد الموحّد (URI) الخاص بلوحة المشرف، استخدِم الأمر التالي لتحديد موقعه:

php bin/magento info:adminuri
  1. إيقاف ذاكرة التخزين المؤقت للصفحة الكاملة لأغراض التطوير، يمكنك إيقاف ذاكرة التخزين المؤقت للصفحة الكاملة في Magento2. سيسمح لك ذلك بتعديل البيانات في Spanner وعرضها على الموقع الإلكتروني بدون التأثّر بالقيم المخزّنة مؤقتًا.
php bin/magento cache:disable full_page

إعداد Spanner

تثبيت محاكي Spanner

توفّر Cloud SDK محاكيًا محليًا في الذاكرة، يمكنك استخدامه لتطوير تطبيقاتك واختبارها مجانًا بدون إنشاء مشروع على Google Cloud Platform أو حساب فوترة. بما أنّ المحاكي يخزّن البيانات في الذاكرة فقط، يتم فقدان كل الحالات، بما في ذلك البيانات والمخطط والإعدادات، عند إعادة التشغيل. يوفّر المحاكي واجهات برمجة التطبيقات نفسها التي توفّرها خدمة Spanner الإنتاجية، وهو مخصّص للتطوير والاختبار على الجهاز المحلي، وليس لعمليات النشر في بيئة الإنتاج.

يُرجى استخدام الرابط أدناه للرجوع إلى مزيد من المعلومات حول تثبيت المحاكي واستخدامه ونشره:

استخدام Spanner Emulator

# 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 جديدة يتم ملؤها بالبيانات من قاعدة البيانات المصدر، وتُنشئ تقرير تقييم تفصيليًا. تم تصميم HarbourBridge لتحميل قواعد بيانات يصل حجمها إلى بضع عشرات من غيغابايت لأغراض التقييم، وليس لعمليات نقل البيانات على نطاق واسع.

تساعدك أداة HarbourBridge في بدء عملية نقل البيانات إلى Spanner في مراحلها الأولى من خلال استخدام قاعدة بيانات مصدر MySQL أو PostgreSQL حالية لتتمكّن من بدء استخدام 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
  • التحقّق من أنّ تفاصيل Catalog يتم ملؤها من Spanner

استنساخ نسخة معدَّلة من مشروع Magento

استنسِخ الرمز البرمجي لتطبيق PHP الخاص بمنصة Magento والذي يتضمّن التعديلات على وحدات "الكتالوج" و"قائمة الأمنيات" و"سلة التسوّق" من عنوان URL الخاص بـ Git المذكور أدناه.

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

يجب أن يبدو الدليل الرئيسي على النحو التالي:

$ ls
go  harbourbridge  magento-spanner-port  magento2

حيث magento2 هو قاعدة الرموز التي سنعدّلها باستخدام الرموز من magento-spanner-port.

تغيير عملية الربط إلى Spanner

للتحقّق مما إذا كانت تعديلات الرمز البرمجي تظهر في واجهة المستخدم، يمكننا اتّباع الخطوات التالية:

يُرجى الرجوع إلى رابط Github https://github.com/searceinc/magento-spanner-port للاطّلاع على نموذج التنفيذ.

  • تتطلّب مكتبة عميل PHP الخاصة بـ google/cloud-spanner
  • أضِف Spanner Adapter لإنشاء اتصال بـ Spanner.
  • اضبط معلومات مثيل Spanner والخادم.
  • أضِف SpannerInterface وSpanner في المحوّل لتنفيذ عملية الربط بـ Spanner.

أولاً، علينا تثبيت مكتبة PHP الخاصة بـ Cloud Spanner باستخدام Composer. في دليل magento2، شغِّل الأمر التالي:

cd ~/magento2
composer require google/cloud-spanner

بعد ذلك، نضيف ملفات Spanner Adapter من magento-spanner-port إلى قاعدة رموز 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 Adapter. أضِف الأسطر الخضراء بعد الأسطر البيضاء في الملف. راجِع 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 واسترداد البيانات منه. استبدِل الخط الأحمر بالخطوط الخضراء.

يُرجى الرجوع إلى /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);

...

التحقّق من أنّ تفاصيل Catalog يتم ملؤها من 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.

تنظيف

بعد اكتمال عملية إعداد إثبات المفهوم والتحقّق من صحته، قد تحتاج إلى حذف موارد Google Cloud Platform التي تم إنشاؤها أثناء العملية. سيشمل ذلك جهاز Compute Engine الظاهري، بالإضافة إلى مثيل Cloud Spanner إذا قررت استخدام أحدهما بدلاً من المحاكي.

ما هي الخطوات التالية؟

هذا مجرد نموذج أولي لإثبات صحة المفهوم في Spanner.

إذا أردت معرفة المزيد حول استخدام Spanner والتكنولوجيات التي استفدنا منها في هذا الدرس التطبيقي حول الترميز، إليك بعض المراجع الإضافية: