BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ アーティクル モノリスからマイクロサービスへのマイグレーションで学んだ7つの教訓

モノリスからマイクロサービスへのマイグレーションで学んだ7つの教訓

キーポイント

  • Even in 2020, there’s a good chance that you’re still working with at least one legacy system. If so, you’re probably thinking about whether to migrate to a microservices architecture. 
  • In some cases, it’s better to skip the migration -- for example, if most of your development is happening in new systems anyway and few devs ever have to interact with the legacy code.
  • Because of the overall complexity and difficulty with making sound estimates, it’s usually not a good idea to make a refactor an official "project" with a defined start and end date. But you’ll still need top-down buy-in for the effort, and you’ll need to schedule work so that you can make consistent progress.
  • If they don’t already exist, writing automated tests before the refactor is one of the best things you can do to ease the process and be sure your new system behaves the way it’s supposed to.
  • Stick to known patterns as you build your known system, and resist the urge to go straight to the bleeding edge. Pioneering a brand new approach to microservices is expensive, and the refactor will keep you busy enough. 
     

原文(投稿日:2020/10/21)へのリンク

ここ何年間、私は、モノリシックなレガシシステムからマイクロサービスアーキテクチャへの移行開発にいくつか参加したり、あるいは間近で見たりしてきました。苦い経験を何度もしましたが、たくさんの落とし穴や課題について学ぶことができました。ある開発案件では、個人的にかなりの額の損害を被ることになって、おそらくは関係した企業が倒産する大きな要因にもなりました。ここで詳しくは説明しませんが、他の方々に同じ経験をさせたくないのは間違いありません。

そこで今回は、私が学んだ教訓の中からいくつかを選んで紹介することで、リファクタリングという過酷な土地を越えるマイグレーションの旅が、可能な限り成功を収められることを祈りたいと思っています。この話題に関しては、すでに多くのことが語られていますが、事前に誰かが教えていてくれたなら、と私自身が思ったものや、これまで紹介されていないようなものもいくつかあります。

私はGardenという会社の共同創業者です。会社では、開発者によるクラウドネイティブなマイクロサービスアプリケーションのテスト、レビュー、トラブルシュートを支援しています(当社のプロダクトは — もちろん — オープンソースです。興味をお持ちならばこちらをご覧ください)。ですから、まさにこの移行プロセスの真っ只中にあるユーザとの開発作業に多くの時間を費やしています。さらに、これらのやり取りを通じて、共有する価値があると思われるような、いくつかの重要な教訓を学んでいます。

本当のことを言いましょう。2020年の現在においても、大部分ではないとしても、多くの成熟した事業がいまだレガシシステムを運用しています。これらはミッションクリティカルではあるものの、拡張性や運用性、保守性において、ますます多くの問題を抱え込んでいます。多くの責務を持ちすぎて複雑化した多機能システムも珍しくありません。こうしたシステムはモノリス(monolith)と呼ばれています。現在ではこの言葉は、最新の開発アーキテクチャに従わない、拡張性に関する要件を満足していない、および/あるいは、組織構造にマッチしないシステムと同義語になっています。強く結合したひとつのコードベース上で作業する人の数が多過ぎると、重大なボトルネックが発生して開発速度が低下する可能性があります。さらに、結合の強さは信頼性や拡張性の問題も引き起こします。

ですから、マイクロサービスアーキテクチャへの移行を検討するのは、間違いなく理に適ったことなのです。ここでいくつか、次のステップを検討し計画する上で考慮すべき点をご紹介したいと思います。アドバイスのナンバーワンから始めましょう。

#1 やめた方がよいかも知れない

真面目な話です。本当にモノリスを分割する必要があるのか十分に検討した上で、もし実行するのならば、正しい理由で行うようにしてください。リファクタにはよい面がたくさんありますが、ここでは、それを回避することが可能な、あるいは回避すべき兆候をいくつか紹介しましょう。

  •  機能開発の大部分がすでに新システム上で行われている場合。開発速度には問題ないと思われますし、レガシシステムが担当しているのはイテレーションを必要としない部分に限られているからです。
  • システムが必要な拡張性を確保できている場合。最新ではないにしても、現時点(および直近)の負荷を処理することはまだ可能でしょう。一般的にモノリスは、内部的にネットワークや高レベルAPIに依存していないため、実は極めて効率的なのです。
  • 作業に必要な開発者を確保できていない場合。これが起こり得るのは、ひとつのチームが担当する場合や、作業するための大規模な組織が存在しない場合です。開発パイプラインがオーバーロードになり、プロセスにボトルネックが発生する可能性があります。
  • 実は非常に優れた設計がされている場合。モノリシックなシステムはその複雑ゆえに、スパゲッティボール(balls of spaghetti)構造になったり、さまざまなパーツが緊密に結合したり、理解が困難になる傾向があります。ですが、これら一般的なトラップを避けて、現在まで優れた構造を維持することができている可能性もあります。

