Web開発
ホビー規模ではWebサーバーのデプロイモデルは破綻する
The web server deployment model breaks at hobby scale (w.on-t.work)
要約
個人が自分のサーバーでホストすることを想定したWebアプリケーションの開発では、ホビー規模ではデプロイモデルが破綻しやすいという問題提起がされています。静的ファイルの配信やキャッシュ戦略において、個人開発者が直面する複雑な課題が、プロフェッショナルな環境とは異なる現実を浮き彫りにしています。
全文翻訳
Webサーバーのデプロイモデルはホビー規模で破綻する
他の人に自分のサーバーでホストしてもらいたいWebアプリケーションを作ろうとすると、その考えを持っただけで、他のプライベートにホストされることを意図したソフトウェアが利用できるいくつかの効率化のトリックからコードベースが締め出されてしまいます。そして、すでに他人がより良く作ったものを、自分で車輪の再発明を強いられることになります。
要件が変わるにつれて追加していくベースラインから始めましょう。プライベートキーが必要以上に広範囲に公開されないように、アプリケーションとは別にTLSを処理する何かが必要です。これにより、アプリケーションコードに影響を与えることなく、証明書の取得方法を変更できます。
ほぼすべてのケースで、最初の部分は比較的強力なWebサーバーになる可能性が高く、その多くの機能の1つとしてリバースプロキシ機能が含まれています。非常に一般的な機能の1つは静的ファイルの提供ですが、これは現在アプリケーションによって処理されています。
#静的ファイル
静的ファイルの提供をリバースプロキシにオフロードするのは悪い考えではありません。その実装は、あなたが選んだ最新のフレームワークに付属しているものよりもはるかに優れている可能性が高く、たとえそうでないとしても、静的ファイルはPythonやNodeのWebサーバーが同時に処理できる限られたリクエストを詰まらせることはなくなります。
これを試してみましょう。アプリケーションまたはリバースプロキシのいずれかがコンテナ化されているか、その他の方法で区画化されている場合、アプリケーションを設定するすべての管理者は、リバースプロキシがアプリケーションとともに配布された静的ファイルにアクセスできるように、これらの区画の1つまたは両方に穴を開ける必要があります。
アプリケーションが最終的にリリースされると、Kubernetesの一部としてのみ配布されている「クラウドネイティブ」なリバースプロキシの1つを使用しているユーザーから問題レポートを受け取ります。アプリケーションにファイルを配信するオプションを再度追加することになり、それが存在することに気づいた全員がすぐにそれを有効にします。
ターゲットオーディエンスがアクセスできる低価格帯のハードウェアの可能性を妨げている非効率性のかなりの部分に貢献してしまったことに気づき、あなたは泣きます。
「プロフェッショナル」な規模ではどうでしょうか?静的ファイルは完全に別個にデプロイされ、おそらくS3バケットなどにデプロイされ、実際のCDNによってフロントエンド化されるため、この問題は発生しません。
#認証されていないキャッシュ
人間またはボットによって、アプリケーションに多くの認証されていないアクセスがあることに気づきます。認証されていないアクセスは常に同じ応答を受け取るため、何も変更されていない場合にこれらの応答を再計算する理由はありません。コンテキスト内で「古い」ページの適切な時間として1時間で十分であると判断します。
Vinyl Cacheのウェブサイトを懐かしく見つめますが、ホビイストのWebサーバーの既存のルーブ・ゴールドバーグ・マシンの一部にすぎないため、実際には要求できないことを完全に理解しています。
落胆して、エンドポイントに必要なCache-ControlとVaryヘッダーを追加します。
No-Vary-Searchについて知り、それがChrome専用であることを発見します。
応答を変更するクエリパラメータの正確なセットを知っていますが、現在いる場所からは何もできません。
Vinylに依存できれば、未使用のクエリパラメータをトリミングできるため、リンクプレビューに関する死んだジョークを復活させようとする人々が、リンクの後に?qweqweaweを追加してキャッシュをバイパスしようとするのを防ぐことができます。
Webサーバーライブラリにキャッシュミドルウェアがあることを発見します。サポートしている機能を確認し、幸運にもCache-ControlのTTLと、おそらくVary以外はサポートしていないことを発見します。
心に希望の光だけを灯して、それを追加します。管理者がすでに優れたキャッシュを設定している場合は、最適な効率のために調整することを期待して、設定スイッチとドキュメントを配置します。
彼らはしません。
アプリケーションがリリースされると、Caddyユーザーから問題が発生します。なぜなら、彼らはCaddyの信じられないほど平均的なキャッシュプラグインを信頼しており、それが気分次第で応答を破損させる可能性があるからです。
別の人がNginxのキャッシュを有効にしましたが、proxy_cache_lockを有効にするのを忘れたため、インストールが依然として詰まっています。
別の人がサイトをCloudflareの後ろに置きましたが、自分のマシンにキャッシュを設定していなかったため、あなたのキャッシュオプションも有効にしました。
無駄にされたメモリの量に顔をしかめます。
また、組み込みのキャッシュミドルウェアが静的ファイルをキャッシュしていることにも気づきます。それらを配信するのは比較的簡単で、OSのディスクキャッシュ機能によってすでにキャッシュされている可能性が高いため、メモリを無駄に消費しているだけです。
ミドルウェアはCache-Controlしか見ないため、ブラウザがクライアント側でベストプラクティスの不変の静的ファイルをキャッシュするのを防ぐことなく何もできません。
あなたは泣きます。
「プロフェッショナル」な規模ではどうでしょうか?彼らはマシン全体を制御しているため、Vinylのようなものを設定し、それを望む正確なキャッシュ動作に合わせて調整できます。まあ、実際には、彼らはそれをCDNにアウトソースしており、それは平均的な仕事をしているかもしれませんが、彼らはキャッシュをこれほど詳細に制御するオプションを持っています。
#認証されたキャッシュ
アプリケーションにもかなりの数の認証されたアクセスがあることに気づきます。おそらく、リモートインスタンスが認証しているフェデレーションを行っているのかもしれません。
それらが取得するデータは、それほど頻繁には変更されず、異なる要求者間で確実に変更されません。
それらを再計算する理由もありません。
より短いタイムアウト、たとえば1分が「古い」応答に適していると判断します。
このキャッシュは、リクエストのバーストを軽減するためにのみ真に意図されています。
キャッシュの前にコードを実行する必要があることを知っているため、データが変更されたときにキャッシュされたデータを無効にできると確信しています。
外部キャッシュをサポートしたい場合、オプションは各キャッシュミドルウェアのプラグインを書き込むか、より現実的には、サポートされているキャッシュミドルウェアを1つだけにして、残りは「コミュニティに任せる」(誰も気にしない)かのどちらかであることをすぐに発見します。
認証を処理し、結果を適切なキャッシュミドルウェアにヘッダーなどで渡すリバースプロキシを書き込みます。
どちらのオプションもソフトウェアのデプロイメントを複雑にするため、どちらも選択しません。
人々がソフトウェアのデプロイメントを気にしないという事実に非常に注意を払っています。指示が「実行して、リバースプロキシをポイントする」よりも長い場合、新規ユーザー向けのポイントアンドクリックインターフェイスにすべてをパッケージ化する「ワンクリックデプロイ」ミドルウェアやオペレーティングシステムの「エコシステム全体」が存在するようになります。
これの利点を認識し、より多くの人々が自分のデータを制御できるようにすることは良い考えです。既存の実装には泣きながらも、その概念をサポートします。
したがって、残りの唯一のオプションを選択します。
外部キャッシュミドルウェアのサポートを停止し、アプリケーションのコードで認証ミドルウェアがキャッシュミドルウェアよりも前に実行されるようにします。
フレームワークのキャッシュミドルウェアが sucks なので泣きます。
「プロフェッショナル」な規模ではどうでしょうか?繰り返しになりますが、彼らはマシン全体を制御しています。どちらのソリューションも選択して機能させることができます。
#その仕事に最適なプログラミング言語
フロントエンドとしてシングルページアプリケーションを正当化するのに十分なインタラクティビティがあります。
しかし、JavaScriptが無効になっているユーザーでも、インタラクションを必要としない部分を読むことができるようにしたいと考えています。
おそらく、このインタラクティビティはログインユーザーにのみ意味があります。
サーバーサイドレンダリングされたシングルページアプリケーションフレームワークを使用することにしました。
competen なオプションはすべてJavaScriptで書かれています。
これは理にかなっています。バックエンドとフロントエンドの両方で同じコードを2回書きたくないからです。
しかし、あなたのアプリケーションはJavaScriptで書かれていません。
Node.jsをアプリケーションに組み込むという、非常に悪い考えを一時的に抱きます。
これは技術的には機能しますが、非常に壊れやすいように感じます。
Node.jsのシングルスレッドの性質により、ロードバランシングのために複数のフロントエンドプロセスが必要になります。
さらに、フロントエンドとアプリケーションをさまざまなリソース使用率メトリックで分離したいと考えているため、どこでopti