Slide 1

Slide 1 text

計測ことはじめ
 〜アプリケーションを知るために〜
 PHPerKaigi 2022
 2022.4.10
 清家史郎
 1


Slide 2

Slide 2 text

推測するな、計測せよ
 データはすべてを決定づける
 推測による行動を行うのではなく、
 計測した「データ」を元に原因を特定して、対策を講じる
 2


Slide 3

Slide 3 text

自己紹介
 清家 史郎
 @seike460
 - ID
 - GitHub:seike460
 - Twitter:@seike460
 - Work at
 - 株式会社 Fusic (フュージック)
 事業本部/技術開発第一部門
 - チームリーダー/エバンジェリスト/プリンシパルエンジニア 
 - Skill
 - PHP/Go/AWS
 - Personal
 - Fukuoka.php Organizer
 - 46fm パーソナリティ
 3


Slide 4

Slide 4 text

Yagula リリースしました!
 4


Slide 5

Slide 5 text

Agenda
 5
 1. 計測ことはじめ
 2. 計測対象
 3. 計測実践
 4. まとめ
 5. AppIndex


Slide 6

Slide 6 text

01 計測ことはじめ


Slide 7

Slide 7 text

計測ことはじめ
 7
 計測とは 対象をあらゆる尺度から数値化して、数値化したものをもとに判定をすること Webシステムにおける計測とは アプリケーションをあらゆる角度から数値化して、数値化したものをもとに判定をすること アプリケーションを理解し、改善に繋げる

Slide 8

Slide 8 text

再現性のある計測
 8
 再現性 何度行っても同じ結果、判断が得られる事が重要 プログラマーにおける経験に頼らない対応を行う 可視化 自分たちが理解しやすい形に変換することで、 特に難しい判断の部分の負荷を下げる

Slide 9

Slide 9 text

計測で解消すべき事象
 9
 パフォーマンス 正常系としてアプリケーションは動作するが、パフォーマンスの問題がある アプリケーションの価値に直結する リソース効率 必要以上にサーバーリソースを消費してしまい、高いスペックを必要としている サーバーリソースの柔軟性が高い昨今では、コストメリットに繋がる 問題の可視化・特定 データ量の多さから認識出来ていなかった問題を認識する エンジニアの知識量、経験に頼った判断の難易度を下げる

Slide 10

Slide 10 text

02 計測対象


Slide 11

Slide 11 text

Webアプリケーションにおける計測対象
 11
 - Webサーバー
 - スループット
 - PHP(アプリケーションサーバー) 
 - データベースサーバー
 - フロントエンド


Slide 12

Slide 12 text

Webサーバー
 12
 Webサーバー
 - 静的ファイルへのリクエスト数からキャッシュすべきファイルの特定 
 アクセスされたURLのランキングや時間分布などから 
 認識が難しい対処すべき問題の優先度を判断が可能 


Slide 13

Slide 13 text

スループット
 13
 スループット
 - ネットワークの外側から、アプリケーションの応答速度の計測 
 バーストアクセス発生時のアプリケーションの限界や、 
 限界を決めるボトルネックになるサーバーの特定に繋がる 


Slide 14

Slide 14 text

PHP(アプリケーションサーバー)
 14
 PHP(アプリケーションサーバー) 
 - プロファイラを使うことでPHPの処理を計測して可視化 
 特に認識の難しい関数レベルでの処理効率を認識することで、 
 パフォーマンスとリソース効率両方の改善が可能 


Slide 15

Slide 15 text

データベースサーバー
 15
 データベースサーバー
 - スローログにて遅いSQLの特定後、
 対象SQLのEXPLAIN結果を計測することで、 DB Indexの不備やそもそものSQL改善に繋げる


Slide 16

Slide 16 text

フロントエンド
 16
 フロントエンド
 - 各種リソースの不適切な容量での配信やフロントエンドから検知可能な問題の特定
 - アクセシビリティやSEOなどのフロントエンドにおける適切な状態をチェック


Slide 17

Slide 17 text

03 計測実践


Slide 18

Slide 18 text

サービス利用


Slide 19

Slide 19 text

SaaS
 19


Slide 20

Slide 20 text

クラウドサービス
 20


Slide 21

Slide 21 text

今回は自分たちで出来ることを考える
 21


