マイクロサービスのトレードオフ

マイクロサービスのアーキテクチャスタイルがモノリシックアーキテクチャよりも優れたアプローチであるというのは、多くの開発チームが実感していることです。その一方で、生産性を低下させる重荷のようなものだと感じているチームも存在します。プラスの面もあればマイナスの面もあるという点においては、マイクロサービスも他のアーキテクチャスタイルと変わりません。具体的なコンテキストに適用する前に、これらをよく理解して、賢明な選択をする必要があります。

マイクロサービスがもたらす利点

  • 強固なモジュールの境界:マイクロサービスではモジュラー構造が強化されています。この点は、チームの規模が大きくなるほどその恩恵は増してくるでしょう。

  • 個別にデプロイ:サービスがシンプルなほどデプロイは容易です。また、マイクロサービスではそれぞれが自律的なため、不具合が起こった時にもシステムエラーに繋がる可能性は高くありません。

  • 技術の多様性:マイクロサービスでは、複数の言語、開発フレームワーク、そしてデータストレージ技術を組み合わせることが可能です。

それに対する欠点はと言うと…

  • 分散:分散システムのプログラミングは比較的困難です。この問題は、リモートな呼び出しは遅く、かつ失敗のリスクが常に存在することに起因します。

  • 最終的な整合性:分散システムでは、強い一貫性を維持するのは非常に難しいこともあり、全ての人が最終的な整合性を管理しなければなりません。

  • 運用上の複雑さ:定期的に再デプロイされる数々のサービスを管理するため、経験を積んだ運用チームが必要になります。

まとめはこちら

強固なモジュールの境界

マイクロサービスにおける大きな利点の1つ目は、強固なモジュールの境界です。これは大切ではありますが、奇妙でもあります。理論的に、マイクロサービスの方がモノリスよりも強固なモジュール境界を持つ理由はありません。

それでは、ここで言う強固なモジュール境界とはどういうことでしょうか。ソフトウェアをいくつかのモジュール(=互いに切り離されたソフトウェアのチャンク)に分けることがいいことだという点については、恐らくほとんどの人に異論はないと思います。モジュールとして動作させることにより、例えばシステムを部分的に変える必要が生じた際でも、ほとんどの場合、システムの一部のみを理解すれば変更が可能になりますし、その一部を見つけるのも難しくはありません。優れたモジュラー構造は、どのようなプログラムにとっても有用なものです。ソフトウェアのサイズが大きくなるにつれて、その重要度は飛躍的に増していきます。そしてさらに言うなら、ソフトウェアを開発するチームの規模が大きくなればなるほど、その意味合いも増してくるということです。

マイクロサービスの支持者は、すぐにコンウェイの法則(ソフトウェアシステムの構造が、それを作る組織のコミュニケーション構造を反映するという考え)を取り入れます。大きなチーム、特にそれぞれのベースが別々の場所に分かれているようなチームの場合、チーム間のコミュニケーションがチーム内に比べてより少なくて済み、より秩序立ったものとなるようソフトウェアを構築することが重要です。マイクロサービスでは、各チームが比較的、独立したユニットを担当することで、そうしたコミュニケーションパターンを実現することができます。

前述の通り、モノリシックなシステムが優れたモジュラー構造を持てないという理由はありません1。ただ、それがまれなことは多くの人が感じているところだと思います。最も一般的なアーキテクチャパターンと言えばBig Ball Of Mudで、モノリスに共通したこの運命に対する不満は、いくつかのチームをマイクロサービスへと移行させるのに十分なものだと言えるでしょう。モジュールの分割が有効なのは、モジュールの境界がモジュール間の参照の障壁となるためです。モノリシックシステムで問題なのは、その障壁をこっそりと抜けるのが大抵は容易なことで、このことは機能を素早く構築するための便利なショートカットにはなりますが、やり過ぎるとモジュラー構造が弱体化し、チームの生産性をも捨て去ることにつながりかねません。モジュールごとに個別のサービスとすることで境界はより強固になるため、ガンとも言えるような急場しのぎをかなりの割合で防ぐことが可能となります。

このカップリングの重要な側面は、永続的なデータです。マイクロサービスの鍵となる特徴の1つは分散型データ管理であることで、各サービスは独自にデータベースを管理します。もし他のサービスがそのデータベースにアクセスする場合は、そのサービスのAPIを経由しなければなりません。これによりIntegration Databases(統合データベース)は排除されます。大きなシステムにおける厄介なカップリングの主ソースがなくなるというわけです。

