こんにちは、
R2に移行しましたが、すべてが完璧に進みました。すべての画像にS3 CDNのURLリンクが設定されています。しかし、1つ問題に気づきました:アバターの読み込みに時間がかかっています。ユーザーのアバターをクリックしたときや投稿の中身を見ているときなど、平均して3〜4秒ほどかかります。これは想定内の動作でしょうか?
こんにちは、
R2に移行しましたが、すべてが完璧に進みました。すべての画像にS3 CDNのURLリンクが設定されています。しかし、1つ問題に気づきました:アバターの読み込みに時間がかかっています。ユーザーのアバターをクリックしたときや投稿の中身を見ているときなど、平均して3〜4秒ほどかかります。これは想定内の動作でしょうか?
ふむ、3つの異なる問題のいずれかだと思うのですが、最も可能性が高いのはリアルタイムでのリサイズです。
アップロードをR2に移行した際、元の画像が移動しました。ただし、Discourseでは投稿用(45px)やユーザーカード用(120px)など、さまざまなサイズのアバターを使用しています。
これらの特定の最適化されたサイズが完璧に移行されなかった場合、またはまだ生成されていない場合、Discourseはユーザーがクリックした瞬間にそれらを同期的に生成する必要があります。
確認方法: ページをハードリフレッシュしてください。最初にアバターが3〜4秒かかるが、2回目には即座に読み込まれる場合、まさにこれが起きていることです。
修正方法: ユーザーが閲覧するにつれてサイズが生成されるため、自然と修正されます。ただし、SSHでサーバーに接続して以下のコマンドを実行することで、サーバーにすべてのアバターをバックグラウンドでプリ生成させ、即座に修正することもできます。
./launcher enter app
rake avatars:refresh
アバターが複数回のリフレッシュ後も毎回3〜4秒かかる場合、ネットワークタイムアウトに遭遇している可能性が高いです。
Cloudflare R2 APIエンドポイントはデュアルスタック(IPv4とIPv6の両方を使用)です。サーバーのドロップレットにIPv6アドレスが割り当てられているが、ホストのIPv6ゲートウェイが正しくルーティングされていない場合、R2バケットへのRuby内部接続はまずIPv6を試み、3秒間ハングし(これはLinuxのデフォルトTCPタイムアウトです)、失敗してからIPv4を使用して即座に成功します。
確認方法: サーバーにSSHで接続し、以下を実行してください。
curl -I -6 https://cloudflare.com
数秒間ハングして失敗する場合、サーバーのIPv6が壊れており、内部のS3 APIチェックごとに3秒の遅延が発生しています。
修正方法: ホストコントロールパネルでIPv6ルーティングを修正するか、ドロップレット全体でIPv6を無効にする必要があります。
サイトがGravatarの更新を確認するように設定されている場合、アバターを描画する前にGravatarの外部サーバーにピングを送信する可能性があります。サーバーの送信接続が遅い場合(これもDNSやIPv6に関連していることが多いです)、アバターの描画がブロックされる可能性があります。
確認方法: サーバーで以下を実行してください。
curl -I -6 https://gravatar.com
3秒間ハングする場合、IPv6が壊れています(上記参照)。
Gravatar関連の修正: Discourseの設定で「Gravatarを自動的にダウンロード」を一時的にオフにし、それが修正されるか確認してください。これが問題だとは思いませんが、もし問題であれば、この設定をオフにしたままにするか、上記2のIPv6ルーティングを修正するか、DNSリゾルバーを変更してください。
お返事が早く、ありがとうございます。以前に「rake avatars:refresh」を試した記憶があるのですが、確信はありません。
以前、アバターを即座に表示させる方法として、一度クリックすると開き、二度目のクリックでは瞬時に表示されるという動作が機能していました。これはおそらくキャッシュによるものだと思います。また、2つ目のヒントを試しましたが、「HTTP/2 301」が返され、他にもいくつかの行が表示されました。3つ目のヒントも同様でした。スナップショットを復元する必要があったため、数日後に再度「avatars:refresh」を実行します。再度ありがとうございます!
Gravatar
server: nginx
date: Mon, 22 Jun 2026 19:29:00 GMT
content-type: text/html; charset=utf-8
content-length: 0
content-language: en
expires: Wed, 11 Jan 1984 05:00:00 GMT
cache-control: no-cache, must-revalidate, max-age=0
x-redirect-by: Gravatar
location: https://en.gravatar.com/
alt-svc: h3=":443"; ma=86400
strict-transport-security: max-age=31536000; includeSubdomains; preload
CF
HTTP/2 301
date: Mon, 22 Jun 2026 19:27:00 GMT
content-type: text/html
content-length: 167
location: https://www.cloudflare.com/
cache-control: max-age=3600
expires: Mon, 22 Jun 2026 20:26:59 GMT
set-cookie: __cf_bm=eBP2aJ7Eg30nHPuvMMNxxKrgNtcNwKs0WDgnYyONeus-1782156420-1.0.1.1-sXpW27iuhGDF615cOfwNFybH4IMxgvZy3uA_3X_o..402T_3KSgT7CSymipL5RjdpGe3raWEqsVxQFFLPKRoDjfoT7B.0rqyDt.osbkOF98; path=/; expires=Mon, 22-Jun-26 19:57:00 GMT; domain=.cloudflare.com; HttpOnly; Secure; SameSite=None
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=QfYqSekEDPJHC2k%2BMjHN0cGjz172tmUWe2GSR8EgwNLh3TGjFYkQ0vwPxlzY1NcBcKFOMaAi4FlgjqjhETOOtHf%2BH9KdQSvqN3OME2Uh1i4nHIw%2Fy1qkvSpf4jxDchM7CaDW80tJkjBV4OqF"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
strict-transport-security: max-age=15780000; includeSubDomains
server: cloudflare
cf-ray: a0fda5d8ecd6b26d-LAX
alt-svc: h3=":443"; ma=86400
返信をいただいたので、CloudflareとGravatarに対する curl コマンドの結果が期待どおりであることを考えると、ほぼ間違いなく問題#1が原因だと確信しています。都合の良い時に rake avatars:refresh を試してみて、うまくいくかどうか教えていただけますか?
リリーさん、こんにちは。まだ同じ問題が発生しています。rake avatars:refresh を実行した後でも、/latest で同じ問題が発生しています。ブラウザと Cloudflare のキャッシュをクリアしてテストしましたが、まだ解決していません。もしかしたら、もう少し待った方がいいのでしょうか? 4500人のユーザーがいるフォーラムでテストしています。
ブラウザやCloudflareのキャッシュをクリアする必要はありません。rake avatars:refresh を多数のユーザーに対して実行すると、処理は即時には完了しません。代わりに、数千のジョブがSidekiqにバックグラウンドで処理されるようキューに入れられ、サーバーのCPU性能に応じて数時間かかることがあります。申し訳ありませんが、Sidekiqの存在や、ユーザー数によっては完了まで時間がかかることを事前に伝えるべきでした。
your-forum.com/sidekiq/queues にアクセスしてキューの状況を確認してください。キューが完全に空になるまで待ちます。Sidekiqの処理が完了すれば、すべてのアバターのサイズがR2バケットに恒久的に保存され、アバターの読み込み速度も通常に戻ると考えられます。
なるほど、他に何か起きているのかもしれません。自分のキューには何もありません。ですが、あるユーザーのアバターをクリックすると、tail -f log/production.log で以下のような出力が確認できます:
Sent file /var/www/discourse/tmp/avatar_proxy/3689d91eb5e1013beef831c585b5e62edeeecbd6.jpeg (0.2ms)
おっと、なるほど。これは決定的な手がかりで、別の問題を示唆していますね。
ログに avatar_proxy が表示されるのは、通常、Discourse が Cloudflare R2 CDN から直接アバターを提供することを拒否していることを意味します。代わりに、Discourse はリクエストを積極的に傍受し、R2 から画像をローカルサーバーの /tmp フォルダにダウンロードしてから、Ruby を使ってブラウザに画像を提供しています。つまり、CDN が完全にバイパスされており、これが3秒の遅延の原因だと考えられます。サーバーがリクエストのたびに手動でファイルをフェッチして読み込んでいるのでしょう:grimacing:
Discourse はごく限られた特定の状況でのみ avatar_proxy を使用し、通常は外部 URL を隠すためのプライバシーまたはセキュリティ設定が原因です。
管理画面の「サイト設定」で以下の設定を確認してください。
「外部システムアバターの URL」を探してください。もしそのボックスに何か入力されている場合(例:/letter_avatar_proxy/v4/... など)、空になるように削除してください。これで、デフォルトの文字アバターがプロキシされるのを防げます。また、「アップロードされたアバターを許可するグループ」も確認し、TL_0 と表示されているか確認してください。
DISCOURSE_S3_CDN_URL も再確認し、末尾にスラッシュがないか、タイプミスがないか確認してください。
カスタムアバターの再マッピング:
データベースには、新しい CDN URL の代わりに生きた R2 バケット URL が残っている可能性が高いです。これらが一致しないため、セキュリティ上の理由からフォラムがそれらをプロキシしているのでしょう。
Rails コンソールで、Discourse が何と戦っているかを確認してください。
./launcher enter app
rails c
アバターの読み込みが遅いユーザー名を選んでください。
u = User.find_by_username("the_selected_username")
u.user_avatar.custom_upload.url
出力に生きたバケット URL が返ってきた場合、以前の再マッピングがすべてを捕捉できていません(サブドメインやスキーマを見落としている可能性があります)。
修正するには、サーバーに SSH で接続し、コンテナに戻ってください(Rails ではなく)(./launcher enter app)、そして再マッピングツールを再度実行して、生 URL を CDN URL に置き換えます(またかよ、という感じですが):
discourse remap "https://<your-raw-cloudflare-url>.r2.cloudflarestorage.com" "https://cdn.your-domain.com"
念のため、2 回目は https:// の代わりに // を使用して実行してください。
余談ですが、好奇心から伺いたいのですが、どのようなホスティングサービスをお使いですか?私もあなたとほぼ同じ構成ですが、この問題はまだ経験していません。そのため、あなたの構成にも興味があり、何かしらの方法で再現を試みたいと考えています。
取得したURLはS3のCDN URLを表示しており、ブラウザで画像を開くことができます。
今回はS3は使用しないことにします。現時点では特に必要ないためです。
私は長年Advinserversを使用しています。
ご協力いただきありがとうございます。大変助かりました。