当然ながら、これら4つのすべてに肯首できるのであれば、結論は明らかです。止めておきましょう。マイクロサービスは将来的なプロジェクトで検討することにして、現実のビジネス問題に集中し、今の堅牢なシステムでそれを実現してください。

とは言っても、そんな人はこの記事を読まないでしょうし、そもそもリファクタリングを検討することもないはずです。現実は複雑です。おそらくはこの中の0~3つのポイントが、あなたの状況にマッチしていると思います。もし0ならば、選択肢は多くありません。その中から何かを選んで、判断を下す必要があります。適切な理由は他にもあるかも知れません。

抱えている課題と移行のコストを比較して、検討する必要があります。コストの見積もりには、少なくと以下のものを含めなくてはなりません。

  • 開発時間の費用これは当然ですが、見積が難しい場合も少なくありません。
  • 新規開発に時間投資しなかった場合の機会費用これは見落とされたり、あるいは過大評価されることがよくあります。あなたのビジネスには競合相手がいるのですから、前進しないことに費やす時間については慎重に検討する必要があります。
  • 新しいツールやプロセスの費用特に既存の完成したマイクロサービスアーキテクチャがない場合には、新たな方法論やツーリング、投資の必要なインフラストラクチャに関するコストを考慮する必要があります。

これらすべての要素を考慮して見積した上で、それを3倍することで、関連するすべての不確実性を考慮に入れておきます。
その結果があなたの頭痛の種より少ないのであれば、先へ進みましょう。確信が持てないようであれば、次に述べるアドバイスが、努力する価値があるかどうかの判断に役立つかも知れません。

#2 プロジェクトにしない

これには説明が必要かも知れません。ここでプロジェクトと言っているのは、スケジュールや計画を立てたり、何週間もの開発時間を割り当てたりすることです。つまり、中断することなく、継続的に作業できるような、開始と計画上の終了日のあるものです。マイグレーション全体をひとつのプロジェクトにして、プロジェクトの完了を目標にすることは、技術的負債に対して一般的に見られる誤った対応のひとつです。

それにはいくつかの理由があります。

  1. まず、ほとんどの場合において、組織の時間の一部をブロックして、この技術的負債プロジェクトの作業に割り当てることになります。チームが以前から解決すべきだと考えていた技術的問題に取り組むというのは、プロジェクトとしてはやりがいを感じるかも知れません。しかしこれは、プロジェクトに参加する人たちを開発中の業務から切り離すことになる上に、組織内の他の人たちとは違う目標を持つことが軋轢を生む可能性もあります。
  2. とは言え、組織全体がこのプロジェクトに取り掛かってしまうと、ユーザや顧客の立場からは、すべての開発が停止ないしスローダウンすることになります。さらには、キッチンに入る料理人の数が多すぎて、モノリスがすでに抱えているボトルネック問題を悪化させることにもなりかねません。最終的な問題は、新規開発のスローダウンという形で現れます。なぜなら ...
  3. 当初想定した以上の時間がかかるからです。あるいはチームが — 経験を積んだ優秀なエンジニアであっても — 想定した以上に、です。リファクタリングプロジェクトの本当の複雑さを過小評価する、という罠に陥るのは容易いことです。高レベルのアーキテクチャに注意を取られて、時間とともにコード内に組み込まれていった些細なロジックや小さなニュアンスを見落とすというのもよくある話です。

プロジェクトにはせず、継続的な活動として取り組むことをお勧めします。継続的な活動にはタイムラインは必要ありませんし、他のプロジェクトをブロックすることもないので、この違いは重要です。それはむしろ、ビジネス目標のひとつなのです。

#3 全力で取り組む

成果を上げるには、しかしながら、活動に全力を傾ける必要があります。自分の作業を優先して、先延ばしを繰り返してはなりません。全力で取り組むというのは、組織に働きかけて、活動に対する文化的なサポートを取り付ける、ということです。

