回答:
仕事で一般的に行うことは次のとおりです。
/www/app-2009-09-01
/www/application
/www/app-2009-09-08
/www/application
が、新しいソースを指す新しいシンボリックリンクを作成します。/www/app-2009-09-08
このプロセスはすべて、自動スクリプトを介して行われます(自動化されないのは、必要なときに起動することだけです)。これの意味は :
このシンボリックリンクの手順のもう1つの利点は、ソースの新しいバージョンを実稼働環境に配置した後でのみ壊滅的なバグに気付いた場合、更新を「ロールバック」するのが非常に簡単なことです。
もちろん、これはステージングサーバーで新しいバージョンを実稼働に移行する前にテストすることを妨げるものではありませんが、誰が知っているのか...時には、誰にも見られない本当に大きなバグがありますテスト:-(
たとえば、ステージングマシンで定期的に行われる負荷テストがないため。(「ロールバック」のことは3年で4〜5回使用されるのを見てきました。
毎回、日を救った-とウェブサイト^^)
簡単な例を次に示します。Apache構成にこのVirtualHostがあるとします。
<VirtualHost *>
ServerName example.com
DocumentRoot /www/application
<Directory /www/application>
# Whatever you might need here (this example is copy-pasted from a test server and test application ^^ )
Options Indexes FollowSymLinks MultiViews +SymLinksIfOwnerMatch
AllowOverride All
php_value error_reporting 6135
php_value short_open_tag on
</Directory>
</VirtualHost>
かなり「標準」...唯一のものは/www/application
、実際のディレクトリではありません。それは、ソースの現在のバージョンへの単なるシンボリックリンクです。
つまり、ソースをサーバーに配置したが、まだ切り替えられていない場合、次のようなものになります。
root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root 19 2009-09-08 22:08 application -> /www/app-2009-09-01
symlincが「古いバージョン」を指すことに注意してください
新しいバージョンがサーバーに完全にアップロードされたので、切り替えましょう:
root@shark:/www
# rm /www/application
root@shark:/www
# ln -s /www/app-2009-09-08 /www/application
そして、今、/www/application
ソースの新しいバージョンへのポイント:
root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root 19 2009-09-08 22:09 application -> /www/app-2009-09-08
そして、Apacheを再起動するだけです。
root@shark:/www
# /etc/init.d/apache2 restart
* Restarting web server apache2
「リンクを削除し、新しいリンクを作成し、Apacheを再起動する」という3つの手順をすばやく行う必要があります。すなわち、自動化されたスクリプトによるものであり、人間によるものではありません。
このソリューションの使用:
また、statオプションを0に設定してAPCのようなオペコードキャッシュを使用すると、ダウンタイムのリスクがさらに低くなる可能性があります。
もちろん、これは「シンプルな」バージョンです。たとえば、アップロードされたファイルがある場合は、どこかで別のシンボリックリンクを使用するか、別のVirtualHostなどを使用する必要があります...
これがより明確であることを願っています:-)
更新されたコードベースで2番目のサーバーをセットアップし、可能な限り高速に切り替えます。:-)
不可能な場合は、コードベースが数十の小さな部分に分割されていることを確認してください。その場合、ダウンタイムは、一度に1つのサブパートのみに制限されます。小さいコードブロックは簡単に交換でき、ほとんどは問題なく実行され続けます。ただし、最初にテスト環境でこれを試してください!
まず、Pascal MARTINの応答に似た方法をよく使います。
私が気に入っているもう1つの方法は、SCMを使用して新しいコードをプッシュすることです。正確なプロセスは、SCMのタイプ(git vs svn vs ...)によって異なります。svnを使用している場合、サーバーのドキュメントルートとしてチェックアウトする「オンライン」ブランチまたは「本番」ブランチを作成するのが好きです。その後、別のブランチ/タグ/トランクから新しいコードをプッシュするたびに、新しいコードを「オンライン」ブランチにコミットし、ドキュメントルートでsvn updateを実行します。これにより、サーバーにアップ/ダウンしたことと、誰がいついつ行ったかの完全な改訂ログがあるため、非常に簡単なロールバックが可能になります。また、テストボックスでその「オンライン」ブランチを簡単に実行して、プッシュしようとしているアプリを吟味することもできます。
このプロセスは、gitや他のスタイルのSCMでも同様ですが、ワークフローのスタイルに合わせてより自然に変更されています。
更新をプッシュする代わりにプル/ポーリングしたいですか?cronジョブまたは他のよりスマートなメカニズムでsvn updateを自動的に実行するだけです。
追加:このプロセスを使用して、アプリケーションがディスクに書き込んだファイルをバックアップすることもできます。cronジョブまたは他のメカニズムにsvn commitを実行させるだけです。これで、アプリケーションが作成したファイルがSCMにバックアップされ、リビジョンが記録されます(たとえば、ユーザーがディスク上のファイルを更新したが、元に戻したい場合は、古いリビジョンをプッシュするだけです)。
Pascal MARTINにも同様のアプローチを使用します。ただし、アプリの複数のバージョンを運用サーバーにアップロードする代わりに、ファイアウォールの背後にある「ビルド」を、それぞれビルド番号と日付のある個別のディレクトリに保存します。新しいバージョンをアップロードするときは、「rsync -avh --delay-updates」を含む簡単なスクリプトを使用します。「delay = updates」フラグは、すべての更新が存在するまですべて(異なる)を一時フォルダーにアップロードし、転送の最後にすべてを一度に適切なパスに移動して、アプリが半分古い新しい状態。上記の方法と同じ効果がありますが、実稼働サイトにはアプリの1つのバージョンのみを保持します(実稼働サーバーで必要不可欠なファイルのみをIMOに配置するのが最善です)。