Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

パフォーマンス向上・負荷軽減のための対応を行う #185

Closed
takahashim opened this issue Mar 16, 2021 · 42 comments · Fixed by #295
Closed

パフォーマンス向上・負荷軽減のための対応を行う #185

takahashim opened this issue Mar 16, 2021 · 42 comments · Fixed by #295
Labels
enhancement New feature or request

Comments

@takahashim
Copy link
Collaborator

改善詳細 / Details of Improvement

#62 に関連して、アクセスが増えると負荷が大きくなるようなのと、全般的に重そうなので、Decidim固有の対処はさておき一般的なパフォーマンス向上のための対応を行うと改善されるかもしれません。

すぐに思いつくのは以下の2点です。

  • 静的なassetsについて、Cloudfront+S3などで配信させるようにする
  • それ以外についてもCDNを使うことでレスポンスの高速化とサーバーへのアクセス軽減を図る

期待する見せ方・挙動 / Expected behavior

とにかくEBのインスタンスに不要なアクセスが来ないようにしたいところです。

対象インスタンス / Instances

  • 全て
@takahashim takahashim added the enhancement New feature or request label Mar 16, 2021
@takahashim
Copy link
Collaborator Author

ちなみに https://web.dev/measure/ でチェックするとPerformanceの項目が良くないのですが、これは海外のDecidimインスタンスでも同様の傾向があるようでした。

@komtaki
Copy link
Contributor

komtaki commented Mar 28, 2021

@takahashim
Cloud frontの導入でキャッシュ対象になるのはこのあたりでしょうか?

  • /assets 配下
  • cfj-decidim.s3.ap-northeast-1.amazonaws.com

一旦、上記のみでstagingで試してみましょうか?ゆくゆくは、ログイン状態を判定して、未ログインの場合はキャッシュするとかもためしてみる感じで。

Cloud forntは何度か設定したことがあるので、出来ると思います。

@halsk
Copy link
Member

halsk commented Mar 30, 2021

@komtaki ありがとうございます!一度ステージングで試してみたいです。

@komtaki
Copy link
Contributor

komtaki commented Apr 8, 2021

@halsk