ミーティングで肯定的な反応を得て、力強く開始した活動が、次のスプリント、週、四半期の中で、他の作業に優先順位で敗れて却下されることはよくあります。日々のビジネスで重要なものは、緊急性の高いものに打ち負かされることが多々あります。終わりのない緊急のパレードに押し流されないためには、太鼓を叩き続けなければならないでしょう。
組織がこの活動へのコミットを続けてくれるようにするためにできることを、いくつか挙げてみました。

  • 時間を掛けて必要な作業を調査し、明確に定義された目標を持った、管理可能かつ自己完結型の部分に分割しましょう。こうすることで、他のプロジェクトとの並行的な実施が容易になると同時に、各ステップでのリスクを軽減することができます。
  • 管理層のサポートを必ず取り付けて — そのモノリスが組織の中核であるならば — 戦略的優先度を獲得するようにしてください。管理層にはメリットと共に、作業を回避した場合に被る影響を理解してもらう必要があります。多くの場合において、スケールアップ時の悲惨な問題発生や、生産性の低下を — まだそうなっていなければ — 未然に防ぐことができるはずです。その文脈で説明すれば、継続的なリファクタリング活動はそれほど悪くないように聞こえるかも知れません。
  • 進捗をデモしましょう。作業を管理可能なチャンクに区分すれば、それぞれのパーツが完了しているかどうか分かるようになるはずです。これはチームにやる気を起こさせる(チェックボックスをオンにして"完了"の列に移すのは気分がよいものです!)と同時に、リファクタリングが終わりのない作業だと感じて幻滅する可能性を回避できます。

#4 テストを書く

レガシシステムに限らず、どのシステムにおいても、自動テストが欠けているというのは一般的であって、完全に普通の状態です。十分なテストがすでに実装されているコードをリファクタリングする喜びを感じているのならば、こんな素晴らしいことはありません。作業がスムーズに進むので、問題の所在にさえ気付かないかも知れません。

自動テストがなければ、新しいコードが以前のコードと同じジョブを行っているかどうか、評価することが非常に難しくなります。このことは、実際にコードを(おそらくは新しいプログラム言語で)実際に書き直す場合にも、古いコードを移動させるだけの場合にも当てはまります。ちょっとしたコードのリファクタであっても、経験の深い開発者が関与したとしても、小さな問題や不一致は発生するものです。

現状のテストカバレッジがよいとは思えないものであれば、まずはこの問題に対処しましょう。よいテストを書くことは、作業を劇的に容易にすると同時に、コードベースやその構造、細部、特異性をより理解する(確実に見つけることのできる)優れた手段でもあります。

すでに多数のテストがあるならば、それらを詳細に調べて、何がカバーされているのかを確認しておきましょう。システムを外部 — 例えばAPIレベル — からテストしているか、あるいは内部コードのみがテスト対象なのか?後者(基本的にはユニットテスト)は、それはそれで重要ですが、コードを分割して移動させる場合にはあまり価値のないものになります。内部の実装内容を仮定しない、優れたインテグレーションテストやエンドツーエンドテストは、システムの現状を維持することを可能にし、移行作業におけるベンチマークとして使用することができます。

#5 徐々にプロキシへと移行する

これには2つのアドバイスが含まれています。ひとつは、分割を漸進的に進める、ということです。大々的なマイグレーションを実施してスイッチを切り替えれば、すべてが素晴らしく動作する、などとは思いこまないでください。単にリスクが高過ぎます。ホットスポットがどこにあるのか、最大のボトルネックやその他の課題は何かを見つけ出して、最初にそれらをひとつずつ取り除きましょう。ふたつめは、おそらくはオプションであって、常に適用可能とは限らないのですが、モノリスを新しいサービスのフロントエンドとして、可能な限り長く置いておくことを強くお勧めします。この方法では、ユーザ/コンシューマに関する限りにおいて同じインターフェースを維持できるというメリットに加えて、プロセス全体を通じて同じインテグレーションテストとエンドツーエンドエストを維持することが可能になります。

もうひとつの賢明な策は、最初にプロキシを作ってモノリスをその背後に配置しておいた上で、ルーティングによってさまざまなサービスを取り外したり、あるいは新しいものを追加したりする、という方法です。どちらもほぼ同じ方法ですので、どちらが最善であるかは現在のシステムの状況や目標とする方向によって決まります。また、どちらのケースでも、ユーザが知ることなく、あるいは気にかけることなく、モノリスの各部分を徐々に移行することができるというメリットがあります。

