Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DMMプラットフォームを支える負荷試験基盤

yuyu_hf
PRO
November 27, 2022

 DMMプラットフォームを支える負荷試験基盤

CloudNative Days Tokyo 2022の2022.11.22(火) 13:20-14:00 Track Eの発表で使用したスライドです。

yuyu_hf
PRO

November 27, 2022
Tweet

More Decks by yuyu_hf

Other Decks in Technology

Transcript

  1. © DMM.com DMMプラットフォームを支える負荷試験基盤 CloudNative Days Tokyo 2022 合同会社DMM.com プラットフォーム事業本部 いっぬ(@yuyu_hf)

    1
  2. © DMM.com 本発表で話すこと • 負荷試験基盤を開発するときのPDCAの実施方法 • 負荷試験基盤の具体的な仕組み 2

  3. © DMM.com DMMプラットフォーム DMMプラットフォームとは、DMMの各サービスで共通して使われる基盤 ex) 会員の管理、ユーザーの認証、認可、各種決済周り、DMMポイントやtoreta+といっ た電子マネーの仕組みを提供 3

  4. © DMM.com 負荷試験基盤をつくった動機 負荷試験をするためのエコシステムがなく、ノウハウの共有ができていなかった • 開発効率が悪い • 各チームで同じようなツールを再生産していた • 普段使ってない言語の学習コストが高い

    (ex. Goを書いてるチームがGatling(Scala)使ってる) DMMプラットフォームのクラウド移行計画 • DMMプラットフォームのアプリケーションの多くはオンプレにある • アプリケーションのクラウド移行時に負荷試験をする予定がある 4
  5. © DMM.com MVP(Minimum Value Product) 試験スクリプトが書ける • 試験をプログラマブルにしたい • 試験共通の仕組みを用意したい

    分散負荷試験ができること • 単一のマシンでかけられる以上の負荷が必要 レポートを出力すること • 負荷試験の結果を社内で共有したい • 各アプリケーションの性能をいつでも見れるようにしたい 5
  6. © DMM.com 負荷試験基盤のプロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 6
  7. © DMM.com 負荷試験基盤のプロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 7
  8. © DMM.com ヒアリングシート • プロダクト名 • プロダクトの環境 • 負荷試験の実施時期 •

    負荷試験の経路 • 負荷試験の経路の理由 • 負荷試験基盤を利用したいか 8
  9. © DMM.com ヒアリングシート 9

  10. © DMM.com Slackで呼びかけ 10

  11. © DMM.com ヒアリングシートからわかったこと • 2022年4-5月くらいに負荷試験の利用予定が多い • STG環境の共通インフラ基盤(マルチテナント型のGKE)にデプロイしたアプリケー ションへの負荷試験が多い 11

  12. © DMM.com MVP • 試験スクリプトが書ける • 分散負荷試験ができること • レポートを出力すること •

    STG環境の共通インフラ基盤(マルチテナント型のGKE)のアプリケーションへの負 荷試験のサポート • 2022年4-5月までにリリースする 12
  13. © DMM.com 負荷試験基盤のプロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 13
  14. © DMM.com Design Doc 14

  15. © DMM.com Design Doc(Goals) 15

  16. © DMM.com Design Doc(Non-Goals) 16

  17. © DMM.com Design Doc(Architecture) 17

  18. © DMM.com 負荷試験基盤のプロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 18
  19. © DMM.com プロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    • 負荷試験フレームワーク • 負荷試験基盤のアーキテクチャ • テンプレートファイルの活用 4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 19
  20. © DMM.com プロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    • 負荷試験フレームワーク • 負荷試験基盤のアーキテクチャ • テンプレートファイルの活用 4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 20
  21. © DMM.com 負荷試験フレームワーク • 試験スクリプトが書ける • 分散負荷試験ができること • レポートを出力すること •

    STG環境の共通インフラ基盤(マルチテナント型のGKE)のアプリケーションへの負 荷試験のサポート • 2022年4-5月までにリリースする 21
  22. © DMM.com 負荷試験フレームワークへの要望 Goで試験スクリプトが書ける • プラットフォーム事業本部では、技術戦略として開発言語にGoを採用 • バラバラな言語を使われるとSDKやノウハウの共有ができない 22

  23. © DMM.com 負荷試験フレームワーク • Goで試験スクリプトが書ける • 分散負荷試験ができること • レポートを出力すること •

    STG環境の共通インフラ基盤(マルチテナント型のGKE)のアプリケーションへの負 荷試験のサポート • 2022年4-5月までにリリースする → Locust + Boomer(Locust Extensions) 23
  24. © DMM.com Locust Locustは、Pythonで書かれた負荷試験フレームワークです 特徴 • 分散負荷試験ができる • Pythonで試験スクリプトが書ける •

    試験後に、試験結果のレポートを出力してくれる • 試験を制御するWebUIを提供してる • カスタマイズ可能である(ex. Locust Extensions) 24
  25. © DMM.com Locustの分散負荷処理の仕組み master • 試験を管理するアプリケーション worker • 負荷をかけるアプリケーション 25

    master worker (Python) worker (Python) app
  26. © DMM.com Boomer BoomerはLocust ExtensionsのGoライブラリ Locust workerのインターフェースを満たせば 任意の言語でLocust workerの試験スクリプト を実行できる

    26 master boomer (Go) boomer (Go) app
  27. © DMM.com Boomerの使い方 BoomerのRun関数にtask構造体の変数をセットし、実行する 27

  28. © DMM.com Boomerの使い方 task関数では、負荷リクエストの成否、レイテンシ、エラー内容をLocust masterに送信し ている 28

  29. © DMM.com プロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    • 負荷試験フレームワーク • 負荷試験基盤のアーキテクチャ • テンプレートファイルの活用 4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 29
  30. © DMM.com 負荷試験基盤のアーキテクチャ 30

  31. © DMM.com 負荷試験基盤のアーキテクチャ 31 GitHubリポジトリに試験スクリプトをPush

  32. © DMM.com 負荷試験基盤のアーキテクチャ 32 GitHub Actionsのworkflowから試験を実施する

  33. © DMM.com GitHub Actionsのworkflow 33

  34. © DMM.com GitHub Actionsのworkflow 負荷試験基盤のコードを管理するGitHubリポジトリでworkflowを管理している 34

  35. © DMM.com GitHub Actionsのworkflow 負荷試験基盤のユースケースごとにworkflowを用意している 35

  36. © DMM.com GitHub Actionsのworkflow 36

  37. © DMM.com 負荷試験基盤のアーキテクチャ 37 ②コンテナイメージを GARにPushする ①コンテナイメージを buildする

  38. © DMM.com 負荷試験基盤のアーキテクチャ 38 Podをデプロイする ステージング環境の GKE/EKS

  39. © DMM.com 負荷試験基盤のアーキテクチャ 39 試験の開始をSlack通知する

  40. © DMM.com 試験開始のSlack通知 Datadogのログとトレースを見て 試験が正常に実施されているか確認する 40

  41. © DMM.com 負荷試験基盤のアーキテクチャ 41 Locust masterは指定したWorker数分の コネクションが作成されるまで待つ

  42. © DMM.com 負荷試験基盤のアーキテクチャ 42 負荷リクエストをアプリケーションに送る

  43. © DMM.com 負荷試験基盤のアーキテクチャ 43 負荷リクエストのメトリクス(成否、レイテンシ、エ ラー内容)をLocust masterに送る

  44. © DMM.com 負荷試験基盤のアーキテクチャ 44 ログとトレースをDatadogに送る

  45. © DMM.com 負荷試験基盤のアーキテクチャ 45 試験レポートをGCSにアップロードする

  46. © DMM.com Locust実行後に出力されるレポート 46

  47. © DMM.com Locust実行後に出力されるレポート 47

  48. © DMM.com 負荷試験基盤のアーキテクチャ 48 試験レポートをGCSにアップロードする

  49. © DMM.com GCSへレポートをアップロード 試験終了のイベントをフックして、レポートをGCSにアップロード 49

  50. © DMM.com GCSでレポートをホストする理由 プラットフォーム事業本部では開発者のGoogle groupをGCPアカウントに 連携済み → GCSのファイルをアップロードすれば開発者は閲覧可能 50

  51. © DMM.com 負荷試験基盤のアーキテクチャ 51 試験の終了をSlack通知する

  52. © DMM.com 試験終了のSlack通知 試験結果のURLから試験レポートを確認できる 52

  53. © DMM.com 負荷試験基盤のアーキテクチャ 53

  54. © DMM.com プロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    • 負荷試験フレームワーク • 負荷試験基盤のアーキテクチャ • テンプレートファイルの活用 4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 54
  55. © DMM.com テンプレートファイル • 試験スクリプトのGoのテンプレートファイル • k8s manifestのテンプレートファイル → ユーザーはテンプレートファイルをコピーして使用する

    55
  56. © DMM.com テンプレートファイルのコピー GitHub Actionsのworkflowで、GitHubリポジトリに新規の試験用のディレクトリを作成 する 56

  57. © DMM.com テンプレートファイルのコピー 試験用ディレクトリ以下にGoとk8s manifestのテンプレートもコピーされる 57

  58. © DMM.com Goのテンプレートファイル サンプルコードやコメントで負荷試験基盤の仕組みやライブラリの使い方を補足 → ユーザーの負荷試験基盤の学習コストが下がる 58

  59. © DMM.com Goのテンプレートファイル 59

  60. © DMM.com k8s manifestのテンプレートファイル 共通設定 • 試験共通で必要なリソースをデフォルト値で作成 • Datadogにログとトレースを送る設定値 k8sクラスターごとの設定

    • Locust master/workerの設定値(External Secretを環境変数へバインディング、 etc…) 試験ごとの設定 • Locust workerの設定値(環境変数、cpu/memory、etc…) 60
  61. © DMM.com k8s manifestのテンプレートファイル 共通設定 • 試験共通で必要なリソースをデフォルト値で作成 • Datadogにログとトレースを送る設定値 k8sクラスターごとの設定

    • Locust master/workerの設定値(External Secretを環境変数へバインディング、 etc…) 試験ごとの設定 • Locust workerの設定値(環境変数、cpu/memory、etc…) 61
  62. © DMM.com k8s manifestのテンプレートファイル 共通設定 • 試験共通で必要なリソースをデフォルト値で作成 • Datadogにログとトレースを送る設定値 k8sクラスターごとの設定

    • Locust master/workerの設定値(External Secretを環境変数へバインディング、 etc…) 試験ごとの設定 • Locust workerの設定値(環境変数、cpu/memory、etc…) 62
  63. © DMM.com k8s manifestのテンプレートファイル 共通設定 • 試験共通で必要なリソースをデフォルト値で作成 • Datadogにログとトレースを送る設定値 k8sクラスターごとの設定

    • Locust master/workerの設定値(External Secretを環境変数へバインディング、 etc…) 試験ごとの設定 • Locust workerの設定値(環境変数、cpu/memory、etc…) 63
  64. © DMM.com k8s manifestのテンプレートファイル 共通設定 • 試験共通で必要なリソースをデフォルト値で作成 • Datadogにログとトレースを送る設定値 k8sクラスターごとの設定

    • Locust master/workerの設定値(External Secretを環境変数へバインディング、 etc…) 試験ごとの設定 • Locust workerの設定値(環境変数、cpu/memory、etc…) 64 試験ごとの設定のみ負荷試験基盤のユーザーでも変更可能
  65. © DMM.com kustomizeでテンプレートファイルを合成する 65 試験共通設定 k8sクラスターごとの設定 試験ごとの設定

  66. © DMM.com k8s manifestのテンプレートファイル 試験ごとの設定をまとめたk8s manifestは 必要があればコメントアウトを外して使う 66

  67. © DMM.com 試験条件をGitHub Actionsから指定する GitHub Actionsのworkflowの引数を、動的にテンプレートファイルのプレースホルダー にセットする → 試験条件を変えるたびにユーザーが手動でk8s manifestを変更しなくてよい

    67
  68. © DMM.com 負荷試験基盤のアーキテクチャ 68 GitHubリポジトリに試験スクリプトをPush

  69. © DMM.com 負荷試験基盤のアーキテクチャ 69 GitHub Actionsのworkflowから試験を実施する

  70. © DMM.com 試験条件をGitHub Actionsから指定する GitHub Actionsのworkflowの引数を、動的にテンプレートファイルのプレースホルダー にセットする → 試験条件を変えるたびにユーザーが手動でk8s manifestを変更しなくてよい

    70
  71. © DMM.com kustomizeでテンプレートファイルを合成する 71 試験共通設定 k8sクラスターごとの設定 試験ごとの設定

  72. © DMM.com テンプレートファイルのプレースホルダー baseディレクトリ以下のテンプレートファイルにプレースホルダーを用意 72

  73. © DMM.com GitHub Actionsのworkflow 73

  74. © DMM.com テンプレートファイルのプレースホルダー テンプレートファイルにプレースホルダーを用意 GitHub Actionsのworkflowで指定した引数を動的にセットする 74

  75. © DMM.com 試験条件をGitHub Actionsから指定する GitHub Actionsのworkflowの引数を、動的にテンプレートファイルのプレースホルダー にセットする → 試験条件を変えるたびにユーザーが手動でk8s manifestを変更しなくてよい

    75
  76. © DMM.com プロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    • 負荷試験フレームワーク • 負荷試験基盤のアーキテクチャ • テンプレートファイルの活用 4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 76
  77. © DMM.com MVPから外したもの • k8sクラスター外からの負荷試験 • 試験の定期実行については考慮しない • Locust WebUIモードの利用はサポートしない

    77
  78. © DMM.com MVPから外したもの • k8sクラスター外からの負荷試験 → 想定ユーザーからのニーズが少なかった • 負荷試験の定期実行はサポートしない •

    Locust WebUIモードの利用はサポートしない 78
  79. © DMM.com MVPから外したもの • インターネットを経由した負荷試験 • 負荷試験の定期実行はサポートしない → パフォーマンスの定点観測のようなユースケースを考慮しない •

    Locust WebUIモードの利用はサポートしない 79
  80. © DMM.com MVPから外したもの • インターネットを経由した負荷試験 • 負荷試験の定期実行はサポートしない • Locust WebUIモードの利用はサポートしない

    80
  81. © DMM.com Locust masterのWebUIモード 81

  82. © DMM.com 負荷試験基盤のアーキテクチャ 82 Locust masterのリソースが残り続ける

  83. © DMM.com MVPから外したもの • インターネットを経由した負荷試験 • 負荷試験の定期実行はサポートしない • Locust WebUIモードの利用はサポートしない

    → 作成したリソースは削除する方針にしたので、WebUIモードでLocust masterのリソー スが残り続けるのは好ましくなかった 83
  84. © DMM.com プロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    3.1. 負荷試験フレームワーク 3.2. 負荷試験基盤のアーキテクチャ 3.3. テンプレートファイルの活用 4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 84
  85. © DMM.com プロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 85
  86. © DMM.com 利用者アンケート リリース後に改善点があるかもしれないので利用者アンケートを配布した → 利用者アンケートの回答を元に、改善点と新機能を考える 86

  87. © DMM.com 利用者アンケート 87

  88. © DMM.com 利用者アンケート 88

  89. © DMM.com 利用者アンケートに基づく課題 Q. その他、負荷試験基盤への要望があれば自由にご記入ください。 • GitHub Actionsの実行パラメータをActionsログに出力して欲しい。 後から再実行 (Actions

    Rerun)したくなったときに、間違ったActionsをRerunしたり、新しくActions を作る必要があったため • レポートにActionへの導線を追加して欲しい。レポートを確認し再実行しやすくする ため • 一定RPSでの負荷試験を実行できるようにして欲しい • 並列数の増加を一定間隔で行えるようにして欲しい • 実行結果の(Slack)通知(の宛先)を複数指定できるようにして欲しい 89
  90. © DMM.com 利用者アンケートに基づく課題 Q. その他、負荷試験基盤への要望があれば自由にご記入ください。 • GitHub Actionsの実行パラメータをActionsログに出力して欲しい。 後から再実行 (Actions

    Rerun)したくなったときに、間違ったActionsをRerunしたり、新しくActions を作る必要があったため ← 対応済み • レポートにActionへの導線を追加して欲しい。レポートを確認し再実行しやすくする ため ← 未対応 • 一定RPSでの負荷試験を実行できるようにして欲しい ← 対応済み • 並列数の増加を一定間隔で行えるようにして欲しい ← 未対応 • 実行結果の(Slack)通知(の宛先)を複数指定できるようにして欲しい ← 対応済み 90
  91. © DMM.com 利用者アンケートに基づく課題 Q. その他、負荷試験基盤への要望があれば自由にご記入ください。 • GitHub Actionsの実行パラメータをActionsログに出力して欲しい。 後から再実行 (Actions

    Rerun)したくなったときに、間違ったActionsをRerunしたり、新しくActions を作る必要があったため • レポートにActionへの導線を追加して欲しい。レポートを確認し再実行しやすくする ため • 一定RPSでの負荷試験を実行できるようにして欲しい • 並列数の増加を一定間隔で行えるようにして欲しい • 実行結果の(Slack)通知(の宛先)を複数指定できるようにして欲しい 91
  92. © DMM.com プロジェクトの進め方 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 92
  93. © DMM.com 負荷試験基盤の改善 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 • k8sクラスター外からの負荷試験のサポート • Locust workerのPodのオートスケール • 負荷をRPSで指定できるようにする • ログ費用の節約 93
  94. © DMM.com 負荷試験基盤の改善 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 • k8sクラスター外からの負荷試験のサポート • Locust workerのPodのオートスケール • 負荷をRPSで指定できるようにする • ログ費用の節約 94
  95. © DMM.com インターネットを経由した負荷試験のサポート 以前の負荷試験基盤ではk8sクラスター内の通信のみサポートしていた 95

  96. © DMM.com 負荷試験基盤のアーキテクチャ 96

  97. © DMM.com k8sクラスター外からの負荷試験のサポート k8sクラスター外からの負荷試験をサポートするため、新たに負荷試験用のk8s(GKE)を 用意した → より本番環境に近い条件での負荷試験が可能に 97

  98. © DMM.com 負荷試験基盤の改善 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 • k8sクラスター外からの負荷試験のサポート • Locust workerのPodのオートスケール • 負荷をRPSで指定できるようにする • ログ費用の節約 98
  99. © DMM.com Locust workerのPodのオートスケール 試験でかける負荷に対して必要なPod数を調査する工数が発生していた ex. 1 Podあたり3つの負荷タスクしか捌けないときに、4つの負荷タスクを実行しようとす ると試験が正常に実施されない 大量のPodをあらかじめ割り当てるとコストがかかる...

    99 Pod Pod Pod
  100. © DMM.com Locust workerのPodのオートスケール 変更前 試験の負荷に対して、ユーザーが必要なPod数を調査する工数が発生していた 変更後 PodのCPU使用率が高くなったら、自動でPodをオートスケールする → HPA(Horizontal

    Pod Autoscaler)を利用してオートスケール 100
  101. © DMM.com 負荷試験基盤の改善 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 • k8sクラスター外からの負荷試験のサポート • Locust workerのPodのオートスケール • 負荷をRPSで指定できるようにする • ログ費用の節約 101
  102. © DMM.com LocustではRPSで負荷の指定ができない 変更前 Locustでは、worker数を指定して負荷を調整している → 期待するRPSを出すにはworker数を手動で細かく調整しないといけない 変更後 BoomerのStableRateLimiterの仕組みを利用 →

    1 workerあたりのRPSの上限値をセットする   ex. 100 rps/worker * 100 workers = 10,000 rpsの負荷 102
  103. © DMM.com 負荷試験基盤の改善 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 • k8sクラスター外からの負荷試験のサポート • Locust workerのPodのオートスケール • 負荷をRPSで指定できるようにする • ログ費用の節約 103
  104. © DMM.com アクセスログ出力による費用増 負荷を受けるアプリケーションではCloudWatch Logs/Cloud Logging/Datadogにログ を出力している → 負荷試験によっては最大数十万円のログに関する費用が発生する 104

  105. © DMM.com 負荷リクエストに専用のヘッダーを追加 負荷リクエストに専用のヘッダーを付与する仕組みを導入 105

  106. © DMM.com 専用のヘッダーでアクセスログの出力を制御 負荷を受けるアプリケーション側でログを出力するか制御できるようにする 106 負荷試験基盤 負荷を受ける アプリケーション 専用のヘッダーがついてたらア クセスログを出力しない

  107. © DMM.com アクセスログの出力の抑制は難しい 負荷を受けるアプリケーションの依存先ではアクセスログを出力してしまう 107 負荷試験基盤 負荷を受ける アプリケーション 負荷を受ける アプリケーションの

    依存先① 負荷を受ける アプリケーションの 依存先②
  108. © DMM.com 負荷試験基盤の改善 1. 想定ユーザーへのヒアリング 2. Design Docの作成 3. 開発・リリース

    4. リリース後の利用者アンケートの取得 5. 利用状況、利用者アンケートを元にした改善 • k8sクラスター外からの負荷試験のサポート • Locust workerのPodのオートスケール • 負荷をRPSで指定できるようにする • ログ費用の節約 108
  109. © DMM.com まとめ 負荷試験基盤の仕組みとPDCAを実施した結果について紹介した 負荷試験基盤をつくる上で工夫した点 • Locust+Boomerを使うことで、Goで試験スクリプトを書けるようにした • テンプレートファイルを活用することで負荷試験基盤の学習コストを下げた •

    インフラのリソースやコストをユーザーが気にしなくて済むように仕組みを導入した → 開発チームの開発効率を向上させているはず 109
  110. © DMM.com 終わり 110