バックエンド、または太った顧客の時代を生き残る方法

記事のタイトルは文字通りに取るべきではありません。 バックエンドは消えていません。開発の焦点は、特に新しいプロジェクトの開発の初期段階で、「 クライアント側 」に強くシフトしています 。 データを保存し、REST APIを既に「バインド」し、PHP / Python / Ruby / Java /などを可能な限り拒否し、「クライアント側」でコードの80%を記述し、最小限の「サーバー側」の面倒を最小限に抑えたい「。



この記事はNikolay Samokhvalovのレポートに基づいています。NikolaySamokhvalovは 、React、React Native、およびSwiftで記述され、 PostgreSQL + PostgRESTに よるnoBackendパラダイムに移行した多くのプロジェクトの経験をまとめました。



最後に、noBackendアプローチを使用するための必須の質問のリストがあります。Postgresの経験が許せば、読んだ直後に、 REST APIの迅速な開発に適した安全で高性能のデプロイを開始できます







スピーカーについて: Nikolay Samokhvalovは10年以上PostgreSQLと連携しており、ロシアのコミュニティRuPostgres.orgの共同主催者であり、現在、さまざまな企業がPostgreSQLの運用に関連するプロセスの最適化、スケーリング、 自動化を支援しています。 次は、バックエンドとフロントエンドの両方の開発者向けに設計された、ニコライのBackend Confに関するレポートのデコードです。



近年、私はシリコンバレーで多くの時間を過ごし、そこで観察している傾向をあなたと共有したいと思います。 もちろん、ここからはすべてが完璧に見えますが、高度な技術についての専門的な会話が文字通りすべてのカフェで行われているため、より視覚的です。





太った顧客の時代



まず、ファットクライアントとは何か、時代は何かを判断しましょう。



奇妙な事実。 RubyがPHP、Java、JavaScriptとともに1年で登場したことをご存知ですか?







これらの4羽のアヒルは同じ年に登場し、実際、どれがいのかは明らかですよね? 当然、これはJavaScriptです。







新しいNetscapeブラウザの準備のためにスクリプト言語を書いた従業員によって10日で書かれた「ひざまずき」でした。 最初は別の名前で呼ばれていましたが、Javaが台無しにされたとき、彼らは同時に名前を変更することを決定しました。 さらに、長年にわたり、JavaScriptは二次的な役割を果たし、ブラウザで何らかのアニメーションを作成したり、何らかの反応を計算したりするために使用されていました。



しかし、次第に2003年から2004年のどこかで、WEB 2.0、GMail、Googleマップなどで宣伝が始まり、JavaScriptの重要性が確実に高まり、顧客は太り始めました。 そして今、私たちはJS上に単一ページのアプリケーションと膨大な数のフレームワークを持っています。 たとえば、ブラウザーにはReact Ecosystem、モバイルにはReact Nativeがあります。 シリコンバレーでは、Reactは膨大な数の人々を魅了する巨大な目的地です。 同日、サンフランシスコの近隣の通りで、数百人の聴衆と数回のReactミーティングが開催されました。



JavaScriptの観点から見ると、これはディストリビューションに関する話です。最初はあまり良くないテクノロジーがありますが、すべてのブラウザーにインストールして各クライアントマシンに伝達する場合、当然、時間の経過とともに、私たち全員がこれに対処する必要があります。原則として、もう一方は単に存在しません。 このストーリーは、この言語がどのように配布されて、他のプログラミング言語の中で主導的な地位を占めるようになったかについてです。



以下は、2018年第1四半期のRedMonk.com調査のチャートです。







OYの場合、StackOverflowの質問のタグの数、OXの場合、GitHubのプロジェクトの数。 JavaScriptは両方のカテゴリで勝ちますが、他の3つのアヒルの子も非常に近いです:Java、一般的にそこに留まっている、PHP、Rubyも非常に近い、つまり、これらは23年前に生まれた4つの言語です。 他のほとんどすべての研究は、JavaScriptがすべてのプログラミング言語よりも優れていることも確認しています。



私はSQLについて少し心配しています。 GitHubでSQLを少し異なる方法で測定すると、noSQLに関する誇大宣伝にもかかわらず、JavaScriptが非常に多くのプロジェクトで使用されているため、JavaScriptに先んじることさえあります。 しかし、JavaScriptは無視できない言語であることは明らかです。