stagingでeb本体にcloud forntを入れました。http2有効化、logはs3のバケットに流してます。
時間とかは適当なので、キャッシュの時間とかもっと長くしてもよいかと。

  • /assets/* キャッシュ default 60s。gzip, broti圧縮有効化
  • その他 全てキャッシュしない

方針確認させてください。 👍

s3の方にもサブドメ適応させて、もう一つcloud frontをたてて上記のassetsと同じようにキャッシュ設定するイメージであってますか?具体的なイメージがあれば教えてもらえると助かります。:bow:

キャプチャ

@komtaki
Copy link
Contributor

komtaki commented Apr 19, 2021

@halsk @ayuki-joto

10日以上経ちますが問題なさそうなので、ebの方だけ先に本番にも同様に設定してもよろしいでしょうか?

お手すきの際に、こちら確認いただければ幸いです。:bow:

s3の方にもサブドメ適応させて、もう一つcloud frontをたてて上記のassetsと同じようにキャッシュ設定するイメージであってますか

@ayuki-joto
Copy link
Collaborator

@komtaki
反応遅れて申し訳ありません。
ebだけの設定は、本番には影響ないという認識ですが合っていますでしょうか?

また、今回行った具体的な操作など教えていただければ幸いです。

s3の方にもサブドメ適応させて、もう一つcloud frontをたてて上記のassetsと同じようにキャッシュ設定するイメージであってますか
こちらについては、明日回答させていただきます!

@komtaki
Copy link
Contributor

komtaki commented Apr 19, 2021

ありがとうございます。

cloud formationのMRにコメントを頂いていますが、あちらのテンプレートをベースにリソースを作成しています。

stagingのcloud formationのスタック: staging-decidim-app-cloud-front

流れとしては、下記の4つやりました。

  1. AWSの仕様に合わせて、手動でバージニアリージョンでSSL証明書取得
  2. ebの前段のalbに対して「staging-alb-origin.diycities.jp」でAレコードを発行
  3. cloud formationでcloud front作成
  4. サービスとして提供している「staging.diycities.jp」,「stagingtest.diycities.jp」のドメインをcloud frontのエイリアスに切りえ。

ROUTE53の設定もcloud formationにするか迷いましたが、提供する都市が増える可能性は高そうなのでいったん見送りました。

本番に入れる際には、SSL証明書以外の作業を同様にやる感じですね。albのサブドメは、production-alb-origin.diycities.jpとかで考えています。

ebだけの設定は、本番には影響ないという認識ですが合っていますでしょうか?

DNSの浸透で切り替わるので、瞬断とかはないです。stagingを見た感じ影響はないかと。

http2有効化、logはs3のバケットに流してます。

  • /assets/* キャッシュ default 600s。gzip, broti圧縮有効化
  • その他 全てキャッシュしない

@ayuki-joto
Copy link
Collaborator

ayuki-joto commented Apr 20, 2021

なるほどです!
ありがとうございます!

と言うことは、今後productionでドメインを増やす際に同様の作業が必要ということですね。
作業の確認できたので、

ebの方だけ先に本番にも同様に設定

こちら進めていただいて構わないと思います!
よろしくお願いいたします!

また、#212 こちらstgで問題ないようであればマージして検証してもいいかと思いますがどうでしょうか?

@komtaki
Copy link
Contributor

komtaki commented Apr 20, 2021

承知しました。タイミングを見てebだけ先に設定しちゃいます。

現状の設定で問題なさそうなので、MR #212 もdraft外しました。:bow:

@komtaki
Copy link
Contributor

komtaki commented Apr 21, 2021

@ayuki-joto

ドメインの設定で2点、確認したいことがあります。:bow:

  1. ワイルドカードで受けるレコードと、個別のドメインで受けるレコードがあります。これは何か理由があるのでしょうかhttps://shibuya-goodtalk.diycities.jp などは、ワイルドカードで受けているようです。ワイルドカードだけで問題ないなら、cloud frontにワイルドカードだけ設定して、個別のドメインは削除しようと思います。
  2. https://diycities.jp というドメインは使っていますか?ワイルドカード証明書では、このドメインは適合しないので現在証明書エラーになっていると思います。

キャプチャ

@ayuki-joto
Copy link
Collaborator

@komtaki
対応遅くなってしまい申し訳ありません!

ドメインの設定で2点、確認したいことがあります。🙇

ワイルドカードで受けるレコードと、個別のドメインで受けるレコードがあります。これは何か理由があるのでしょうかhttps://shibuya-goodtalk.diycities.jp などは、ワイルドカードで受けているようです。ワイルドカードだけで問題ないなら、cloud frontにワイルドカードだけ設定して、個別のドメインは削除しようと思います。
https://diycities.jp というドメインは使っていますか?ワイルドカード証明書では、このドメインは適合しないので現在証明書エラーになっていると思います。

こちら僕の方で把握できていない情報になるので、次回打ち合わせ時に聞いて回答させていただきます!

@komtaki
Copy link
Contributor

komtaki commented Jun 24, 2021

@ayuki-joto ↑何か進展ありましたでしょうか? 👀

こちら僕の方で把握できていない情報になるので、次回打ち合わせ時に聞いて回答させていただきます!

@komtaki
Copy link
Contributor

komtaki commented Aug 12, 2021

@ayuki-joto

下記で問題なさそうに見えたので、本番用のcloud frontを作成しました。
あとはDNSをcloud frontに向けるだけとなります。:sweat_drops:

お手数ですが、最終確認をお願いします。

  1. ワイルドカードですべて受ける。
  2. https://diycities.jp というドメインは使っていない。対応しない。

@ayuki-joto
Copy link
Collaborator

@komtaki ありがとうございます!
こちら月曜の定例で確認します!

@ayuki-joto
Copy link
Collaborator

@komtaki

ワイルドカードですべて受ける。
https://diycities.jp というドメインは使っていない。対応しない。

こちら問題にないことを確認しました!

また今後は,diycities.jpではなく,makeour.cityのドメインで運用するようになるのでこちらの対応も相談したいです!
現在makeour.cityのドメインは別のプロジェクトで管理している状況です!

@komtaki
Copy link
Contributor

komtaki commented Aug 17, 2021

承知しました。では段階的に対応しますね。

  1. DNS側の調整
  • ワイルドカードですべて受けるよう、既存の本番のサブドメを削除
  • https://diycities.jp ドメイン削除
  1. cloud frontにDNSを切り替えという形で。

また今後は,diycities.jpではなく,makeour.cityのドメインで運用するようになるのでこちらの対応も相談したいです!
現在makeour.cityのドメインは別のプロジェクトで管理している状況です!

どうなっているのかよくわかってないので、適当なことしか言えませんが。AWSの別プロジェクトという意味でしたら、そちらでも同じテンプレートでcloud frontを作成するのが良いかと思います。

@komtaki
Copy link
Contributor

komtaki commented Aug 18, 2021

1.DNS側の調整

  • ワイルドカードですべて受けるよう、既存の本番のサブドメを削除
  • https://diycities.jp ドメイン削除

こちら完了しました。来週あたりタイミングをみて、DNSをcloud frontに切り替えます。

@komtaki
Copy link
Contributor

komtaki commented Aug 22, 2021

Cloud Front経由のDNS切り替え完了しました。主な変更は下記です。
何かありましたら連絡お願いします。

js, cssの圧縮でpage insightでも少しスコアがあがったようです。:rocket:

  • /assets/* キャッシュ default 60s。gzip, broti圧縮有効化
  • http2有効化

before

before

after

after

@komtaki
Copy link
Contributor

komtaki commented Aug 22, 2021

@ayuki-joto

現在makeour.cityのドメインは別のプロジェクトで管理している状況です!

ちなみにこちらはどんな感じで進んでるんですか?切り替わり時期とか。AWSの別プロジェクトということは、全て作り直しているのでしょうか?私もawsの権限もらった方がいいですかね? 🤔

@ayuki-joto
Copy link
Collaborator

ayuki-joto commented Aug 22, 2021

@komtaki
対応ありがとうございます!!

makeour.cityドメインに関してですが,今後作られるものをmakeour.cityドメインで運用をするという方針です!
なので既存のものはそのままの運用になります!
スクリーンショット 2021-08-23 2 52 58
ちなみにmakeour.cityに関しては現在こちらの設定が入っているのみです!
cloud frontに関しては対応方法教えていただければ僕の方で対応できると思います!

@komtaki
Copy link
Contributor

komtaki commented Aug 23, 2021

@ayuki-joto
ありがとうございます。

せっかく作り直すなら、VPCとかも根本的に見直してる感じですかね?RDS作成時しか対応できなさそうなDB暗号化のisuue #179もあがってましたし。

いつから運用にのる予定ですか?

↓構成とかがわからないのでざっくりした対応方法ですが、基本この流れでいけると思います。
#185 (comment)

@ayuki-joto
Copy link
Collaborator

@komtaki
現在,decidimのv0.23.5の環境に切り替えるため環境の複製を行なっているのですが,
現在のドメインを新環境に向ける場合は
*.diycities.jpの宛先がcloudfrontに向いているものを新しい環境の方に移行でいいでしょうか?
production-alb-origin.diycities.jpこちらは一旦触らない認識です!

安定稼働して問題ないと判断した際には今のmatestrの環境の方にマージしてdbを入れ替えて対応する予定です!

@komtaki
Copy link
Contributor

komtaki commented Sep 6, 2021

@ayuki-joto

現在のドメインを新環境に向ける場合は
*.diycities.jpの宛先がcloudfrontに向いているものを新しい環境の方に移行でいいでしょうか?
production-alb-origin.diycities.jpこちらは一旦触らない認識です!

Cloud Frontを通さないなら、その*.diycities.jpをElastic beanstalk環境のドメインに変えるでいいと思います。:+1:

@ayuki-joto
Copy link
Collaborator

@komtaki @image
ルール展にてこちらのエラーが発生してるようなのですが何か心当たりありますでしょうか?

@komtaki
Copy link
Contributor

komtaki commented Sep 13, 2021

特に心当たりはないです。作業もしてないですし。今は特に問題はなさそうですね。

https://rules-2121.diycities.jp/

可能性としては、サーバー高負荷でElastic beanstalkのレスポンスが遅かったとかですかね?

@ayuki-joto
Copy link
Collaborator

こちら10日からたびたび発生してるようで...ちなみにtimeoutに関してはnginxのものが適用されるのでしょうか?
ちなみにwafのLogとかってどこかでみれたりしますでしょうか?

@komtaki
Copy link
Contributor

komtaki commented Sep 13, 2021

timeoutはCloud Frontのデフォルト値の10sです。

wafはブロックしてないので、ログ出してないです。一応ダッシュボードから、総リクエスト数やルールごとの脅威検知数は見れます。ただ、その画面だとwafを通った後に見えるので関係なさそうです。

Cloud Frontのログは全てs3にあるので、詳しい時間とかがわかればそちらから調べられると思います。そのうちathenaとかで見れるようにしたいのですが、現状gzipで細かく分かれたファイルなのでかなり探しづらい気がします。

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/http-502-bad-gateway.html

@ayuki-joto
Copy link
Collaborator

なるほど!
timeoutの調整は必要かもしれませんね.今回のルール展ではコメント数が多すぎて,処理に時間がかかっているので...
今後の対応は一旦検討中ですが,今後も起こり得るかと思うので...

ただ今回の問題に関しては502のエラーなのでまたtimeoutとは別かもしれませんね...

Cloud Frontのログは全てs3にあるので、詳しい時間とかがわかればそちらから調べられると思います。そのうちathenaとかで見れるようにしたいのですが、現状gzipで細かく分かれたファイルなのでかなり探しづらい気がします。

なるほど!ダメもとで漁ってみます!!

@komtaki
Copy link
Contributor

komtaki commented Sep 14, 2021

失礼しました。接続タイムアウトは10sでしたが、レスポンスタイムアウト(オリジンからのレスポンスを待つ時間)は30sになってました。:sweat_drops:
60sまでは伸ばせそうですが、根本解決にはならないで避けたいところ。

個人的にはインフラまわりをいじってないので、Elastic Beanstalkの問題だと思うんです。

HTTP 502 ステータスコード (Bad Gateway) は、CloudFront がオリジンサーバーに接続できず、リクエストされたオブジェクトを提供できなかった場合に返されます。

なんとかCloud Frontのキャッシュに載せられないですかね?正直ログインしてない時とか全部キャッシュに載せてもいい気がするんですが、使えそうなheaderとかcookieが見つからず。Cache-controlヘッダーとかついているものの、どこまで使えるのか

@komtaki
Copy link
Contributor

komtaki commented Sep 14, 2021

@ayuki-joto

athenaでcloud frontのログをSELECTできるようにしました。
直近s3のログ増加量だと1年運用しても1GB超えないので、一旦パーテーションなしで問題ないと判断しました。

9月10日ではなく導入時から502出てますね。以前から話題になってるdebatesばかりです。
下記で確認できます。

SELECT *
FROM production_cloud_front_log
WHERE sc_status = '502' ORDER BY request_date;

テーブル作成DDLは下記ほぼそのままです。:eyes:
https://dev.classmethod.jp/articles/athena-cloudfront-log-activity/

@ayuki-joto
Copy link
Collaborator

@komtaki 
相談なのですが、現在同じインスタンスにsidekiqと、appのコンテナをたてて、nginxで処理をappに流すような構成になっていると思うのですが、こちらsidekiqを別インスタンスに分けるような対応方法何かありますでしょうか?
メールが大量に飛んだ際に負荷がかかっている時があったので、原因の切り分けのためにここを分けたいと考えています!

また, #223 の対応で、本番の環境をproductionから、production-v0-23-5に切り替える方法でデプロイしたのですが、こちらをgithub actionsで対応させる際には、

echo "IMAGE_TAG_PREFIX=production" >> $GITHUB_ENV
echo "EB_ENVIRONMENT_NAME=production" >> $GITHUB_ENV

この部分を書き換えるだけでいいのでしょうか?

@komtaki
Copy link
Contributor

komtaki commented Oct 12, 2021

相談なのですが、現在同じインスタンスにsidekiqと、appのコンテナをたてて、nginxで処理をappに流すような構成になっていると思うのですが、こちらsidekiqを別インスタンスに分けるような対応方法何かありますでしょうか?
メールが大量に飛んだ際に負荷がかかっている時があったので、原因の切り分けのためにここを分けたいと考えています!

以前言ったようにECSに乗せ換えるくらいしか思いつかないです。elasticbeanstalkのworker環境とかでは代替できないので、elastic beanstalkの限界ですね。ほかにもヘルスチェックに失敗したときに、再起動しなかったり今の構成は課題がありますね。

この部分を書き換えるだけでいいのでしょうか?

良いと思います。

@ayuki-joto
Copy link
Collaborator

以前言ったようにECSに乗せ換えるくらいしか思いつかないです。elasticbeanstalkのworker環境とかでは代替できないので、elastic beanstalkの限界ですね。ほかにもヘルスチェックに失敗したときに、再起動しなかったり今の構成は課題がありますね。

んーーー...なるほど、どこかのタイミングでecsでの管理に切り替えるとかは検討する必要があるかもしれませんね...
ただ、ecsに全部置き換えちゃうとかなりの修正と、管理コストがかかりそうですね...

@komtaki
Copy link
Contributor

komtaki commented Oct 14, 2021

ECS Fargateだったら、管理コストは今と大して変わらないと思います。本職でECS運用してます。大きく上げられるメリデメは下記ですが、個人的にはメリットが上回ると思います。

  • sshが不可(セキュリティ的にはメリット)
  • プロセスが隔離でき、sidekiqやwebが独立してスケール可能
  • 現状の構成のまま移行して、EC2料金がざっくり1.2倍
  • ヘルスチェック失敗で勝手にインスタンスが入れ替わる
  • Elastic beanstalkと同様インスタンスのメンテは不要

もちろん移行コストは多少はかかります。ただElastic beanstalkにデプロイするdocker-composeが、ほぼそのままECSのデプロイに使えます。またECRやパラメーターストアもそのまま使えるので、作業は.ebextensionsを書き直すくらいでそこまで多くないです。

AWS WAFの導入が終われば検討してもいいかなと思ってます。

@takahashim
Copy link
Collaborator Author

takahashim commented Oct 14, 2021

sshはできないにしても、ECS Execでログインできればそれで事足りるんではないかと思いますが、どんなもんでしょうか(そもそも私はログインしないのでアレですが…)

@komtaki
Copy link
Contributor

komtaki commented Oct 16, 2021

ECS Execがあれば十分だと思いますね。ec2のメンテナンスはしないですし、コンテナの外で作業することは基本ないので。

@ayuki-joto
Copy link
Collaborator

@komtaki
なるほど、Fargateはかなり有力そうですね!
これも後ほど対応で良いかと思います!

それと、cloud frontの件ですが、現状のルール?展での展示が終わっていないので、timeout問題が本質的に解決できていない可能性があります!
なので、可能であればcloud frontのtimeoutをnginxに対応した時間(現在は180s)に変更することは可能でしょうか?
その対応を待ってcloud frontに流すように変えたいと思います!

@komtaki
Copy link
Contributor

komtaki commented Oct 19, 2021

@ayuki-joto

失礼しました。接続タイムアウトは10sでしたが、レスポンスタイムアウト(オリジンからのレスポンスを待つ時間)は30sになってました。💦
60sまでは伸ばせそうですが、根本解決にはならないで避けたいところ。

#185 (comment)

180sは無理です。1か月前にも言った通り、最大60sまでです。

@ayuki-joto
Copy link
Collaborator

@komtaki
確認漏れでした。すみません。
ルール展期間中だけでも60sの対応できそうでしょうか?

@komtaki
Copy link
Contributor

komtaki commented Oct 22, 2021

@ayuki-joto 本番、stagingともに60s変更しました。

@komtaki
Copy link
Contributor

komtaki commented Oct 22, 2021

カスタマーサポート上げれば、時間は伸ばせる可能性があります。ただ接続時間をのばすせば実行に時間のかかるリクエストが増えたときに、コネクションが切れずコネクションが増加しさらなる負荷上昇につながります。

180という数字がどうやって計算されたのか知らないですが、過度にタイムアウトを伸ばすのはよくないと思います。

@takahashim
Copy link
Collaborator Author

以前はたまに遅いトランザクションがあったので伸ばしたいという話になっていたかと思うのですが、その後アプリ側も改善し、最近(ここ1週間)では長くてもほとんど20秒前後で済むようになっているので(1件だけ履歴を直接見てるやつで極端に遅いのがありましたが、これは諦めた方が良さそう)、とりあえず60sで様子を見るでよさそうです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants