Magento Open Source 2.4.4で追加されたBlue-Green deploymentオプションとは

リリースノートにも記載されておらず、あまり話題にもされていないのですが、Magento2.4.4でBlue-Green  deploymentに関する機能追加が行われていたようです。
今回はこのBlue-Green deploymentに関する機能の仕組みについて解説したいと思います。

Blue-Green deploymentとは

Blue-Green deploymentとは、Martin Fowler氏が提唱した情報システムの更新手法の一つです。

  • 現在の稼働環境(Blue)
  • 新しいバージョンの環境(Green)

という2種類の環境を用意し、プログラムの正常デプロイ後にBlueとGreenを入れ替えることによって、システムのダウンタイムをほぼゼロにしながらも更新作業を行うという手法です。
(詳細に書き出すとがないので、この記事ではBlue-Green  deploymentそのものについての話はココまでにしておきます)

Magento2.4.3までのデプロイの課題

2.4.3までのMagentoでは、サードパーティ製のエクステンションなどを活用しなければBlue-Green deploymentは実現できませんでした。
その理由は以下のとおりです。

  • module.xmlに定義されたsetup_version / data_versionの数字が変わると、setup:upgrade の実行が必須
  • config.phpやenv.phpにシステム設定値を定義している場合、内容の変更時には app:config:import の実行が必須

これらの処理を適切に行わない場合、ソースコードのデプロイが正しくできていても、アプリケーションがエラーを起こしてしまうのがMagentoの仕様でした。

この問題に対し、2.4.4で密かに新しい設定値が増えていたわけです。

Magento2.4.4で追加された設定値

Magento2.4.4で追加された設定値のパスは、

deployment/blue_green/enable

となっています。
このパスが追加されたことについて、Experience Leagueのリリースノートには一切の記述がありません。
では、このパラメータを使うとどのようなことができるのでしょうか?

ソースコードを検索して調べてみましょう。

deployment/blue_green/enable が使用されている箇所

Magentoのソースコードを検索すると、deployment/blue_green/enableが使用されている箇所は2箇所であることがわかります。

  • Magento\Framework\Module\Plugin\DbStatusValidator
  • Magento\Deploy\Model\Plugin\ConfigChangeDetector

それぞれの実装を確認してみましょう。

Magento\Framework\Module\Plugin\DbStatusValidator

このクラスの中で、設定値が使用されている箇所は、beforeDispatchの中です。
下記のような記述となっています。

if ($this->deploymentConfig->get(self::DEPLOYMENT_BLUE_GREEN_ENABLED)) {
    return;
}

if (!$this->cache->load('db_is_up_to_date')) {
    list($versionTooLowErrors, $versionTooHighErrors) = array_values($this->getGroupedDbVersionErrors());
    if ($versionTooHighErrors) {
        $message = 'Please update your modules: '
            . "Run \"composer install\" from the Magento root directory.\n"
            . "The following modules are outdated:\n%1";
        throw new LocalizedException(
            new Phrase($message, [implode("\n", $this->formatVersionTooHighErrors($versionTooHighErrors))])
        );
    } elseif ($versionTooLowErrors) {
        $message = 'Please upgrade your database: '
            . "Run \"bin/magento setup:upgrade\" from the Magento root directory.\n"
            . "The following modules are outdated:\n%1";

        throw new LocalizedException(
            new Phrase($message, [implode("\n", $this->formatVersionTooLowErrors($versionTooLowErrors))])
        );
    } else {
        $this->cache->save('true', 'db_is_up_to_date');
    }
}

この処理では、データベースの状態が最新でなければエラーを返すという判断をしています。
2.3系以降ではdeclarative schemaが導入されたため、module.xmlのバージョン番号定義は必須ではなくなりましたが、今でもモジュール毎のスキーマやデータバージョン管理用に残されています。

もし、deployment/blue_green/enable に1を指定した場合は、前述の条件式が成立することになるので、以前から実装されていたチェック処理は動かなくなります。
つまり、データベースの状態に関わりなく、Magentoは動作することになります。

Magento\Deploy\Model\Plugin\ConfigChangeDetector

このクラスでも先程と同様に、beforeDispatchの中で設定値が利用されています。
下記のような記述ですね。

if (!$this->deploymentConfig->get(self::DEPLOYMENT_BLUE_GREEN_ENABLED)
    && $this->changeDetector->hasChanges()
) {
    throw new LocalizedException(
        __(
            'The configuration file has changed.'
            . ' Run the "app:config:import" or the "setup:upgrade" command to synchronize the configuration.'
        )
    );
}

こちらの場合は、設定値に変更が生じていた場合にエラーを出すものですが、Blue-Green deploymentが有効な場合はエラーが出ません。

結局この設定値は何をしているのか?

要はこの設定値はここまで解説してきた通り、

有効な場合に本来エラーとなるべき挙動を抑制する

というものです。
Blue-Green deploymentを行う場合に重要な要素としては、

新バージョン(Green)のデプロイが正しく完了してから、現行バージョン(Blue)との切り替えを行う

というものがあります。
しかしここにはデータベースや各種設定値の話は含まれていません。
MagentoでBlue-Green deploymentが有効な場合は、データベースや設定値の反映が行われないので、何らかの形で手動反映する必要があります。

Blue-Green deploymentを行う際に気をつけること

ここからはBlue-Green deploymentを行う際にMagentoで気をつけることについて取り上げていきたいと思います。

新しいエクステンションをインストールする場合や、既存のエクステンションをアップデートした際には、これまで存在しなかったテーブルや列がデータベースに作成されることがあります。
Blue-Green deploymentをしない場合であれば、ソースコードのデプロイ後に遅滞なくsetup:upgradeやconfig:importを行う必要があります。
しかし先程も書いた通り、Blue-Green deploymentが有効な場合は、データベース定義(データ定義も)が最新でなくともMagentoは動作しようとします。
存在しないテーブルに対するデータベース問い合わせが行われた場合、

TableNotFoundException

が発生します。
列の場合は単純にクエリエラーになります。これらの対処がBlue-Green deploymentを始める前に必要です。
なお、この対応はサードパーティ製エクステンションや独自実装のエクステンションだけでなく、Magentoのコア実装も同様です。

2023年8月時点の安定版である、2.4.6でTableNotFoundExceptionを判断材料に用いて制御を行っている箇所は非常に限定的です。
ですからBlue-Green deploymentを今すぐに利用できるか?と言われればかなり疑問符をつけざるを得ない状況であるのは間違いありません。
とはいえ、これまでエクステンションでしかBlue-Green deploymentを実現する方法がなかったMagentoにおいて、2.4.4でひっそりと追加されたこの設定値は小さくても大きな進歩であることは間違いないですね。