ちなみに、モノリスで強固なモジュール境界を作ることは不可能ではありませんが、かなりの規律を要します。同様に、マイクロサービスでもBig Ball Of Mudのような状態にはできるものの、わざと誤った方向に進むようにでもしない限りはそうはなりません。私が見る限りマイクロサービスを使えば、よりよいモジュール性を得る確率は高くなるでしょう。もしあなたがチームの統制に絶大な自信を持っている場合、前述の確率はあなたのチームの利点を減少させるものとなるかもしれません。ただ、チームの規模が大きくなり、モジュール境界を維持する重要性が増すほど、チームの統制を保つのも難しくなりますよね。

よりよいモジュール性を得る確率の高さという利点は、境界が正しく設定されない場合、障害にもなり得ます。これが、Monolith First(モノリスを最初に)という考えの、2つある主な理由のうちの1つです。早い段階でマイクロサービスに傾倒していた人々も、マイクロサービスを使うなら、それについて十分に理解することが先決だと強調しています。

注意点はこれだけではありません。システムが本当にしっかりとしたモジュール性を維持したかどうかは、ある程度時間が経つまでは分かりませんよね。少なくとも数年は稼働しているようなシステムでの実績を見て初めて、マイクロサービスが優れたモジュール性を導き出したと評価できるはずです。加えて、アーリーアダプターは有能な人が多い傾向にあるため、平均的なチームが書いたマイクロサービスシステムにおけるモジュール性の評価となると、さらに後に(時間がかかることに)なるでしょう。その時でさえ、平均的なチームが書いた平均的なソフトウェアとして受け入れる必要があるため、有能なチームと結果を比べるのではなく、平均的なチームがモノリシックアーキテクチャで書くであろうソフトウェアを想定して比較する必要があります。これは評価という点において、非常に扱いにくく反事実的です。

私が現状で頼ることができるのは、このスタイルを使ってきた知人からの一足早い証言です。彼らは口をそろえて、モジュールの維持が格段に簡単になったと言います。


マイクロサービスシステムの構築についてもっと知りたい方には、Sam Newmanのが有力なソースとなるはずです。

面白い事例があります。あるチームは、Microservice Premium(マイクロサービスの追加コスト)に見合わない比較的シンプルなシステムに、マイクロサービスを使うという誤った選択をしてしまいました。ある時、プロジェクトにトラブルが発生し、救済が必要となります。それで多くの人材がプロジェクトに追加投入されました。この時点で、マイクロサービスアーキテクチャは役に立ちます。なぜなら、急速に増えた開発者をシステムが吸収でき、かつ一般的なモノリスの場合と比べて、チームが増援された人材をそのシステムで有効に活用できたからです。結果的にプロジェクトは加速し、チームはモノリスを使った場合において期待されるよりも高い生産性を実現しました。しかし総体的に見ると、結果的にソフトウェアに必要以上の労力が費やされたという点で、負の要素の方が大きかったと言えるでしょう。マイクロサービスアーキテクチャが生産性を加速したということは確かですがね。

分散

マイクロサービスはモジュール性の向上のため分散システムを使っていますが、分散型のソフトウェアには大きなデメリットがあります。それは正に「分散している」ということです。分散のカード遊びを始めたとたん、多彩な複雑さを招くことになるでしょう。マイクロサービスのコミュニティはこれらの欠点について、以前の分散オブジェクトのムーブメントの時ほどは認識の甘さはないと思いますが、それでも複雑であることには変わりません。

欠点の第1はパフォーマンスです。最近では「インプロセスでの関数呼び出しが、パフォーマンスのホットスポットと化してしまっている」という状況を目にすることは滅多にないものなのですが、しかしリモート呼び出しは遅いのです。仮にサービスが6つのリモートサービスを呼び出して、そのそれぞれがさらに別の6つのリモートサービスを呼び出すと、これらの応答時間は累積され恐ろしいほどの遅延特性となります。

もちろん、この問題を軽減するための方法はあります。まず、呼び出しの粒度を上げることです。そうすれば呼び出しを少なくすることができます。ただ、これによってプログラミングモデルが複雑化するため、サービス間の相互作用をバッチ処理するやり方を考えなくてはなりません。また、この方法では、それぞれのコラボレーションサービスを少なくとも1回は呼び出す必要があります。