そして、太った顧客の第二の側面。 4年前、モバイルデバイスはデスクトップよりも優れていました。 2015年に、Googleは検索がコンピューターよりもモバイルデバイスでより多く使用されたことを発表しました。







これらの2つの側面から、新しいプロジェクトを開始するとき、バックエンドについてまったく考えたくないという考えに至ります







アイデアはこれです-バックエンドについてはまったく考えません。 もちろん、多くのユーザーがいて何らかの形で相互作用する場合は、もちろんどこかにこのデータをサーバーに保存し、何らかの方法で作業する必要があります。 効率的で、信頼性があり、安全です。



もう1つの重要な側面は、新しいプロジェクトではなく、Webサイト、iOS、Android向けのアプリケーション、多分smartTV、さらには時計を備えた長期にわたるプロジェクトの場合、当然ながらバックエンドとユニバーサルAPIが必要なことです。







動物園全体が統一された方法で対話する必要があり、REST APIまたはReact EcosystemのGraphQLのいずれかを使用します。いずれにしても、そのようなものが必要です。



生き残る方法



最初のオプション。 雲



さあ、サーバーはまったくありません。完全にクラウドに住んでいます 。 残念ながら、そのような(最小限の労力でクラウドへのAPIの展開を提供する特殊なクラウドサービス)、オンラインプロジェクトは存続しませんでした。 StackMob.comParseの 2つの著名な代表者







どちらの場合も、プロジェクトを吸収した会社は、エンジニアをより緊急のプロジェクトに移しただけです。 これらのケースでは、AmazonやGoogleなどの汎用クラウド競合失われたと言えますが、理解できないAPI、ストレージの不足、低パフォーマンス、高価格など、他の側面もあります。数年前には多くのノイズがありましたが、これらのサービスは存続しませんでした。



一般に、アイデアは次のとおりです。クラウドがあれば、より信頼性が高く、わかりやすく、明日も消えないものにしましょう。ソリューションはAmazonとGoogleです。 noBackendアプローチの要素がいくつかあります。これはLambdaCognito認証/承認サービスです。



APIなどのバックエンドを絶対に使用したくない場合は、バックエンドサーバーをまったく使用せずに、すぐにクライアントコードを作成できるようにするための専用ソリューションへのリンクがあります。



2番目のオプション。 ポストグレスト



そして今、私は言うが、まだ真剣にそれやろう。 そして、ここにPostgRESTがあります。 私は彼に使用することを強く推奨しているという事実にもかかわらず、この記事は非常に一般的です。







PostgRESTにはこのような積極的に開発されている機能があります。これは本質的に本物のJediの道です。



PostgRESTの力



PostgRESTはHaskellで記述され、非常に自由なライセンスの下で配布され、積極的に開発されており、 Gitter Chatでサポートを受けることができます。 現時点では、PostgRESTは優れた状態に成熟しており、多くのプロジェクトで実行されています。







上記のスライドは、これをどのように開始できるかを示しています。v1-schemeは、APIの最初のバージョンが存続するスキームであり、プレートをすばやく作成できます。または、すでにプレートがある場合は、「仮想プレート」を組み立てることができます「-表現(ビュー)。 そして、APIエンドポイント/人を取得します。そこから、他のテーブルのフィルタリング、ページング、ソート、結合にパラメーターを使用できます。



4つのメソッドがサポートされています: GETは SQLのSELECT、POSTからINSERT、PATCHからUPDATE、DELETEからDELETEに自動的に変換されます。



ストアドプロシージャを作成することもできます。PostgRESTを使用する場合は、ほとんどの場合それを実行します。 ストアドプロシージャは悪だと多くの人が言うことを知っています。 しかし、私はそうは思わない。私はかなり多くの経験を持ち、さまざまなDBMSと「ストレージ」を使用した-悪ではない 。 はい、デバッグにはいくつかの困難がありますが、デバッグは一般に注意が必要です。



PL / pgSQLはストアドプロシージャのメイン言語であり、そのためのデバッガがあります。 ただし、PL / Pythonやplv8(これはJavaScriptですが、外部と通信できない言語)を含む他の言語を使用することもできます。 つまり、分析用の言語やPL / R統計など、さまざまな機能があります。 ストアドプロシージャは、POST / rpc / procedure_name(本体の名前付きパラメーターを転送する)またはGET / rpc / procedure_name(GETパラメーターのみを使用でき、対応する制限が伴う)を使用して呼び出すことができます。