Slide 22

Slide 22 text

Webサーバー


Slide 23

Slide 23 text

アクセスログの解析
 23
 まずは実世界の事象に対する計測を行うため 
 実際のアクセスログに対する解析を行います 
 ここではApacheでもNginxでも簡単に可視化できる「GoAccess」を利用します。 
 https://goaccess.io
 


Slide 24

Slide 24 text

アクセスログの解析
 24
 状況理解に以下の指標を利用
 
 - リクエストされたURL
 - 静的ファイルリクエスト数 - 時間分布 - HTTPステータスコード リクエストの多い静的ファイルに対するファイルのキャッシュ戦略立案や、 システム利用が多い時間帯の特定などに利用します。 リクエストされたURLをもとに、負荷テストを行うべき URLも特定できます。

Slide 25

Slide 25 text

スループット計測


Slide 26

Slide 26 text

スループット計測
 26
 スループット計測はLocustを利用します。  https://locust.io Python製ではありますが簡単なスクリプトでログインなどの処理も可能で 
 ネットワークの外側から少しづつ負荷を上昇させることが出来るます。 
 簡単にWebアプリケーションのスループットの閾値を測定することが出来ます。 


Slide 27

Slide 27 text

サーバーリソースの確認
 27
 リクエストを徐々に増やしてスループットの閾値に到達した際に、
 閾値を決定づけるボトルネックになっているサーバを探します。
 サーバーの特定には各サーバのリソース状況を参照します。
 可能ならAmazon CloudWatchなどのメトリクスを計測できる 外部サービスを利用します。今回はできる限り低負荷のコマンドを駆使します。
 
 - 処理待ち状況、CPUの負荷
 - ディスクの負荷
 - メモリの負荷


Slide 28

Slide 28 text

処理待ち状況、CPUの負荷
 28
 サーバの処理待ちの状況を確認するにはLoad Averageを確認します。 
 初期アプローチとしては処理コストが少ない「uptime」を使うのが適切です。 
 
 CPU状況も合わせて確認するには「htop」を使うと便利です。 
 CPUのコア数以上の処理待ちがある場合、 
 そのサーバーがボトルネックになっている可能性が高いです。 


Slide 29

Slide 29 text

メモリの負荷
 29
 メモリを100%使い切っている場合、スワップメモリを利用することになります。 
 スワップメモリは、ディスクをメモリ領域として確保して利用する為、 
 実質ディスクI/Oを発生させる事になります。 
 ディスクは非常に低速なデータ領域なのでボトルネックになる可能性が高いです。 
 
 「htop」や「vmstat」でスワップメモリの状況を確認出来ます。 


Slide 30

Slide 30 text

ディスクI/Oの状況
 30
 ディスクはデータの読み書きをする上で、一番低速な機器となります。 
 ディスクI/Oが大きい時は、パフォーマンス劣化の原因になっている事が多いです。 
 
 「vmstat」でディスクの読み込み、書き込みを確認する事が出来ます(bi / bo) 


Slide 31

Slide 31 text

PHPプロファイリング


Slide 32

Slide 32 text

PHPのパフォーマンス測定
 32
 負荷が高そうなURLの特定ができた場合、URLにて動作する 
 PHPのどの関数で問題が発生しているのかをプロファイラーを用いて確認します。 
 OSSになっているXdebugが比較的気軽に導入することが出来ます。 
 https://xdebug.org


Slide 33

Slide 33 text

Xdebug x qcachegrind
 33
 Xdebugにてプロファイルcachegrind.outを取得します。
 具体的な利用方法はこちらの記事をご確認ください。[tech.fusic.co.jp xdebug]で検索
 こちらのプロファイルを「qcachegrind」に読み込ませます。
 すると右図の用に図が生成出来ます。 
 
 - どの関数から呼び出されているか 
 - 処理を専有している関数
 - 繰り返し実行されている回数


Slide 34

Slide 34 text

qcachegrind
 34
 Called
 呼出し回数
 
 Self
 自身の実行時間


Slide 35

Slide 35 text

データベース
 実行計画


Slide 36

Slide 36 text

