警告:大きな投稿、いくつかの意見、あいまいな「あなたに最適なことをする」結論
一般的に、これはデータベースの周りに「六角形のアーキテクチャ」を実装する手段として行われます。Webアプリケーション、モバイルアプリケーション、デスクトップアプリケーション、バルクインポーター、およびバックグラウンド処理のすべてで、データベースを均一に消費させることができます。確かに、データベースにアクセスするための豊富なライブラリを作成し、すべてのプロセスでそのライブラリを使用することで、ある程度同じことを達成できます。確かに、非常にシンプルなシステムを備えた小さな店にいる場合、実際にはおそらくこれがより良いルートです。それはより単純なアプローチであり、より複雑なシステムの高度な機能が必要ない場合、なぜ複雑さを払うのですか?ただし、大規模で洗練された一連のシステムで作業している場合、すべて大規模にデータベースとやり取りする必要があります。
プラットフォームの独立性とメンテナンス
データベースがあり、そのデータベースと対話するPythonライブラリを作成し、誰もがそのライブラリを引き込んでデータベースと対話する場合、それは素晴らしいことです。しかし、突然モバイルアプリを作成する必要があり、そのモバイルアプリもデータベースと通信する必要があるとしましょう。また、iOSエンジニアはPythonを使用せず、AndroidエンジニアはPythonを使用しません。たぶん、iOSの人たちはAppleの言語を使い、AndroidのエンジニアはJavaを使いたいと思うでしょう。そうすると、データアクセスライブラリを3つの異なる言語で記述し、維持する必要がなくなります。iOSとAndroidの開発者は、Xamarinなどを使用して、共有できるコードを最大化することを決定するかもしれません。ただし、データアクセスライブラリを.NETに移植する必要がある場合を除き、完璧です。そして、あなたの会社はちょうど別の会社を購入しました s Webアプリケーションは、異種ではあるが関連製品であり、企業は、自社のプラットフォームのデータの一部を、新しく買収した子会社のプラットフォームに統合したいと考えています。唯一の問題があります。子会社は新興企業であり、アプリケーションの大部分をDartで作成することにしました。さらに、何らかの理由(おそらく制御できない理由)のために、Xamarinを試験運用していたモバイルチームは、それは彼らのためではなく、開発対象のモバイルデバイスに固有のツールと言語を使用することを決定しました。しかし、その段階では、あなたのチームはすでに.NETでデータアクセスライブラリの大部分を提供していたため、社内の別のチームがSalesforceのクレイジーな統合作業を書いていたので、そこからすべてを.NETで行うことにしました。は既にのデータアクセスライブラリでした。
イベントの非常に現実的な変化により、Python、.NET、Swift、Java、およびDartで記述されたデータアクセスライブラリが用意されました。どちらもあなたが望むほど良いものではありません。各言語には異なるORMツールがあるため、希望するほど効果的にORMを使用できませんでした。そのため、必要以上のコードを記述する必要がありました。そして、5つあるので、それぞれの化身にあなたが望むほど多くの時間を割くことができませんでした。ライブラリのDartバージョンは、ライブラリとサポートが実際には存在しなかったため、一部のトランザクションのものをロールバックする必要があるため、特に毛深いです。このため、Dartアプリケーションにはデータベースの読み取り専用機能のみが必要であるというケースを作成しようとしましたが、しかし、ビジネスはすでに、計画している機能はすべて追加の努力に見合う価値があると考えていました。そして、データアクセスライブラリのこれらすべてのインカネーションに存在する検証ロジックのいくつかにバグがあることがわかりました。これらのすべてのライブラリでこのバグを修正するためのテストとコードを作成し、これらすべてのライブラリの変更のコードレビューを取得し、これらすべてのライブラリのQAを取得し、すべてを使用してすべてのシステムの変更をリリースする必要がありますこれらのライブラリ。一方、あなたの顧客は不快になり、Twitterに連れて行かれ、あなたの会社の主力製品をターゲットにしたことは言うまでもなく、想像もしなかった下品の組み合わせをつなぎ合わせました。そして、製品の所有者は、状況についてまったく理解していないと判断します。
一部の環境では、上記の例は不自然なものであることを理解してください。また、この一連のイベントが数年にわたって展開する可能性があることも考慮してください。一般に、アーキテクトやビジネスマンが他のシステムをデータベースに接続することについて話し始める段階に達すると、ロードマップに「データベースの前にREST APIを置く」ことを望みます。早い段階で、このデータベースがいくつかのシステムで共有され始めることが明らかになったときに、Webサービス/ REST APIがその前に置かれたかどうかを検討してください。検証バグの修正は、5回ではなく1回行うため、はるかに迅速かつ簡単になります。修正プログラムをリリースすると、調整がはるかに簡単になります。なぜなら、
TLDR; データにアクセスする必要のある各アプリケーションにデータアクセスロジックを配布するよりも、データアクセスロジックを集中化し、非常に薄いHTTPクライアントを維持する方が簡単です。実際、HTTPクライアントはメタデータから生成されることさえあります。大規模なシステムでは、REST APIを使用すると、少ないコードで管理できます
パフォーマンスとスケーラビリティ
一部の人々は、最初にWebサービスを経由するのではなく、データベースと直接対話する方が速いと考えるかもしれません。アプリケーションが1つしかない場合、それは確かに真実です。しかし、大規模なシステムでは、私は感情に同意しません。最終的には、ある程度の規模では、データベースの前に何らかのキャッシュを置くことは非常に有益です。Hibernateを使用していて、InfinispanグリッドをL2キャッシュとしてインストールしたい場合があります。アプリケーションとは別にWebサービスをホストする4つの強力なサーバーのクラスターがある場合は、同期レプリケーションを有効にした埋め込みトポロジを使用する余裕があります。これを30個のアプリケーションサーバーのクラスターに配置しようとすると、そのセットアップでレプリケーションをオンにするオーバーヘッドが大きすぎるため、分散モードまたはある種の専用トポロジでInfinispanを実行する必要があり、キャッシュから読み取るためにHibernateが突然ネットワークを経由する必要があります。さらに、InfinispanはJavaでのみ機能します。他の言語がある場合は、他のキャッシングソリューションが必要になります。データベースに到達する前にアプリケーションからWebサービスに移動する必要があるネットワークオーバーヘッドは、一般に独自のオーバーヘッドが伴うはるかに複雑なキャッシングソリューションを使用する必要があるため、すぐに相殺されます。
さらに、REST APIのそのHTTPレイヤーは、別の貴重なキャッシングメカニズムを提供します。REST APIのサーバーは応答にキャッシュヘッダーを配置でき、これらの応答はネットワークレイヤーでキャッシュできます。1つまたは2つのサーバーがある小規模なセットアップでは、データベースと通信するときにアプリケーションのメモリ内キャッシュを使用するのが最善の策ですが、多くのサーバーで実行される多くのアプリケーションがある大規模なプラットフォームでは、ネットワークを使用してキャッシングを処理します。適切に構成すると、squid、ニス、nginxなどが比較的小さなハードウェア上で非常識なレベルにスケールアウトできるためです。1秒あたり数十万または数百万のリクエストのスループットは、アプリケーションサーバーまたはデータベースからの場合よりもHTTPキャッシュからの方がはるかに安価です。
それに加えて、データベースを指す少数のサーバーをすべて指すのではなく、大量のクライアントがすべてデータベースを指すようにすることで、データベースのチューニングと接続プーリングが非常に難しくなります。一般に、アプリケーションサーバーの実際のワークロードのほとんどはアプリケーションに関連しています。データベースからデータが戻ってくるのを待つことは、多くの場合時間がかかりますが、一般的には非常に計算コストがかかりません。アプリケーションのワークロードを処理するために40台のサーバーが必要な場合がありますが、おそらくデータベースからデータを取得するために40台のサーバーは必要ありません。そのタスクをWebサービス専用にすると、Webサービスはおそらくアプリケーションの他の部分よりもはるかに少ないサーバーで実行されます。つまり、データベースへの接続がはるかに少なくなります。これは重要です。データベースは一般的に
TLDR; 異なる言語やテクノロジーを使用する多くの異なるアプリケーションで発生する場合よりも、単一の専用Webサービス内で発生する場合の方が、データアクセスの調整、スケーリング、およびキャッシュが容易です。
最終的な考え
「おっと、データを取得するために常にREST APIを使用する必要があります」または「このバカは、Webアプリがデータベースと直接通信するため、間違っていると言っています」という考えから離れないでください。私たちのものは正常に動作します!」。私がやろうとしている主なポイントは、異なるシステムと異なるビジネスには異なる要件があるということです。多くの場合、REST APIをデータベースの前に配置することは本当に意味がありません。それはより複雑なアーキテクチャであり、その複雑さを正当化する必要があります。しかし、複雑さが保証される場合、REST APIを使用することには多くの利点があります。さまざまな懸念事項を比較検討し、システムに適切なアプローチを選択できることが、優れたエンジニアになります。
また、REST APIが物事のデバッグを妨げている場合、その図に何か問題があるか、欠落している可能性があります。追加された抽象化レイヤーが本質的にデバッグを難しくするとは思わない。大規模なn層システムで作業する場合、分散ロギングコンテキストがあることを確認するのが好きです。おそらく、ユーザーがリクエストを開始したときに、そのリクエストのGUIDを生成し、そのユーザーのユーザー名とユーザーが行ったリクエストを記録します。次に、アプリケーションが他のシステムと通信するときに、そのGUIDを渡します。適切なログの集計とインデックス作成により、問題を報告しているユーザーについてプラットフォーム全体を照会し、すべてのアクションを可視化できます。システムを細かく調べて、問題が発生した場所をすばやく特定できます。繰り返しますが、より複雑なアーキテクチャです。
出典:http
:
//alistair.cockburn.us/Hexagonal+architecture https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing