LotusJeff
(Jeff Cocking)
2025 年 2 月 5 日午後 8:05
1
Discourse の 1RTT の哲学により、アバター画像の提供コードを書き直す時期が来たかもしれません。
アバター画像は、他の画像アップロードと同様に扱われるべきです。アップロード時にリサイズされ、保存され、ファイルシステム/S3/CDN から直接提供されるべきです。
現在の Discourse の方法は、プロキシ方式を使用してアバター画像を提供しています。このアプローチは、不要な HTTP ラウンドトリップと IP アドレスの課題を生み出します。
アバターリクエストの概要は次のとおりです。
初期の Discourse HTML が描画されます。
ブラウザがアバター画像を検出し、Discourse サーバーに画像の要求を送信します。
Discourse サーバーはプロキシとして機能し、ローカルファイルストア/S3/CDN から画像を取得します。
Discourse サーバーが画像を受信します。
Discourse サーバーが画像をブラウザに送信します。
カスタムアバターごとに、1 回の追加 HTTP ラウンドトリップと関連するサーバー処理時間が発生します。典型的なトピックまたはトピックリストには、30 を超えるカスタムアバター画像が含まれる場合があります。私のサイトでは、回避できる 1 日あたり 10K から 20K の追加 RTT と関連するサーバー負荷が発生します。
さらに、アバター画像はサーバーから直接呼び出されます。CDN レベルの保護を行うには、IP アドレスのホワイトリスト登録が必要です。これには、サーバーの IP アドレスではなく、ゲートウェイのホワイトリスト登録が必要です。ホスティング会社は、ネットワークトラフィックのバランスをとるために定期的に変更を行います。私のゲートウェイ IP アドレスは変更/進化します。基本的なアバター画像が機能するために、ソフトウェアは IP アドレスの更新に依存すべきではありません。これは、サポートでの次のインシデントに基づいています。アバタープロキシと CDN のホットリンク保護
パフォーマンスとシンプルさの観点から、アバター画像を Discourse の指定されたファイルストアから直接提供することは可能でしょうか?
「いいね!」 5
Falco
(Falco)
2025 年 2 月 5 日午後 9:29
2
これは確かにアプリの非常に複雑な部分ですね、@LotusJeff 。
その短所の一部に対処するために、最近ホスティングでそれらの往復を減らす方法を開発しましたが、ここで文書化したことはないと思います。それに関する公開ドキュメントはありますか、@david ?
「いいね!」 4
david
(David Taylor)
2025 年 2 月 5 日午後 11:06
3
はい、この GlobalSetting があり、環境変数 DISCOURSE_REDIRECT_AVATAR_REQUESTS=true を設定することで有効にできます。
これにより、プロキシではなく、アバターリクエストはファイルストアへの 302 リダイレクトで処理されるようになります。
それ自体では…あまり良い考えではありません。ブラウザはアバターごとに 2 回の完全な HTTP ラウンドトリップを行う必要があります。したがって、「ホットリンク保護」の問題を解決するかもしれませんが…有効にすることは推奨しません。ユーザーエクスペリエンスが悪化します。
私たちは discourse.org ホスティングでこの設定を使用しています。しかし、Cloudfront CDN で実行されるラムダ関数で補完しています。ラムダ関数は 302 を検出し、それ自体でプロキシを実行します。基本的に、アプリケーションサーバーから CDN にプロキシを移動させます。
「アバターをアセットに直接リンクするように変更できますか」という、より一般的な質問についてはどうでしょうか。アバターの URL はすべての過去の投稿(例:引用)に埋め込まれているため、これは難しいです。動的な /user-avatar/ URL により、ユーザーがアバターを変更した場合でも、それらが機能し続けることができます。残念ながら、そのシステムを変更する予定はありません。
既存のプロキシをユースケースに合わせて機能させる簡単な低リスクの方法(例:アバタープロキシリクエストに特定の HTTP ヘッダーを挿入する GlobalSetting を追加する)があれば、その変更のための PR を受け入れることを検討できます。
「いいね!」 3
LotusJeff
(Jeff Cocking)
2025 年 2 月 6 日午後 3:12
4
上述のどの選択肢も、私の現在の環境では実現可能でも望ましいとも思えません。 この複雑な部分の問題解決を手伝いたいのですが、私はこの技術スタックに非常に新しいため、難しいです。
今のところ私ができる唯一の支援は、古いBAとDev Mgtのスキルを使うことです。 なので、助けになった気持ちで、これが私の考えです。
技術的な難題を見るとき、まず解決を難しくする可能性のある前提条件を考えます。
一つの前提は、更新されたアバター画像を新しいファイル名で保存することです。 人は一つのアバターしか持っていません。私たちはアバターの名前の記録を保持しません。 ポイントは、誰かがアバター画像を更新したとき、既存のアバターと同じファイル名で保存することです。 これは基本的に /user-avatar/ リンクがやっていることです。 迂回策を設ける代わりに、このロジックをアバター作成/更新時に実行します。 これにより、将来の焼き付け投稿に関する過去の投稿の問題が解決されます。
これは一気に変更する大きな変更ですか? いいえ、この変更は数か月にわたって段階的に実装可能であり、サイトのパフォーマンスを徐々に向上させることができます。私たちの開発チームは常に各コードブロックのための機会主義的なコードリストを持っていました。 これらの改善をしたいと思っていましたが、それぞれを個別に行う必要はありませんでした。 他の理由でコードを開放したとき、開発者はまた機会主義的な変更も行いました。 これにより、コードの開発と更新の回数を減らすことで、テストとエラーを最小限に抑えました。
このプロジェクトを次のフェーズに分けて進めると良いでしょう:
アバター画像の保存ロジックを更新し、画像の更新を現在のファイル名を使用して置き換える。
アバター画像のすべての使用箇所を、ディスコースの推奨するファイル保存/配信システムを利用する標準関数に置き換える。これらの変更は数か月をかけて段階的に進め、徐々に新しいアバター表示ロジックへ移行します。
最初の二つが完了したら、コミュニティに対してヒストリカルなアバター画像を焼き付けHTMLから推奨ファイルシステムへ変更し再焼きする手順とコードスニペットを提供します。これは各ディスコースサイトのオーナーの選択次第です。(このコードの指示とスニペットは、生のHTMLの変更に役立ちます)
これらの点はすべて考慮されていると思います。 さらに、古いコードの修正は優先順位が高くないことも承知しています。
もし私に手伝えることがあれば、遠慮なくお知らせください。
追伸。 グローバルヘッダー設定のPRの申し出には感謝します。 もう少し調査を行い、より明確な要件について追って連絡します。ご支援に感謝します。
david
(David Taylor)
2025 年 2 月 6 日午後 3:18
5
残念ながら、ファイルがミュータブル(変更可能)な場合、CDNやエンドユーザーブラウザでのアセットの無限キャッシュを有効にできなくなります。
パフォーマンスへの影響をそれほど 大きくせずにそのようなことを機能させるための戦略はあります。例えば、「stale-while-revalidate」ディレクティブなどです。しかし、それには独自のコストとユーザーエクスペリエンスへの影響が伴います。
「いいね!」 1