これによって、新たに構築したサービスに機能を移行した場合でも、リファクタ期間を通じて — おそらくはその後もしばらく — モノリスが存在して、新サービスのファサードあるいはファサードの背後のプロキシという形で機能を提供することが可能になるのです。

#6 既知のパターンを用いる

レガシを離れて、最先端へと移行したくなるかも知れません。その気持ちは理解できます。近いうちにまたリファクタをしなくても済むように、今度は将来も使い続けられるようにしたいとも思うでしょう。

しかし私は、この点に関して注意を促すとともに、確立したルートを取ることをお勧めします。そうしなければ、結果として二兎を追うことになり、また新たな兎の穴に落ち込む可能性があるからです。ほとんどの企業には、新たなテクノロジのパイオニアになる余裕はありません。そういったことは、ビジネス上のクリティカルパス以外で実行しようという企業が大部分です。同じような理由から、同じプロセス内で新たな言語での書き直し — Python 2から3への移行のような、無難に思えるものであったとしても — を行うことは避けるべきだ、というアドバイスも多くの場合において成り立ちます。作業を進める上で何らかの動作の違いが生じた場合、デバッグが難しくなることが確実だからです。

それから、何をするにしても、マイクロサービスや他のものを行うための、まったく新しい手法を発明しようなどとは思わないことです。自分の抱えている問題に対して、既存のソリューションを適用するのではなく、独自のソリューションをゼロから発明する必要があると考えているのならば、おそらく止めた方がよいでしょう。すでに存在するソリューションを探したり、たずねて回ったり、組織外で問題を解決するようにしてください。

#7 ツーリングへの投資に備える

モノリシックアーキテクチャには、すべての制限を考慮した上でも、まだ本質的なメリットがいくつかあります。その中のひとつが、一般的にシンプルであるという点です。パイプラインはひとつですし、開発ツールも1セットで済みます。分散アーキテクチャの導入には、数多くの複雑性が伴います。特に初めての場合には、考慮すべき稼働部分がたくさんあります。開発環境を整えるためにツールセットを構成する必要がありますし、場合によっては(可能な限り避けるべきですが)自分たちで開発しなければなりません。さらには、それらすべてを習得するプロセスの考慮も必要になります。

マイクロサービスの運用には、モノリスの運用とは違う部分が多々あることも事実です。監視ツールへの投資も必要になります。運用に関する知識を組織内に構築するための、学習と調整の期間も計画しておかなくてはなりません。

これら運用上の違いには、技術的なものだけでなく、組織的なものもあります。多数の開発チームがそれぞれのサービスを開発し、独立的にデプロイするのであれば、コミュニケーションのチャネルや規範について再考する必要が生じる可能性があります。

それはそれで価値のあることかも知れませんが、これら"2日目の問題(day 2 problem)"に気を取られないようにしてください。

最後に

レガシシステムは私たちの生活の一部であり、それは今後も変わりません。世界はますます急速に進化しているので、私たちは何らかの技術的負債に絶えず直面することになります。開発者としての私たちは、それを存在の一部として受け入れなくてはなりません。

モノリスはそのような技術的負債の中で最も知られたもののひとつです。今現在、あなたの目の前にあるかも知れません。それは差し迫った問題かも知れませんし、そうではないかも知れませんが、もしそうならば、段階的に分解するように活動していきましょう。その際には必ず、関係者すべての賛同を得るようにしてください。

ドラゴン(隠れ機能)はいるでしょうが、賢く扱えば問題ありません。その上で、前任者の残した苦労の跡に思いを馳せましょう。安心してください、あなたひとりではないのです。

関連する技術的課題や、それらを軽減する方法については、この分野でのフォローアップ記事で取り上げていくと思いますので、ぜひ注目してください。この記事を読んだ読者のみなさんが、リファクタリングにおけるコンテナやKubernetes操作を行うツールに関心をお持ちならば、Gardenがお役に立つことと思います。

著者について

Jon Edvald氏は、オープンソースのKubernetes開発およびテスト用プラットフォームの製造企業であるGardenの共同創業者兼CEOです。10年以上にわたる開発キャリアの中で氏は、ClueやQuizUpといった企業でエンジニアリングリーダの役割を担った後、CLARA(Jive Softwareによって買収された)を共同創業し、CTOとなりました。現在は開発者エクスペリエンス、抽象化、音楽、抽象音楽(abstract music)に熱意を持っています。

 

この記事に星をつける

おすすめ度
スタイル

BT