遅いSQLの特定
 36
 PHPプロファイリングにて時間がかかっているのがRDB操作の関数であったり、 
 DBサーバのリソース枯渇している場合、RDBにボトルネックがあることがわかります 
 その場合、まずはスロークエリログにて問題の特定を行います。 
 今回はPostgreSQLを使った流れを記述しますが、設定内容は以下の通りです。 
 
 - PostgreSQL
 - log_min_duration_statement - MySQL
 - slow_query_log、long_query_time、log_queries_not_using_indexes、slow_query_log_file


Slide 37

Slide 37 text

pgBadgerによるスロークエリ可視化
 37
 スロークエリが大量に発生する時は、pgBadgerなどのツールを使って可視化します。(MySQLはanemoeater)
 図のようにスロークエリの可視化が出来ます。
 必要な設定に本番運用時に負荷がかかる設定を含みますので
 難しい場合はlog_min_duration_statementにより長い値を入れて本当に遅いSQLのみを抽出後
 以下のログのような「duration: XxxxX ms」と記述されているログを探して対処します。
 user=postgres,db=postgres LOG: duration: 67.301 ms statement: create database phperkaigi;


Slide 38

Slide 38 text

SQLの実行計画
 38
 スロークエリログにより、遅いSQLの特定が行えたら 
 対象SQLに対して実行計画を見て計測していきます。 
 
 実行計画を見ていくのであれば、最終的にどこが問題になっているかを 
 自分で判断していく必要があります。 


Slide 39

Slide 39 text

SQLの実行計画
 39
 https://github.com/simon-engledew/gocmdpev 
 そこで実行計画の問題を可視化してくれるgocmdpevを使います。 
 こちらを利用すると、実際の問題点を可視化してくれる為 
 適切な対応が取りやすくなります。 


Slide 40

Slide 40 text

フロントエンド


Slide 41

Slide 41 text

Lighthouse
 41
 フロントエンドの測定には 
 Google Chromeの開発者ツール 
 標準の「Lighthouse」を利用 
 
 パフォーマンスの他にも、 
 アクセシビリティやSEOの 状況も計測出来ます。

Slide 42

Slide 42 text

実際のパフォーマンス問題
 42
 実際に問題が…
 - 画像サイズ
 - widthとheight
 記述漏れ


Slide 43

Slide 43 text

残存事象だけで判断しなければならないわけではない
 残された事象だけで、適切な判断を行うのは職人技
 全エンジニアが職人になどなれるはずがない
 何よりも頼りになる「データ」収集、計測して原因を特定し、
 適切な優先順位をもとに対策を講じる
 43


Slide 44

Slide 44 text

まとめ
 Point 3
 様々なOSSを利用することで、作業のコストだけで計測を始める事が出来ます。 
 44
 推測するな、計測せよ。再現性のある対策を行いましょう。
 Point 1
 Point 4
 データの収集と計測、適切なステップを踏んで対処を行う 
 
 鍵は可視化。難しい判断の部分の負荷を下げましょう。
 Point 2


Slide 45

Slide 45 text

ご清聴いただきありがとうございました
 Thank You We are Hiring !
 https://recruit.fusic.co.jp/


Slide 46

Slide 46 text

Appendix
 05

Slide 47

Slide 47 text

CloudWatch (リソース計測) 
 47
 メトリクスデータを取得
 負荷がかかっているサーバーの 
 負荷を増やさずに計測が可能 
 - CPUの使用率
 - ディスクのI/O


Slide 48

Slide 48 text

RDS Performance Insights(DB計測)
 48
 RDS(DB)パフォーマンス可視化
 どのオペレーションに
 時間がかかっているかを計測可能 
 - 各オペレーションコスト
 - Insert
 - Update
 - Delete
 - fetch


Slide 49

Slide 49 text

RDS Performance Insights 
 49
 スロークエリログのように特に負荷がかかっているSQLの抽出を行ってくれる 
 こちらをひたすら解決すれば、パフォーマンスの改善が見込める 


Slide 50

Slide 50 text

CloudWatch RUM(フロントエンド) ウェブバイタル
 50
 ウェブバイタル
 レイテンシー状況の可視化


Slide 51

Slide 51 text

ページロードのステップ(httpsサイト)
 51
 ページロードのステップ
 どこのステップで時間がかかっているかを可視化 


Slide 52

Slide 52 text

ユーザジャーニー
 52
 ユーザジャーニー
 ユーザーの行動の可視化