最後に、記事に含まれるすべてのレッスンをメモにまとめます。 あなたが「フロントエンド」である場合、このメモを取り、バックエンド用に選択したソリューションがどれだけ良いかをポイントで確認することができます。 バックエンドの場合は、構築しているバックエンドがどれだけ優れているかを確認する必要があります。



品質



いくつかのプロジェクトで学ばなければならなかった最初のレッスンから始めましょう。



ちなみに、PostgreSQLは必ずしも純粋なリレーショナルDBMSではなく、JSONをそこに保存することができます。一部の支払いシステムは、独特のNoSQLなどです。



APIの構築を開始すると、 テストをほぼすぐ乗り越える必要があります。 そして、(ほとんど使用していると思いますが) 継続的インテグレーションツールを使用していない場合は、これを実行してテストを行う必要があります。特に「悪いテスト」は、公開できないものを明らかにしないためです。 データベースにスーパーユーザーを作成し、ルービストがそれを使用する場合、それは別の問題です。これはすべて突き出ており、悪いことをすることができます。 一部のハッカーは遅かれ早かれ来ます。私はそのようなケースに何度も遭遇しました。







レポート(2016年)の少し前に、@ backendsecretがTwitterでアンケートを実施し、実際には半分が継続的インテグレーションなしであると予想していましたが、実際にはすべてがすでにかなりクールでした。







上記のスライドの最初の段落にいる場合、これを行わないでください。これは「敗者」アプローチです。



REST API



Firefoxで直接リクエストを作成できることを誰もが知っているわけではなく、変更するだけです;編集と再送信があります; cURLがあります;より便利な出力を持つコンソールユーティリティHTTPieがあります。







ただし、メインツールはGoogle ChromeのPostman拡張機能です。 APIを使用する場合、非常に役立ちます。 それは多くの問題を解決します:たくさんのリクエストを投げ、保存し、環境から抽象化することができます。 つまり dev-server、staging-server、production-serverがあります-異なるホストがあり、異なるユーザー名、パスワードがあります。これらはすべて環境として入力し、ファイルにアップロードして、newmanを使用して、Postmanに追加するようなものです。コンソールから。 また、プロジェクトを変更するたびにAPIテストが自動的に実行されるようにCIに配置します。



安全性



セキュリティについて考える人はほとんどいませんが、 これを行う必要があります 。 たとえば、ラベルがあり、PostgRESTで「SELECT * FROM this label」としてビューを作成するだけの場合、 セキュリティ問題が発生します。 APIを操作するユーザーが権利を持っている場合、他のユーザーのuser_idなど、誰でも追加できます。つまり、これは完全な混乱です。







この場合、リレーショナルデータベースの権限を理解し、必要な権限のみを付与する必要があります。 DDL変更の移行にユーティリティを使用する場合、たとえばSqitchで 変更テストできます 。つまり、migration-testを使用して検証できます。 特に、特権を割り当てることができますが、このようなトリックをお勧めします(上のスライドの矢印がそれにつながります):ゼロによる除算が発生した場合、エラーが検出され、これはユーザーがこのテーブルに対する特権を持っていないことを確認するのに役立ちます



APIの観点から、APIが適切なコードで応答することを確認する必要があります(PostgRESTの場合、ほとんどのコードは400です)。 Postmanでテストを作成すると、テストは自動的にアンロードされ、newmanを使用するとすべてが自動的に有効になり、チェックされます。 これは行われなければならず、どのドアがどこにあり、どのようにそれらを閉じるかを事前に考えることが不可欠です。



実際、セキュリティの問題には3つのレベルの問題があります。それぞれについて個別に話しましょう。



匿名クエリ



問題の最初のレベルは、匿名ユーザーの検証です。 PostgREST署名ヘッダーを持たないユーザー。 ヘッダーはあるが、PostgRESTがそれを認識しない場合、「無効なトークン」になります。 ヘッダーがない場合、これは匿名と見なされ、PostgRESTデータベースでのそのアクションは別のユーザーの下で実行されます。







あなたの仕事は、このユーザーが登録、ログイン、パスワードのリセット以外の権利を一切持たないようにすることです-これで十分です。 その後、テストを作成して、このユーザーが前のスライドで説明したような権限を持たないことを確認できます。 したがって、匿名名の問題は解決されます。



列の権利



それは何ですか? 「user」テーブルからSELECT *を作成すると、少なくともパスワードハッシュを「シャイニング」します(ハッシュ形式で保存することを望みます)。 しかし、あなたは「シャイニング」してメールを送ります-これはできません。







他のユーザーにユーザーのリストを見てもらう場合、少なくとも「輝く」ことができない列を切り落とすように注意する必要があります。 これは明白な方法で行われます。このビューを作成するとき、読み取り可能なフィールドをリストし、「SELECT *」は実行しません。 長い間PostgRESTでは、あなたが突然焦りを感じた場合、匿名の人にテーブルを見せ、彼がそれを読むことができる機会があります。 ただし、いくつかの個別の列を読み取る権利を削除することができます。 INSERTとUPDATEを使用して、 非常に柔軟に操作することもできます。 たとえば、ユーザーが自分のIDを変更する権利を持ってはならないことは明らかです。 列の権利は、個人が変更する権利を持たないデータを保護するのに役立ちます。



外部文字列へのアクセスを拒否する



これは非常に難しい視界ですが、非常に重要な側面です。他の人に行を変更させないでください。 つまり ビューを更新する機会を与えた場合、実際には、デフォルトですべてのユーザーがAPIを介して他の人の行を更新できます。これは災害です。







これはもう1つのドアで、その閉鎖を自動的に確認する必要があります。 そして、それを閉じる方法は? 最も高度なPostgRESTを使用している場合は、 行レベルのセキュリティを使用します-これが最も好ましい方法です。 古いバージョンを使用している場合、ストアドプロシージャを作成します。PostgRESTはセッション変数(claims.XXXXX)を作成し、誰がこのプロシージャを正確に実行するかを知っており、すべてを確認できます。



性能



典型的な例から始めましょう。ユーザーベースと投稿があるコレクションがあるとします。また、数百万と数百万のブログがあり、ユーザーとコレクションの間の接続があるとします。 以下のスライドでは、4つのテーブル(person、post、collection、person2collection)をマークしました。これは、ソーシャルメディアの標準モデルと標準タスクです。







もちろん、インスタグラムやツイッターなどの巨人はニュースを時系列で表示しませんが、この例では印象の時系列を構築します。



この問題を「正面から」解決するための2つのオプションがあります。 参加するのが怖い場合の最初の方法:最初に投稿を選択し、次にどのコレクションからのものかを知り、コレクションを選択してから著者を選択します。



2つ目は、よりPostgRESTスタイルです。4つのテーブルからJOINを作成すると、すべてが「消化」されます。 たとえば、上記のrow_to_jsonを引用した後、PostgRESTはjsonを返します。jsonには、作成者とコレクションに関する情報を含むjsonが埋め込まれます。



しかし、これらの要求は両方ともパフォーマンスの点で劣っています 。 しかし、3つのリクエスト、 3つのAPIコールがあるため、最初のリクエストははるかに悪いです。 Ruby / PHP / Pythonで記述する場合、あまり心配することはできません;一部のDBMSでは、1つではなく3つの迅速で短いSQLクエリを作成する方が便利です。 ただし、APIを使用してこれを行う場合はまったく異なります。 ある人が別の国から来ており、往復時間が100〜200ミリ秒であり、今では600ミリ秒余分になっているとします 。 200になり、現在は600になります。つまり、最初のオプションはすぐに却下する必要があります。もちろん、可能な場合は、1つの要求ですべてを実行する必要があります。



したがって、ここでの最初のサブレッスンは、まずネットワークの複雑さについて考える必要があるということです。



ところで、リレーショナルデータベースを使用する場合、ページごとのナビゲーションにOFFSETを使用しないでください。 スライドでは、WHEREと以前のIDを使用して行われます。



大量のデータがある場合、数秒または数十秒でも機能するため、stopudovoは2番目の方法で問題を取得します。







私のいくつかを含む多くのプロジェクトがこれに出くわしました。オーストラリアに住んでいる有名なPostgRESTの専門家であるMaxim Bogukにとても助けられました。PGdayに関する彼のレポートのこのプレゼンテーションを強くお勧めします 。 学習した後、次のようなJediのテクニックを習得できます。再帰クエリ、配列、文​​字列の折りたたみ、非常に経済的なLoose IndexScanデータ読み取りアプローチなど。



