ライブ(eコマース)サイトに新しいコードをデプロイするためのベストプラクティスは何ですか?
今のところ、ディレクトリの名前を変更するときに、Apacheを+/- 10秒間停止しましたpublic_html_new
からpublic_html
と古いpublic_html_old
。これにより、Apacheを再起動する前に、短いダウンタイムが発生します。
Gitを使用して新しいリポジトリをライブディレクトリにプルする場合も同じ問題が発生します。サイトがアクティブな間にリポジトリをプルできますか?また、DBもコピーする必要がある場合はどうなりますか?
ライブサイトのtar(バックアップ目的)圧縮中に、メディアディレクトリで変更が発生していることに気付きました。これは、ファイルが定期的に変化し続けることを私に示しました。展開中にApacheが停止されない場合、これらの変更が干渉する可能性があります。
ロードバランサーを使用することをお勧めします。サイトが数秒のダウンタイムを心配するのに十分重要である場合、フォールトトレランスを心配するのに十分重要です。
それはさておき、これがUNIXシステム上にある場合、名前変更(またはシンボリックリンクの更新など)中にApacheを保留にすることができます。
killall -STOP httpd # Pause all httpd processes
mv public_html public_html_orig
mv public_html_new public_html
killall -CONT httpd # Resume all httpd processes
これにより、Apacheが名前変更中に新しいリクエストを受け入れないようにします。シンボリックリンクやその他のアプローチを好む場合は、同じ考え方を使用できます。
killall -STOP httpd # Pause all httpd processes
rm /var/www/html
ln -s /var/www/version/03 /var/www/html
killall -CONT httpd # Resume all httpd processes
保留中の接続またはパケットはOSのキューに入れられることに注意してください。非常にビジーなサイトの場合、httpdワーカータイプに適切な場合はListenBacklogを調整することを検討し、TCP listen backlog。に関連するOS設定を確認してください。
Httpd.confのDocumentRootを変更して、正常な再起動(apachectl graceful
)。ここでの欠点は、Directory
構成も更新する必要があるため、エラーのリスクが高まることです。
次のようなバージョンディレクトリを使用するのが最も簡単です。
/var/www/version/01
/var/www/version/02
現在のシンボリックリンクをhtml_rootとして使用します。
/var/www/html -> /var/www/version/02
この技術はリビジョンコントロールシステム(svn、git、Mercurialなど)に完全に統合されているため、ブランチとタグをチェックアウトし、シンボリックリンクを変更して、Apacheを再ロードできます。 ダウンタイムは最小限この手法を使用すると、非常に簡単なロールバックが可能になります。
また、RPMパッケージや構成変更管理(chef、puppetなど)インフラストラクチャなどのより複雑なデプロイメントシステムとうまく統合できます。
Apacheをシャットダウンせずにディレクトリの名前を変更しても機能するはずです。これにより、ウィンドウが大幅に短縮されます。 mv public_html public_html_old && mv public_html_new public_html
は、ほんの一瞬で終了するはずです。
いくつかの欠点は、このアプローチは、ウィンドウの間にまだ発生するように管理されているすべての要求に404
を提供することです。また、public_html_new
ディレクトリがない状態で上記のコマンドを実行すると、失敗し、すべてのリクエストで404
を提供するサイトが残ります。
ディレクトリでアトミックに行うことはサポートされていません。しかし、シンボリックリンクでそれを行うことができます。 public_html
という名前のディレクトリの代わりに、public_html.version-number
という名前のディレクトリと、そのディレクトリを指すpublic_html
というシンボリックリンクを用意します。これで、public_html.new-version-number
というディレクトリとpublic_html.new
という新しいシンボリックリンクを作成できます。
次に、public_html.new
の名前をpublic_html
に変更して、アトミックに切り替えることができます。 mv
はその名前変更を実行するには「高度すぎる」ことに注意してください。ただし、os.rename
from pythonまたはrename
システムコールを賢くしようとせずに。
データベースをどうするかは、使用しているデータベースと、それを何に使用しているかによって異なります。私たちはあなたの質問のその部分に良い答えを与えることができる前に、データベースについてより多くの詳細を提供する必要があります。
Symlinksとmvは友だちですが、エンドユーザーが新しいバージョンをデプロイするときにエラーページが表示されるのを本当に避ける必要がある場合は、少なくとも2つのバックエンドサーバー(Apacheあなたの場合)。
デプロイ中は、一度に1つのバックエンドを停止し、新しいコードをデプロイして再起動し、残りのバックエンドで繰り返すだけです。
エンドユーザーは常にプロキシによって適切なバックエンドに誘導されます。
プロダクションシステムに定期的に変更を適用する場合は、構造化されたライフサイクルを担当します。 Capistrano http://capistranorb.com/ をお勧めします。これは、いくつかのプラットフォームと構成の1つ以上のサーバーにソフトウェアを展開するためのオープンソースソリューションです。
Magentoにはプラグインさえあります: https://github.com/augustash/capistrano-ash/wiki/Magento-Example
単一サーバーでほぼシームレスな移行の場合、シンボリックリンクを使用することをお勧めします。
私のやり方は、私のローカル開発環境からの変更をGithubなどのオンラインGitリポジトリにコミットすることです。私の運用環境はリモートリポジトリで実行されているため、サーバーにsshしてgit pull
を実行するだけで、最新の変更が反映されます。ウェブサーバーを停止する必要はありません。
プロジェクトに設定やコンテンツがローカルバージョンと異なるファイルがある場合(構成ファイルやメディアのアップロードなど)、環境変数を使用したり、これらのファイル/ディレクトリを.gitignore
ファイルに追加して、リポジトリと同期しています。
私の最初のアイデアは:
# deploy into public_html_new, and then:
rsync -vaH --delete public_html_new/ public_html/
良い解決策はrsyncを使うことでした。実際に変更されたファイルのみが変更されました。 パスの最後のスラッシュはここで重要です。
通常、Apacheは再起動を必要としません。Javaの世界ではありません。要求に応じてすべてのphpファイルの変更をチェックし、変更時に自動的に再読み取り(および再トークン化)します。
Git pullも同様に効率的でしたが、スクリプトを作成するのは少し困難でした。もちろん、さまざまなマージ/変更検出の可能性を幅広く可能にしました。
このソリューションは、実際に大きな変更がない場合にのみシームレスに行われます-デプロイメントに大きな変更がある場合、コードが部分的に変更されるときの無視できない時間間隔があるため、少しの危険を閉じることができません一部ではありません。
大きな変更がある場合、私の提案は最初の解決策(2つの名前の変更)でした。
これは少しハードコアですが、100%アトミックソリューションです。
(1)ファイルシステムの一部を代替マウントして、magentoを実行します。
mount /dev/sdXY /mnt/tmp
(2)--bind
public_html_newのpublic_htmlへのマウント:
mount --bind /path/to/public_html_new /path/to/public_html
この時点から、Apacheに新しいデプロイメントが表示されます。 404の変更は不可能です。
(3)rsyncを使用して同期を行いますbut代替マウントポイントで):
rsync -vaH --delete /mnt/tmp/path/to/public_html_new/ /mnt/tmp/path/to/public_html/
(4)バインドマウントを削除する
umount /path/to/public_html
http_public
フォルダーの移動/置換は、単純なmv
またはln -s
コマンドまたは同等のコマンドを使用して、httpサーバーが稼働している間に実行できます。スクリプトを実行してダウンタイムを大幅に削減できますが、プロセスを自動化する場合は、スクリプト内のコマンドの戻りコードを慎重に確認してください。
とはいえ、ダウンタイムを発生させたくない場合は、applicationもサポートする必要があります。ほとんどのアプリケーションは、永続性のためにデータベースを使用します。アプリケーションのバージョンNをデータモデルのバージョンN + 1(またはその逆)で操作すると、開発チームが予見しないと、問題が発生する可能性があります。
経験上、ほとんどのアプリケーションでは、アップグレードによってそのような一貫性を維持することは想定されていません。ダウンタイムにもかかわらず、適切なシャットダウンは、一貫性の問題を回避するための良い方法です。