web-dev-qa-db-ja.com

RESTがWebアプリケーションでRPCのようなメカニズムの代わりに一般的に使用されるのはなぜですか?

私はごく最近、少なくとも私が知っている典型的なWebアプリケーションフレームワークと比較して、彼らのWebアプリケーションにかなり変わったカスタムフレームワークを使用する会社で始めました。 RESTful Webサービスの代わりに、RPCメカニズムを使用してサーバーと通信します。

サーバーとの通信は単純な関数呼び出しのように見えますが、関数はクライアントではなくサーバーで実行されます。サーバー側には、クライアントが呼び出すことができる関数を定義する方法があります。これがどのようにhttpリクエストに変換されるかの詳細は完全に抽象化されています。

私はこれを少しだけ使用しましたが、かなり便利なようです。しかし、私はこのアプローチのどの欠点が欠けているのだろうと思っています。他の誰もが違うやり方をしているようです。これは通常、私が愚かまたは素晴らしい何かをしている可能性があり、前者よりはるかに高いオッズであるという兆候です。

20
Vivian

RESTはWeb用に設計され、WebはREST用に設計されました。 2つはぴったり合うでしょう。 ロイフィールディングの2000年の博士論文アーキテクチャスタイルとネットワークベースのソフトウェアアーキテクチャの設計 用語を定義および導入 [〜#〜] rest [ 〜#〜] 、そしてWebとRESTの間には重要な相互作用があります:ロイフィールディングはHTTP/1.1で作業しました。その著者は彼が主著者であり、彼はそこで学んだことを使用して説明しましたREST彼の論文。

したがって、WebとRESTがうまく連携している単純な理由は、RESTの定義がWebの動作方法から抽出され、WebがRESTの実装。

RESTはWebサービスとWebアプリに適しています。「人間の」Webで動作することがすでに証明されているのと同じことを行い、それらを「マシン」ウェブ。

big RPCの問題(exactの実装に依存)は基本的に Fallacies of Distributed Computing にあり、 Arnon Rotem-Gal-Ozによるこのホワイトペーパー

  1. ネットワークは信頼できる
  2. 待ち時間はゼロです
  3. 帯域幅は無限です
  4. ネットワークは安全です
  5. トポロジーは変わらない
  6. 管理者が一人います
  7. 輸送費はゼロ
  8. ネットワークは均一です

これらはすべて、新参者が分散システムの作成を開始するときに通常行う前提です。もちろん、それらはすべて誤りです。また、分散システムを作成する場合は、それらすべてを考慮する必要があります。

多くのRPC実装の問題は、リモート呼び出しをローカル呼び出しのように見せようとすることです。しかし、それらは似ていない:

  • ローカル呼び出しが失敗することはありません。呼び出したsubroutineが失敗する可能性がありますが、呼び出しitselfが失敗することはありません。リモートコールがネットワーク上で失われる可能性があります
  • ローカル呼び出しは瞬時に行われます。呼び出したsubroutineは長時間(または無限ループに陥った場合は永久に)実行される可能性がありますが、呼び出しitselfにはまったく時間がかかりません( 、せいぜい一握りのCPU命令、呼び出しがインライン化されている場合は少なくなりますが、それはvery fast)です。–リモート呼び出しが長時間ネットワーク上でスタックする可能性があります
  • サブルーチンが正常に戻った場合、結果は常に返されます。リモート呼び出しでは、結果がネットワーク上で失われる可能性があります
  • 返品は瞬時に行われます–リモートの結果は長期間ネットワーク上を移動できます
  • サブルーチンを1回呼び出すと、1回だけ実行されます。リモート呼び出しがネットワーク上で失われたり、重複したりして、リモートルーチンが0から任意の回数実行される可能性があります。
  • 結果は1つだけ返されます。リモートの結果が失われたり重複したりする可能性があるため、結果が0回以上返される可能性があります
  • サブルーチンを2回呼び出した場合、2つの結果が得られ、2番目の呼び出しの結果よりも前に最初の呼び出しの結果が得られます。おそらく、おそらくそれを推測できます。RPCでは、結果が返されないか、最初の呼び出しだけが返される場合があります。 、または2番目のみ、または1番目の前の1番目、または1番目が失われる可能性があり、2番目を2回取得するか、またはその逆などです。
  • aを呼び出してからbを呼び出すと、aの結果が返され、次にbの結果が返されます。これは、より一般的なバージョンです。前のポイントでは、RPCを使用すると、2つの回答のいずれかを任意の順序で0回以上取得できます

あなたはwillリモート呼び出しのために上記のすべてに対処する必要があります。しかし、フレームワークがリモート呼び出しをローカル呼び出しと区別できないようにする場合、あなたはca n'tを知らないのでどれかはリモート呼び出しです。フレームワークはそれらすべてを試して処理してくれるかもしれませんが、問題はフレームワークがあなたのシステムほどあなたのシステムについて知らないということです。たまに迷子になっても問題にならない通話があるかどうかはわかりません。したがって、フレームワークは非常に防御的である必要があり、それは待ち時間と帯域幅の点で高価です。

特にフレームワークは実際にcannotを保護するためです。 CAP Theorem は、分散システムは、一貫性があり、利用可能であり、同時にパーティショントレラントであってはならないことを示しています。より正確には、パーティションが発生すると、システムは一貫性と可用性の両方を維持できなくなるため、どちらかを選択する必要があると言われています(一般的な考えとは異なり、定理では、システムの実行時に3つすべてを使用できないとは言われていません通常、あなたはcan 3つすべてを持っていますが、パーティションを作成したら、他の2つのうちの1つを選択する必要があります)。 PACELC Theorem は、システムが動作している場合でも、レイテンシと一貫性のトレードオフが必要であることを示すことで、CAP定理を拡張します。

これらはドメイン固有であり、コアの設計にとって重要であるため、フレームワークがユーザーを保護できない重要なトレードオフです。

doesが機能するErlangのようなアプローチとは対照的です:Erlangではallメッセージの送信は、たとえローカルであってもリモートとして扱われます。これは、上記の問題(およびその他多く)のすべてに常に対処する準備ができていることを意味します。ただし、ローカルプロセスの場合、これらのdoは少しオーバーヘッドになります。これを支援するために、エラー処理と監視を処理するためのツール、フレームワーク、ライブラリ、パターン、およびイディオムが多数あります。

RPCフレームワークがどのように機能するか、使用している言語やライブラリについてはまだ説明していませんが、前者の「ネットワークが存在しないふりをする」タイプに属していると強く疑っています。それらは機能しません。 すべてリモート呼び出しとして扱うことにより、ローカルコールとリモートコールの区別を取り除くのはOK]です。逆にそれを行うと、抽象化が多すぎます。ネットワークisシステムの一部です。抽象化すると、実際に何かを抽象化します必要知っておく必要があります。