2つ目の軽減方法は、非同期にすることです。並列に6つの非同期呼び出しを行えば、待ち時間の合計時間ではなく、最も遅い呼び出し時間の遅さで済むことになります。これによりパフォーマンスは大きく飛躍しますが、注意したいのは経験的知識に基づいた作業が必要になることです。非同期プログラミングは正確に行うのが非常に難しく、デバッグについてはそれ以上に困難になります。それでも、私がマイクロサービスについて色々と聞いた限りだと、パフォーマンスを許容範囲内に改善するためには非同期が必要になるということでした。

速度の次に重要なのが信頼性です。インプロセスの関数呼び出しが正常に機能すればいいですが、リモート呼び出しはいついかなる時でも失敗する可能性を秘めています。多くのマイクロサービスでは、さらに潜在的な障害点があるため、賢明な開発者はこのことを想定し、Design for failure(不具合のための設計)をすることが普通です。幸い、非同期のコラボレーションに必要な方策がこの不具合の対処法とも一致し、結果的に耐障害性をも向上させます。ただ、それでも十分な対策とは言えません。全てのリモート呼び出しについて、不具合の結果を解明するのは格別の複雑さが伴います。

これは、Fallacies of Distributed Computing(分散コンピューティングの落とし穴)の代表的な2例に過ぎません。

この問題にはいくつかの注意点があります。まず、これらの事例の多くは、それが大きくなるにつれて、モノリスに突然現れるということです。ほとんどのモノリスは自己完結型ではなく、通常は他のシステム(多くの場合、レガシーシステム)と一緒に動作します。それらの相互作用によってネットワークを経由することになり、同じ問題に出くわすことになるのです。リモートシステムとの相互作用において、多くの人がマイクロサービスにいち早く移行する傾向があるのはそのためでしょう。なお、このことについても経験が役に立ちます。つまり、熟練したチームほど、分散の問題によりよく対処できるというわけです。

ただし、分散は常に労力を要します。私自身は分散のカードを使うことにも、あまりに多くの人が急速に分散化に突き進むことにも、全面的に同意することはできません。なぜなら、問題が過小評価されているからです。

最終的な整合性

多少の忍耐力を要するようなWebサイトがあることは皆さんご存じかと思います。あなたが何かを変更したのに、ページを更新すると、その変更は見当たりません。数分ほど待って、改めて更新してやると、やっと表示される……という具合です。

これは非常に苛立つユーザビリティの問題で、結果整合性の危険性が原因であることは確かです。変更はピンクのノードが受領しました。しかし、GET要求はグリーンのノードが処理しています。つまり、グリーンのノードがピンクのノードからその変更を取得するまでは、不整合なウィンドウで立ち往生してしまうというわけです。最終的にはつじつまは合いますが、それまでは「どこかに問題があるのかも」という不安で気が気ではないことでしょう。

このような不整合は十分に不愉快ですが、時にはもっと深刻な問題となり得ます。ビジネスロジックが不整合な情報に基づいて決定を下すこともあり得るわけで、こうなってしまうと何がおかしいのかを分析するのは非常に困難です。なぜなら、どのような調査も、矛盾したウィンドウが閉じてから長い時間が経過した後で行われるからです。

マイクロサービスは、優れた分散データ管理を主張することにより、結果整合性の問題点を招き入れました。モノリスにおいては、単一のトランザクションで複数のものを一緒に更新することができます。それに対し、マイクロサービスでは複数のリソースを更新しなければならない一方で、分散トランザクションは(正当な理由で)よしとされません。そのため、開発者は一貫性の問題点について自覚しなければならず、コードを改悪してしまうような事態になる前に、同期がずれたことを検出する方法を考え出す必要があるのです。

モノリシックな世界ではこういった問題がないかというと、そうではありません。システムが大きくなるにつれ、パフォーマンスを向上させるためにキャッシングを使う必要性が高まりますが、キャッシュの無効化は別の難しい問題です。ほとんどのアプリケーションでは、長期のデータベーストランザクションを避けるためにオフラインロックが必要ですし、外部システムには、トランザクションマネージャと連携できない更新が必要となります。ビジネスプロセスは、しばしば可用性を重んじるため、思っているよりも矛盾に対して寛容です(ビジネスプロセスには以前より、CAP定理の直感的な理解があったのでしょう)。