以下は、最初の2つに似たプロジェクトの1つに対する実際のクエリですが、同じデータで数ミリ秒動作します。







彼は再帰的にタスクを解き、各コレクションから1つの投稿を受け取り、セットを形成し、既に表示可能な25の投稿を収集するまで置換、置換を行います。 とてもクールなこと、勉強することをお勧めします。



PostgRESTを使用する場合、生産性を向上させるための膨大な数のツールがあり、強制的に使用できます。



拡張性



第1レベル:セッションがなく、RESTfulなアプローチがあり、PostgRESTを多数のマシンに配置でき、静かに動作することは明らかです。



第2レベル。 たとえば、読み込みの負荷を調整する必要がある場合は、スレーブにのみアクセスする特別なPostgRESTインスタンスを構成し、ngnixを使用して負荷を分散することもできます。 モノリシックなアプローチとは異なり、ここのすべては透明です。



このトピック全体がオブジェクトリレーショナルマッピングに非常に似ていることに注意してください。 それはもちろん、これはORMではなく、そのようなJSONリレーショナルマッピングです。



この場合、GETがある場合、100%は単なるSELECT読み取りトランザクションです(上記のSELECT / rpc / procedure_nameでない限り)。 そのため、ngnixは、トラフィックの一部を別のホストに送信するように簡単に構成できます。 すべては管理者の手にあり、管理者はngnixを扱います。 これらすべてをまだ必要としない人は、将来、プロジェクトをスケーリングできるようになるでしょう。



質問:マスターのスケーリング方法は? すぐに-何もありませんが、Poctgr​​esコミュニティはこれに積極的に取り組んでいます。







哲学的な側面がまだあります:WebScaleの周りのすべてのこの誇大広告。 あなたがフィールドを掘る必要があるとき、あなたは何を好みます:スペードまたはトラクターを持つ100人のゲスト労働者? PostgreSQLは現在、1台のサーバーで1秒あたり100万トランザクションに近づいています。 実際、これは毎年改良されているトラクターであり、毎年新しいバージョンがリリースされており、非常に高度です。



MongoDBのようなソリューションをインストールする場合、まず、1台のマシンで動作が悪くなり、2番目に、PosgreSQL機能がまったくない-これはトラクターとはほど遠いです。 あなたは、移民労働者のように、それらすべてを心配する必要があります。MongoDB上のサーバーを維持する必要があり、失敗し、いたずらです。



畑を掘るという作業は、コストと時間の両方で、トラクターによってはるかに効率的に解決でき、将来的には改善される可能性があります。



内部で行う価値がないものは何ですか?



答えは明らかです! 外部サーバーを要求する場合、予測できない時間がかかるため、PostgRESTで直接実行しないでください。また、マスターのPosgresバックエンドを理解できない時間保持しないでください。







LISTEN / NOTIFYメソッドを使用する価値があります-これは古くから確立されたものです。 または、「SELECT ... FOR UPDATE SKIP LOCKED」を使用して多くのスレッドで非常に効率的な処理を使用して、データベースにキューを直接実装します。



Node.jsまたはRUBYでスクリプトを作成できます。あるいは、このデーモンはPostgRESTのイベントにサブスクライブします。その後、ストアドプロシージャはこのイベントでメッセージを送信するだけで、デーモンはそれを取得します。



しばらくの間誰も聞いていなかったイベントが突然消える場合は、すべてのキューシステムを変更する必要があります。 これには多くの解決策がありますが、このトピックは非常に重要です。いくつかのリンクを示してください。





そして最後に、約束されたメモ。 これは、今日議論したすべてのリストです。 新しいプロジェクトを開始したり、内部APIを使用するために古いプロジェクトをやり直したりする場合は、これらの点を確認してください。







連絡先とリンク:



メール: ru@postgresql.org

ウェブサイト: http : //PostgreSQL.support

Twitter: https : //twitter.com/postgresmen

YouTube: https : //youtube.com/c/RuPostgres

ミタパス:http://RuPostgres.org



次回のバックエンド会議で、ニコライは引き続きPostgresを大衆に持ち込みます。特に、内部コンポーネントの深い知識を必要としないパフォーマンスボトルネックの半自動検索のための新しいツールを提供すること約束します。



Highload ++ Siberiaのことを忘れないでください。2か月未満の負荷の高いプロジェクトの開発者による夏の会議まで- チケット予約するときです。




All Articles