具体的に使用する必要があるかどうかRESTかどうかは、まったく別の質問です。上で説明したように、WebはRESTとRESTはWeb用に設計されているため、2つのdoを一緒に使用しても意味がありますが、必要に応じて他のアーキテクチャスタイルを使用できます。ただし、あなたの質問の少なくとも一部は「なぜRPCではないのか」に関するものであり、上記の理由を説明しました。具体的には、使用していると思われるRPCのtypeが問題を引き起こす可能性がある理由を詳しく説明しました。

33
Jörg W Mittag

コメントにはすでにいくつかの良いアイデアがあります。ここで繰り返します。

  1. RPCは通常、テクノロジー固有です。
  2. 開発者が最も関心を持っているのはRESTではなくJSONです。

JSONにはいくつかの非常に優れた性質があります。シンプルで、人間が読みやすく、コンピュータが解析しやすく、Javascriptはそれをネイティブに即座に認識します(つまり、Javascriptオブジェクト表記)。

RESTのような制約を無視しても構わないとしたら、リモートプロシージャコールを含め、JSONを使用してほぼすべてのことを実行できます。あなたがしなければならないすべては、適切なプロトコルを確立することです。実際、そのようなプロトコルはすでに存在しています: JSON-RPC。

--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
<-- {"jsonrpc": "2.0", "result": 19, "id": 1}
5
Robert Harvey