他の分散の問題点を考えてみても、モノリスが完全に不整合の問題を回避できているわけではありません。ただし、特に規模が小さい場合、その問題の影響ははるかに少なく済みます。

個別にデプロイ

モジュールの境界と分散システムの複雑さとの間に存在するトレードオフについては、私がこの業界に身を置き始めてから、ずっと変わらずに話題になってきました。しかし、ここ10年間で1つだけ目に見えて変わったことがあります。それは、プロダクトのリリースに期待される役割です。20世紀においてプロダクトリリースは、非常に大変でめったにないイベントであり、24時間体制のシフトや週末のシフトを組み、うまく動かないソフトウェアを何とか使えるものにしていったというものでした。しかし最近では、能力の高いチームが頻繁にプロダクトをリリースする時代になっています。多くの組織では継続的デリバリによって、日に何度ものプロダクトリリースが可能になったのです。

マイクロサービスはDevOps革命の後継となる最初のアーキテクチャである。
–Neal Ford

このような変化はソフトウェア業界に計り知れない影響を及ぼし、またマイクロサービスを巡る動きと密接に連動していました。いくつかのマイクロサービスへの取り組みは、大きなモノリスをデプロイするのが困難だったことをきっかけにして行われました。大きなモノリスでは、一部に加えられた小さな変更がシステム全体のデプロイの失敗につながることがあったのです。マイクロサービスの基本方針は、サービスはコンポーネントということであり、個々のサービスは個別にデプロイできます。そのため、部分的に変更を加える場合でも、1つの小さなサービスだけをテストしデプロイするだけでよいのです。失敗したとしても、システム全体に影響することはありません。結局のところ、何らかのグレースフル・デグラデーションはあるかもしれないものの、障害時に備えた設計が必要であり、コンポーネントが完全に障害を起こしていたとしても、システムの他の部分を停止させるべきではありません。

これは相互的関係です。頻繁にデプロイする必要のある多くのマイクロサービスにおいて、デプロイ作業を一緒に行うことは重要なことなのです。そのため、RAD(ラピッドアプリケーションデベロップメント)やインフラストラクチャのラピッドプロビジョニングはマイクロサービスの前提条件となっています。とにかく、継続的デリバリをする必要があるのです。

継続的デリバリにおける大きな利点としては、発案からソフトウェアを実行するまでのサイクルタイムの短縮が挙げられるでしょう。また継続的デリバリを実施している組織は市場の変化に迅速に対応できるとともに、競合他社よりも素早く新たな機能を導入できます。

マイクロサービスを利用する理由として、多くの人々が継続的デリバリを挙げていますが、実は大きなモノリスも継続的デリバリが可能だということをお伝えしておきましょう。よく知られている例としては、FacebookやEtsyの2つがあります。また、マイクロサービスアーキテクチャで個別のデプロイを試みて失敗する多くの事例があり、そのような事例では、リリース時に複数のサービス間で慎重に連携させる必要があります2。マイクロサービスとともに継続的デリバリを行うと、より容易に事が進むという大勢の人々の意見は、確かに私にも聞こえてきます。しかし、モジュラーがデリバリの速さと強い相関関係があるにしても、モジュラーのための実質的な重要性のほうが大切だと私は思っています。

運用上の複雑さ

個々のユニットを迅速にデプロイできるということは、開発側にとって非常にありがたいことですが、運用側にとっては、半ダースほどのアプリケーションが、何百もの小さなマイクロサービスになるということですから、さらなるしわ寄せが来るということでもあります。多くの組織では、そのような目まぐるしく変わる大量のツールを取り扱うことが困難だと感じるでしょう。

このことは継続的デリバリの役割の重要性を強めています。継続的デリバリはモノリスにとっても価値あるスキルで、努力をして習得する価値のあるものです。しかしもちろん、重要なマイクロサービスの設定においては不可欠なものとなっています。継続的デリバリによって得られる自動化やコラボレーションを行わずに、多くのサービスを取り扱う方法が単にないだけなのです。これらのようなサービスを管理しモニタする要求の増加により、運用上の複雑さもまた増加しています。そして、マイクロサービスが混乱状態にあるとすれば、モノリシックのアプリケーションでの便利な成熟したレベルが必要となってくるのです。

マイクロサービスの支持者は、各サービスが小さければ小さいほど、その内容を理解するのが簡単になるものだと指摘しがちです。しかしここで問題なのは、そこにはマイクロサービスに複雑さがなくなったわけではなく、単にサービス間の相関性の方に、複雑性がシフトしただけということです。その結果、サービスを拡張する際に行うデバッグにおける困難さというような運用上の複雑さが増加し、そこで問題が表面化してしまいます。サービスの境界において適切な選択をすることで、この問題は減らせます。しかし、境界の選択を誤ると、事態はさらに悪化してしまうのです。

このような運用上の複雑さの取り扱いには、多くの新たなスキルとツールを必要とします。その中でも、スキルは特に強調すべきことです。ツールは未熟です。しかしツールをよくするよりも、スキル習得への壁を低くすることの方が、マイクロサービス環境にとって優先度が高いと私は直感的に思っています。

しかし、この高いスキルとツールの必要性は、処理の複雑さに対応するための最も大変な部分ではありません。効果的に対応するためには、DevOpsの文化を導入する必要があります。開発者、オペレーション、そしてソフトウェア配信に関わる全ての人たちの間のより大きな協力体制です。文化を変えていくのは、大きく古い組織では特に難しいことです。でもこのスキルアップと文化的な改革を行わなければ、モノリシックなアプリケーションでは障害が起き、マイクロサービスアプリケーションは痛手を負ってしまうでしょう。

技術の多様性

それぞれのマイクロサービスは個別にデプロイできる単位なので、その中での技術の選択には比較的自由度があります。マイクロサービスでは違う言語で記述したり、異なるライブラリを使用したり、異なるデータストアを利用したりすることができます。これによって、各チームはその仕事に合った適切なツールを選択することができます。ある特定の問題に適した言語やライブラリというものがあるからです。

技術の多様性については、仕事内容にとってベストなツールは何かということがよく議論の中心になります。しかしマイクロサービスの最も大きな利点というのは、多くの場合ありふれたバージョニングの問題だったりします。モノリシックシステムでは単一バージョンのライブラリしか使うことができず、アップグレードの際に問題になることがよくあります。システムの一部では新機能を使うためにアップグレードを必要としているのに、アップグレードするとシステムの他のパートが壊れてしまうためできないというような状態です。ライブラリのバージョン問題は、コードベースが大きくなるにつれ指数関数的に難しくなる問題の1つです。

ここでの危険性は、あまりにもテクノロジの多様性が大きすぎると開発会社が圧倒されてしまうということです。私の知るほとんどの組織では、推奨する技術に制限が設けられています。そうすることよって、モニタリングなどのための共通のツールを供給し、共通環境の小さな製品ラインにサービスを追随させやすくなるからです。

確認実験の価値を過小評価しないようにしましょう。モノリシックなシステムでは、初期の段階で決定した言語やフレームワークを覆すのは困難です。10年も経てば、その時の決断によって組織が時代にそぐわない技術に縛り付けられてしまう可能性があります。マイクロサービスでは、組織は新しいツールを試し、優れたテクノロジが適切になった時期に1サービスずつ徐々にシステムを移行していくことができます。

二次的要因

上述したようなことは最も重要なトレードオフとして考慮すべきです。それより重要度は少し劣りますが、二次的なことをいくつか述べたいと思います。

マイクロサービスの支持者がよく言うのはサービスのスケールがしやすいという点、つまり、1つのサービスが高負荷になった場合、アプリケーション全体ではなく、その箇所のみをスケールできる、ということです。しかし、全部のアプリケーションをコピーすることにより行うCookie-Cutter Scalingに比べて、この選択的なスケールをするほうが効率的なのでしょうか。私を納得させるに足る、まともな実験レポートがあったかどうかちょっと思い出せません。

マイクロサービスでは極秘情報を切り離しておくことができ、そのデータに対してより入念なセキュリティを付加することができます。更に、マイクロサービスのアプローチでは、サービス間のトラフィックが全て安全であることを保証することによってマルウェアが侵入するのを難しくします。セキュリティ問題の重要性は増しているので、これはマイクロサービスを使うことを考慮する大きな要因となるでしょう。そうでなくとも、そもそもモノリシックなシステムでは極秘情報を扱うために別のサービスを作成しなくてはならないことも珍しくありません。

