新しいコードをライブでデプロイする


29

ライブ(eコマース)サイトに新しいコードを展開するためのベストプラクティスは何ですか?

今のところ、ディレクトリの名前をに変更public_html_newpublic_html、古いものに変更するとき、apacheを+/- 10秒間停止しましたpublic_html_old。これにより、Apacheを再び起動する前に短いダウンタイムが発生します。

Gitを使用して新しいリポジトリをライブディレクトリにプルする場合、同じ質問があります。サイトがアクティブな間にレポジトリをプルできますか?また、DBもコピーする必要がある場合はどうでしょうか。

ライブサイトのtar(バックアップ目的)圧縮中に、メディアディレクトリで変更が発生したことに気付きました。それは、ファイルが定期的に変化し続けることを私に示しました。また、Apacheがデプロイメント中に停止されない場合、これらの変更が干渉する可能性がある場合。

回答:


13

ロードバランサーを使用することをお勧めします。サイトが数秒のダウンタイムを心配するほど重要である場合、フォールトトレランスを心配するのに十分重要です。

それはさておき、これが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リスンバックログに関連するOS設定を確認してください。

httpd.confのDocumentRootを変更し、グレースフルリスタート(apachectl graceful)を実行することもできます。ここでの欠点は、Directory構成の更新も必要になるため、エラーのリスクが高くなることです。


これで一時停止セッションはまだサイトを実行していますか?
nicoX 14

4
ApacheへのCPU時間の提供を停止します。Apacheが一時停止しているときにブラウザーでサイトにアクセスしようとすると、Apacheが再開されるまで(または、Apacheがタイムアウト期間より長く一時停止されるとブラウザーがタイムアウトするまで)、ブラウザーは接続を待機します。誰かがファイルをダウンロード中の場合、ApacheはCPU時間を取得していないため、一時停止中にデータの送信を停止します。繰り返しますが、これは、Apacheが長時間停止して転送がタイムアウトした場合にのみ問題を引き起こします。
GargantuChet 14

5
別の言い方をすれば、Apacheが一時停止している間、サイトは応答しなくなりますが、保留中の操作は再開されると終了します。ユーザーは「接続拒否」を取得せず、ダウンロードは中断しませんが、操作はApacheが再開されたときにのみ継続します。これにより、既存のトランザクションを終了できますが、新しいリクエストが処理されるのは、新しいコンテンツが所定の場所に移動した後のみです。
GargantuChet

1
トラフィックの多いWebサイトでは、これによりApacheサービスが非常に簡単に停止する可能性があることに注意してください。200 rq / sは、移動後にApacheプロセスを「ロック解除」
すると

1
トラフィックの多いサイトでは、Apacheが再開されたときに完了する多数の処理中のリクエストがあります。これにより、新しいリクエストの処理がずらされます。また、Apacheの設定(スレッド/サーバー/クライアントの最大数)が適切であることを確認し、それに応じてTCPバックログを調整するための適切な引数です。あなたがサービスを「殺す」ことの意味について私は混乱していますが。Apacheは非常に調整可能です。
GargantuChet

32

最速かつ最も簡単な方法は、次のようなバージョンディレクトリを使用することです

/var/www/version/01
/var/www/version/02

html_rootとして現在のシンボリックリンクを使用します。

/var/www/html -> /var/www/version/02

この手法は、 、ブランチとタグをチェックアウトし、シンボリックリンクを変更し、Apacheをリロードできるリビジョン管理システム(svn、git、mercurialなど)れます。ダウンタイムは最小限で、この技術を使用して、それが可能に非常に簡単にロールバック

また、RPMパッケージや構成変更管理(chef、puppetなど)インフラストラクチャなど、より複雑な展開システムともうまく統合されます。


4
最も単純な解決策が常に最良です... :-)もちろん、設定にいくつかのFollowSymlinksおよびそのようなApacheフラグが必要になる可能性があることを忘れないでください。
ペテルは、モニカを復元する

@PeterHorvathの発言には特に注意してください。Apacheは、シンボリックリンクされたDocumentRootsを操作するときに非常に不機嫌になることがあります。慎重にテストしてください!
mhutter

おかげ@mhutter :-)本当に問題にどのようなことはapacheの上ではFollowSymLinksを有効にすると、セキュリティ上の問題を引き起こすことができるということです...
peterhはREINSTATEモニカ言う

シンボリックリンクの更新は、アトミック操作ではありません。ln -snf元のシンボリックリンクを破壊するようなものを使用しても、基になる操作はunlinkand symlinkです。更新中にユーザーが404を取得する可能性があります。これは、邪魔にならないように元のディレクトリの名前を変更し、新しいディレクトリを所定の場所に変更する(ファイルシステムを越えていないことを前提とする)ことよりも優れています。この懸念に対処するチェックマークが付いた上記の回答を参照してください。
GargantuChet

