オーストラリアの大規模なゲームサイトを手伝っています。毎日午前7時から翌日の午前1時まで、毎日競技を行っています。サイトが公開されて以来、1日もスキップしていません。当然、これによりメンテナンスの実行が非常に困難になり、ステージングサーバーが本番ブランチよりも最大50コミット多いことがわかります。通常、メインの開発者はブランチをマージしてすべてが適切に機能していることを確認するために、非常に早く目を覚ます必要があります。
ステージングサイトを本番サイトにできる限り類似させるように努めていますが、類似させることしかできません。
私たちのサイトは、LaravelリアルタイムのNode.JSサーバーを使用しています。Laravel Forgeを使用しています。
更新をより頻繁にプッシュする方法について何か提案はありますか?私たちは何にでもオープンです。
展開プロセスを改善するためにできることはたくさんあります。それらのいくつかは次のとおりです。
コードが十分にテストされていることを確認します。
理想的には、100%の単体テストカバレッジと、考えられるすべてのシナリオの統合テストが必要です。
これをお持ちでない場合は、おそらくすべてを削除して、これを処理する必要があります。
振る舞い主導の開発を調べてください。
完全なテストスイートがあると、次のことが可能になります...
継続的インテグレーションを実行します。
誰かが変更をコミットすると、CIは自動的にでテストスイートを実行できます。テストスイートに合格すると、すぐに展開できます(または展開をスケジュールできます)。データベースへの大きな変更を必要としない変更の場合、これだけで多くの時間と頭痛を節約できます。
問題が発生した場合、CIはワンクリックのロールバックも提供します。
CIはmuchテストスイートが完全で正確でない場合、前提全体が自動化された方法でコードを検証できることに依存するため、あまり役に立ちません。
アトミック更新を行います。
理想的には、運用サーバー上の古いファイルの上に新しいファイルをコピーするだけではいけません。代わりに、capistranoなどのツールを使用して、すべてのファイルを新しい場所にコピーし、シンボリックリンクを使用して目的のデプロイメントをポイントします。以前の展開を指すようにシンボリックリンクを変更するだけなので、ロールバックは瞬時に行われます。 (ただし、これは必ずしもデータベースの移行をカバーしているわけではありません。)
また、Dockerなどのコンテナーが役立つかどうかも確認してください。
より小さく、より頻繁な変更を行います。
テスト、CI、または何もない場合でも、これだけで大幅に役立ちます。すべての変更には独自のgitブランチが必要であり、デプロイメントには変更をできるだけ少なくする必要があります。変更が小さいため、展開中に問題が発生する可能性が少なくなります。
その点に注意して、可能な限り変更を分離してください。オマハのゲームに変更を加え、それがテキサスホールデム、5カードスタッドなどに影響を与えない場合、メンテナンスのために中断する必要があるのはそれだけです。
長時間実行されているものを分析します。
デプロイメントの一部に時間がかかるとのことですが、これはおそらくデータベーススキーマの変更です。 DBAに各スキーマの変更とともにデータベースを見てもらい、何がより良いパフォーマンスを発揮できるかを確認することは価値があります。
主題の専門家に、大規模な時間を必要とする展開の他の部分を調べてもらいます。
奇数時間働きます。
あなたはすでにこれをしているかもしれませんが、それは言及に値します。開発者(およびsysadmins!)は、特に24時間年中無休の操作では、「9から5」で動作することはもうありません。誰かがデプロイメントにベビーシッターをして夜間時間を費やして問題を修正し、日中のスケジュールを維持すると予想される場合、期待は現実的ではなく、その人を燃え尽きようとしています。
毎日午前1時から午前7時までメンテナンスウィンドウがあるとのことですが、問題は時間ではなく便利です。これは正常なことであり、多くの人々はビジネスの一部としてそれを扱います。
現在稼働している方にトラフィックを転送するフロントエンドを備えた2つ(またはそれ以上のバックエンド)システムを使用できます。リリースがうまくいくことに満足したら、フロントエンドに新しいシステムに切り替えるように指示します。これは短時間で簡単にスクリプト化できるはずです。
これで、古いシステムをそのままにするか、元に戻すか、最新の状態にして、次の更新をビルド/テストするまでライブシステムのスペアとして使用できるようになりました。
他の回答の修正:blue-green配置モデルに従う必要があります。新しいバージョンをリリースする場合は、内部ステージングWebサイトに展開します。その後、次のバージョンの本番サイトで自動テストを実行できます。テストが完了すると、ロードバランサーが新しいWebサイトを使用するように指定されます。
これは次のように役立ちます。
あなたや他の人が述べた他のすべての問題は、いつでもストレスのない方法で展開できる場合、それほど深刻ではなくなります。青緑色の展開モデルは、展開の問題に対する完全なソリューションです。
メインのデータセンターで障害が発生し、すべてのデータセンターで時々発生する場合はどうしますか?ダウンタイムを受け入れたり、別のデータセンターにフェールオーバーしたり、常に複数のデータセンターでアクティブ/アクティブモードで実行したり、その他の計画を立てたりすることができます。どちらの場合でも、リリース時に行うと、リリース中にメインデータセンターを停止できます。データセンターが停止したときにダウンタイムが発生する準備ができている場合は、ダウンタイムが発生する準備ができているため、リリース中に問題が発生することはありません。
以前の回答に追加するには:
ロールバックと即時切り替えを可能にする配備戦略を使用してください。Capistranoまたは他のほとんどの配備システムがこれを支援します。データベーススナップショットやコードシンボリックリンクなどを使用して、以前の状態にすばやく戻すことができます。
完全な構成管理を使用し、手動で管理されているものを残さないでください。 SaltStack、Ansible、Puppetなどのシステムがその例です。これらは、Dockerコンテナー構成およびvagrantボックスにも適用できます。
HAを使用して、ノードをアップグレードするときにリクエストを確実に引き渡せるようにします。アップグレードが失敗した場合は、ノードをダウンし、ロールバックされたときにアップに戻すと、HAソリューションがそのノードに再度通知し、リクエストをプッシュします。 HAProxyは一例ですが、nginxも問題なく動作します。
アプリケーションが並行インスタンスを処理できることを確認し、キャッシュなどのディスクに格納する必要がある非コードデータ用の中央バージョン対応データリポジトリを使用しました。この方法では、アップグレードされたアプリケーションを実行して、異なるバージョンのファイルをキャッシュすることはありません。もちろん、これはキャッシュのパージとキャッシュのウォームアップに加えて行われます。 (キャッシングは一例です)
私は通常、ワークフローをセットアップして、チームマネージャーが通常のCIのすべてを行う特別なブランチへのマージ要求を承認できるようにしますが、追加の最後のステップとして、本番ノードへのプッシュも開始します。基本的には、本番インスタンスに手動でCIデプロイを実行します。そのインスタンスが無効な応答を生成しない、中断しない、またはデータに奇妙なことを行わない場合は、選択したCIソリューションを使用してすべてのノードを一括アップグレードします。これにより、1つのデプロイメントが機能する場合、すべてのデプロイメントが特定のタグ/コミットで機能することがわかります。
現在のところ、1つのデプロイメントプロセス、1つのソース、1つのターゲットを備えた単一のノードで本番アプリケーションを実行しているように聞こえます。これは実際には、そのワークフローのすべてのステップが、それ自体がWebサイトを破壊する可能性がある障害点であることを意味します。このようなことが起こらないようにすることは、すべてのCI、HA、およびフェイルオーバープロセスの基本です。 1つのノードだけを実行したり、1つのHAプロセスだけを実行したり、1つのIPアドレスだけで実行したり、1つのCDNだけを実行したりしないでください。高額に聞こえるかもしれませんが、すでに持っているものを複製してください独自の接続を備えたサーバー上のラックでは、通常、ビジネスサイトでのダウンタイムは1時間未満です。
私は彼のすべての点でマイケルに全体的に同意します( https://serverfault.com/a/739449/309477 )。
私の意見では、最初に行うべき改善は、デプロイメントツール(Capistrano)を使用することです。
それはあなたが平和的に展開することを可能にし、そしてすぐに新しいバージョンに切り替えることができます。何か問題が発生した場合は、現在のシンボリックリンクを作業バージョンに変更するだけで、すぐに作業バージョンに切り替えることができます。
そして、Capistranoは最初の処理がかなり高速です(テストとCIの使用を開始するのに比べて、時間の投資が大きくなります)。
次に、お金がmainの問題ではない場合は、iso-prod開発サーバーでアプリをテストしてから本番環境にデプロイする必要があります。 industrialソリューション(Ansible、Chef、Puppet)を使用してVPSインスタンスを管理します。