マイクロサービスに否定的な人たちは、モノリシックシステムよりもマイクロサービスのアプリケーションをテストするのが難しいと言います。事実そうなのですが、これは分散化アプリケーションの複雑性が高いためです。しかしマイクロサービスでテストを行うよいアプローチがあります。ここで最も重要な点はテストを真剣に行うという原則をしっかり持つことです。それに比べれば、モノリシックシステムをテストするのと、マイクロサービスをテストする違いというのはさして重要ではありません。

まとめ

アーキテクチャのスタイルに関する記事はどんなものでも、一般的なアドバイスの限界がつきまといます。ですから、このような記事を読んでも決断には至らないかもしれませんが、考慮に入れるべき様々な要素をきちんと考察するのには役立つはずです。ここで述べたそれぞれのコストと利点は、それらを入れ替えたとしても、システムが違えば重要度も違います(モジュールの明確な境界は複雑なシステムでは良いが、シンプルなシステムにとっては重荷となります)。どのような決断を下すにせよ、それは状況に応じた基準に基づくことになります。あなたのシステムに最も影響がある要因と、それがあなた独自の状況にどう影響するかの評価に基づくのです。しかも、マイクロサービスアーキテクチャに関する私たちの経験値はまだ高くありません。通常、アーキテクチャに関しての判断はシステムが成熟して、開発開始から何年も使って学んだ後でないとできないものです。

マイクロサービス・リソースガイド


マイクロサービスに関する他の情報については、まず私の書いたマイクロサービス・リソースガイドを読んでみてください。マイクロサービスに関しての何、いつ、誰についてベストな情報を厳選して書いています。

モノリシックシステムとマイクロサービスは単なる二者択一ではありません。どちらも定義はあいまいで、ぼんやりとした境界エリアに多くのシステムが存在しています。どちらのカテゴリにも属さないシステムもあります。私も含め多くの人々はモノリシックシステムとの対比としてマイクロサービスについて話すことが多いですが、これは一般的なスタイルとして比較しやすいからです。しかし、どちらのカテゴリにもフィットしないシステムもあるということを覚えておかなければなりません。私は、モノリシックシステムとマイクロサービスはアーキテクチャ空間の中の2つの領域だと捉えています。それぞれに特筆に値する興味深い特徴があり、議論するのにふさわしいからです。しかし思慮深いアーキテクトであれば、これらをアーキテクチャ空間の包括的な区分けとして扱う人はいません。

そういうわけで、広く受け入れられている1つのまとめとして、マイクロサービスで生じる追加コストがあります。マイクロサービスには生産性のコストがあり、より複雑なシステムの場合でなければペイしません。ですから、あなたのシステムの複雑さがモノリシックなアーキテクチャで管理できるなら、マイクロサービスを使うべきではないのです。

しかしマイクロサービスについて話す時、ソフトウェアプロジェクトの成功や失敗をもたらす重要な問題について忘れてはなりません。組織における人材の質や、協力関係がうまくいっているか、そして専門家とのコミュニケーションの度合いなど、ソフトな要因の方が、マイクロサービスを使うかどうかということよりも大きな影響があります。純粋に技術的なレベルでは、クリーンなコードや、しっかりしたテスト、そして新進のアーキテクチャに注目するなどということに注力する方が重要なのです。

脚注


  1. “モノリシックシステム”という語は侮辱であり、常に「モジュール性に乏しい構造」を意味すると考える人もいます。マイクロサービスの世界にいる人々の殆どはこのようには考えず、純粋に1つのユニットとして構築されたアプリケーションとして定義しています。もちろん、マイクロサービスの支持者は、殆どのモノリシックシステムが大きな泥団子に終わってしまうと思っていますが、私の知る限り、適切に構築することが不可能だと言う人はいません。 

  2. サービスを個別にデプロイする機能はマイクロサービスの定義の一部です。ですから、サービス一式でデプロイメントを連携させしなくてはならないとしたら、それはマイクロサービスアーキテクチャではないと言って間違いありません。そして、マイクロサービスアーキテクチャを試みている多くの組織で、結局はサービスのデプロイメントを連携させなくてはならない羽目に陥り、問題が発生している、ということも申し添えておきます。