14

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.renamepythonから、またはrenameスマートにしようとせずにシステムコールを呼び出す他の何かを使用して行うことができます。

データベースで何をするかは、使用しているデータベース、および使用するデータベースによって異なります。質問のその部分に対する適切な回答を提供する前に、データベースに関する詳細を提供する必要があります。


1
私のDebianシステムにmv-T、シンボリックリンクをたどらないようにするオプションがあります。これにより、両方がソフトリンクであると仮定しpublic_html.newpublic_html、アトミックに名前を変更できます。
GargantuChet

11

Symlinksとmvは友達ですが、エンドユーザーが新しいバージョンのデプロイ中にエラーページを表示しないようにする必要がある場合は、少なくとも2台のバックエンドサーバーの前にリバースプロキシまたはロードバランサーが必要です(apacheあなたの場合)。

デプロイ中に、一度に1つのバックエンドを停止し、新しいコードをデプロイし、それを再起動して、残りのバックエンドで繰り返すだけです。

エンドユーザーは常にプロキシによって適切なバックエンドに誘導されます。


4
あなたがすでに投稿したのを見たとき、私はちょうどこの答えに取り組んでいました。バランサ+ 2台のサーバーが...悪いアップグレードから回復するプロセスは見えないし、簡単になります
バートSilverstrim

9

運用システムに定期的に変更を適用する場合は、構造化されたライフサイクルを処理します。カピストラーノhttp://capistranorb.com/をお勧めします。これは、複数のプラットフォームと構成の1つ以上のサーバーにソフトウェアを展開するためのオープンソースソリューションです。

Magentoにはプラグインもあります:https : //github.com/augustash/capistrano-ash/wiki/Magento-Example

単一サーバーおよびほぼシームレスな移行の場合、シンボリックリンクを使用することをお勧めします。


4

私が行う方法は、ローカルの開発環境からGithubなどのオンラインGitリポジトリに変更をコミットすることです。私の実稼働環境はリモートリポジトリから実行さgit pullれるため、サーバーにssh し、最新の変更を反映するために実行するだけです。ウェブサーバーを停止する必要はありません。

プロジェクトにファイルがあり、設定やコンテンツがローカルバージョンと異なる場合(構成ファイルやメディアアップロードなど)、環境変数を使用したり、これらのファイル/ディレクトリをファイルに追加.gitignoreして、リポジトリとの同期を防ぐことができます。


3

私の最初のアイデアは:

# 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)--bindpublic_html_newをpublic_htmlにマウントします:

mount --bind /path/to/public_html_new /path/to/public_html

この時点から、Apacheは新しいデプロイメントを確認します。404の変更は不可能です。

(3)rsyncとのシンクロナイゼーションを行います、代替マウントポイントで行います):

rsync -vaH --delete /mnt/tmp/path/to/public_html_new/ /mnt/tmp/path/to/public_html/

(4)バインドマウントを削除する

umount /path/to/public_html

このコマンドはpublic_htmlを削除し、public_html_newをそこにデプロイしますか?
nicoX 14

@nicoXいいえ、変更のみをコピーします。
ペテルはモニカを復活させると

@nicoX 両方のディレクトリ構造を調べ、違い(新しいファイル、変更されたファイル、削除されたファイル)が見つかった場合、必要に応じて2番目のディレクトリを最初のディレクトリと一致するように変更します。あなたはpublic_htmlのを削除して、その場所にpublic_html_new移動、場合、結果が、一時的に404の問題の可能性なし。
ペテルはモニカを復活させると

1
いいえ、これは良い考えではありません。変更内容によっては、コードがpublic_html矛盾した状態になる時間が短い場合があり、この機会を利用したくない場合があります。
スヴェン

@SvWあなたは正しいです。私の考えは、わずかな変更しかなければ大丈夫です。それに応じて答えを拡張しました。
ペテルはモニカを復活させる

1

http_publicフォルダの移動/置換は、シンプルmvまたはln -s HTTPサーバーが稼働し続けながらコマンドまたは同等。いくつかのスクリプトを実行してダウンタイムを大幅に削減できますが、プロセスを自動化する場合は、スクリプト内のコマンドのリターンコードを慎重に確認してください。

ただし、ダウンタイムを発生させたくない場合は、アプリケーションもそれをサポートする必要があり。ほとんどのアプリケーションは、永続性のためにデータベースを使用します。アプリケーションのバージョンNがデータモデルのバージョンN + 1(またはその逆)を台無しにすると、開発チームが予見していなければ問題が発生する可能性があります。

経験から、アップグレードを通じてこのような一貫性を維持することは、ほとんどのアプリケーションでは与えられていません。ダウンタイムにもかかわらず、適切なシャットダウンは、一貫性の問題を回避するための良い方法です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.