Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
最大100倍高速化!PHPからJavaへのFFIを実現する、JNIを用いた高速なサーバAPIの...
Search
Cygames, Inc.
PRO
August 31, 2023
Technology
720
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
最大100倍高速化!PHPからJavaへのFFIを実現する、JNIを用いた高速なサーバAPIの実装方法
2022/08/25 CEDEC2022
Cygames, Inc.
PRO
August 31, 2023
More Decks by Cygames, Inc.
See All by Cygames, Inc.
【U/Day Tokyo 2025】Cygames流 最新スマートフォンゲームの技術設計 〜『Shadowverse: Worlds Beyond』におけるアーキテクチャ再設計の挑戦~
cygames
PRO
4
17k
【CEDEC+KYUSHU2025】学生・若手必見!テクニカルアーティスト 大全 ~仕事・スキル・キャリアパス、TAの「わからない」を徹底解剖~
cygames
PRO
1
1.3k
【TiDB User Day2025】リリース時のアクセス急増をいかにしてノーメンテで乗り越えたか 〜『Shadowverse: Worlds Beyond』におけるTiDB採用のゲームサーバー設計〜
cygames
PRO
1
2.9k
【CEDEC2025】『Shadowverse: Worlds Beyond』二度目のDCG開発でゲームをリデザインする~遊びやすさと競技性の両立~
cygames
PRO
2
980
【CEDEC2025】大規模言語モデルを活用したゲーム内会話パートのスクリプト作成支援への取り組み
cygames
PRO
2
2.7k
【CEDEC2025】現場を理解して実現!ゲーム開発を効率化するWebサービスの開発と、利用促進のための継続的な改善
cygames
PRO
0
1.9k
【CEDEC2025】ブランド力アップのためのコンテンツマーケティング~ゲーム会社における情報資産の活かし方~
cygames
PRO
0
2k
【CEDEC2025】『ウマ娘 プリティーダービー』における映像制作のさらなる高品質化へ!~ 豊富な素材出力と制作フローの改善を実現するツールについて~
cygames
PRO
0
870
【CEDEC2025】LLMを活用したゲーム開発支援と、生成AIの利活用を進める組織的な取り組み
cygames
PRO
1
5.3k
Other Decks in Technology
See All in Technology
ガバナンスの「ちょうどいい落とし所」を探れ!開発スピードを妨げない運用判断の勘所 / SRE NEXT 2026
genda
1
240
AIが実装を自走する時代の認知負債との戦い
lycorptech_jp
PRO
0
110
SREとQA 二人三脚で進めるSLO運用/sre-qa-slo
sugitak
0
820
Compose 新機能総まとめ / What's New in Jetpack Compose
yanzm
0
310
大量データに対しても、生成AIを用いてリーズナブルにデータ加工をしたい!Databricksのai_queryについて調べてみた
kamoshika
1
210
AIレビューはどこまで任せられるのか?自動化と人が背負うレビューの境界
sansantech
PRO
3
1.1k
Foxgloveについて 実際にExtensionを開発して公開するまでの話 / About Foxglove: The Story of Developing and Releasing an Extension
ry0_ka
0
290
Making sense of Google’s agentic dev tools
glaforge
1
260
Amazon EVS で VCF 9.0 / 9.1 のサポート開始まとめ
mtoyoda
0
310
Genie Ontologyは銀の弾丸かを考える / Is Genie Ontology a Silver Bullet?
nttcom
0
390
見守りエージェントを作ってみた(ローカルLLM + Hermes Agent)
happysamurai294
0
110
壊して学ぶAWS CDK: そのcdk deployで消えるもの、残るもの
k_adachi_01
1
370
Featured
See All Featured
Deep Space Network (abreviated)
tonyrice
0
230
Six Lessons from altMBA
skipperchong
29
4.3k
What's in a price? How to price your products and services
michaelherold
247
13k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Practical Orchestrator
shlominoach
191
11k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.3k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.4k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
490
For a Future-Friendly Web
brad_frost
183
10k
Mind Mapping
helmedeiros
PRO
1
280
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1k
Building AI with AI
inesmontani
PRO
1
1.1k
Transcript
None
2/36 本講演でお伝えすること PHPで他の言語のライブラリを使用したいといった状況では通 常そのライブラリを移植するといった手法がとられます。し かし移植の労力やパフォーマンスの面で問題が出るケースが 多く高処理効率と運用のしやすさの両立を目指す必要がある ゲームサーバとしては問題となりがちです。 これを解決するためにCによるPHP Extensionを実装しPHPか らJavaライブラリを直接実行できるFFI(Foreign
Function Interface)を実現した結果、処理時間はPHPに移植した場合に 比べ約1/100となりました。この事例をもとに実装に至った経 緯や、具体的な設計構成についてご紹介します。
3/36 伊藤 英知 サーバーサイド /シニアエンジニア サイバーエージェントグループのソーシャルゲーム会社を経て、2012年よ り株式会社Cygamesに参画。 フィーチャーフォン/スマートフォンのブラウザおよび、スマートフォンの ネイティブゲーム、コンシューマゲームの開発・運用に携わる。 負荷対策やミドルウェアの検証や社内で使用しているサーバフレームワーク
のメンテナンスなど社内のプロジェクトを横断的に支援、より安定して快適 に遊べるよう日々開発を行っている。 自己紹介
4/36 1. 経緯と検証の流れ 2. Pure PHPでの実装 3. Jettyによる実装 4. JNIを使ったFFIの実装
5. 本番導入準備 6. まとめ アジェンダ
5/36 経緯と検証の流れ
6/36 経緯 サーバAPIにJWSの署名検証が必要になった サ ー バ 改 竄 チ ェ
ッ ク ク ラ イ ア ン ト JWS (JSON Web Signature) JOSE Header JWS Payload JWS Signature
7/36 検証の流れ ※FFI…Foreign Function Interface(≒他の言語の呼び出し) JavaへのFFI(※)を実装し PHPから実行されるJavaのクラスで署名検証 Pure PHPで署名検証を実装 JettyでローカルHTTP
Serverを立てて そのプロセス内で署名検証
8/36 Pure PHPでの実装
9/36 Pure PHPでの実装 PHPのみで署名検証を実装 インフラ構成は通常と変化なし 要求仕様のリファレンスである Javaのライブラリをもとに移植実装 通常のNginx+PHP-FPMの構成
10/36 Pure PHPでの実装: 構成 PHP-FPMプロセス リクエスト PHPのみで 署名検証を実装 PHP NGINX
11/36 Pure PHPでの実装: 課題 遅い PHPでの移植が等価である証明が大変 ライブラリバージョンアップへの追従 約100msかかる。サーバ用途としては致命的 要求仕様がJavaのライブラリの実装である以上 この確認はかなり手間がかかる
変更点のポーティングなどメンテナンスコストが高い もちろん変更したあとは同様に等価である確認が必要
12/36 Jettyによる実装
13/36 Jettyによる実装 別プロセスでHTTPをListenする 署名検証結果をレスポンスする JettyでHTTPのサービスを作り ステートを持たないため各サーバにこのプロセスを配置 PHPプロセスからGETリクエストとしてJWSの文字 列を送り、署名検証をJavaのライブラリで行い、 0か1のレスポンスをPHPプロセスに返す
14/36 Jettyによる実装: 構成 Javaプロセス port 3520で Listen HTTP GET JWS文字列
Load 署名検証 PHP-FPMプロセス リクエスト HTTP Response 署名検証結果 .jar PHP NGINX
15/36 Jettyによる実装: 結果 パフォーマンスは一応の解決 ローカルHTTPが一つ増えた HTTPのオーバーヘッドがある 処理時間は1/10の約10msほどになった 死活監視対象が増え運用上は望ましくない Javaのみで該当の処理時間を計測した場合に比べて遅い (署名検証1回あたり1ms以下)
16/36 JNIを使ったFFIの実装
17/36 JNIを使ったFFIの実装 C/C++とJavaのコードを互いに呼べる 今回はCからJavaを実行する為に使用 いわゆるInteropの機能を提供する C#で言うところのCoreCLRやEmbeddingMono等 にあたる PHPのExtensionはCで記述される点に着目し PHPからJavaへのFFIを実現
18/36 JNIを使ったFFIの実装: 構成 PHP-FPMプロセス PHP C Extension JNI Load 署名検証
リクエスト 今回実装したFFI Java .jar PHP NGINX
19/36 JNIを使ったFFIの実装: 結果 パフォーマンスはほぼ理想的 PHPプロセスのメモリがJVMの分増加 1/100の約1msほどで処理できた 大量にforkする場合は注意 JVMのヒープメモリ指定で対処(例: -Xmx32m) PHPからの使い方もシンプルにできた
CURLでリクエスト&レスポンスのパースが不要に 例: $is_valid = verify_jws(‘JWSの文字列’); -Xmx32m -Xmx32m
20/36 JNIを使ったFFIの実装: パフォーマンス PHP-FPMプロセス PHP C Extension JNI Load 署名検証
リクエスト 今回実装したFFI 同一プロセス内で完結 || IPCのオーバヘッドがない Java .jar JITでコンパイル済みの コードが実行され続ける (PHPのプロセスが作り直されるまで) PHP NGINX
21/36 JNIを使ったFFIの実装: アップデートの容易さ PHP-FPMプロセス PHP C Extension JNI Load 署名検証
リクエスト 今回実装したFFI ここを差し替えるだけで バージョンアップできる Java .jar PHP NGINX
22/36 JNIを使ったFFIの実装: アップデートの容易さ ; Java classpath for JVM. separate with
':’. verify_jws.d_java.class.path='-Djava.class.path=./:/usr/lib64/php/modules/SomeJavaClass.jar’ ; JVM min. heap size verify_jws.xms='-Xms16m' ; JVM Max heap size. 32MB is sufficient for typical cases. verify_jws.xmx='-Xmx32m’ ; T arget Class Config verify_jws.invoke.class=‘SomeJavaClass' verify_jws.invoke.method=‘methodName' verify_jws.invoke.method_signature='(Ljava/lang/String;)Ljava/lang/String;' PHP extensionのiniで差替え設定可能 PHP extensionの再ビルドも不要
23/36 JNIを使ったFFIの実装: 運用のしやすさ PHP-FPMプロセス PHP C Extension JNI Load 署名検証
リクエスト 今回実装したFFI このプロセスだけ監視 (従来通り) Java .jar NGINX PHP
24/36 JNIを使ったFFIの実装: 他の方式との比較 JNI FFI PHP Extension Jetty Server Pure
PHP 処理速度 約1ms 約10ms 約100ms メンテナンスの しやすさ Jarを差替える Jarを差替える 移植実装が必要 追加の監視 不要 必要 不要
25/36 本番導入準備
26/36 本番導入準備: なぜここが大事か PJにとっての問題解決が大前提 ◼ 良いパフォーマンスでも使い勝手が悪い、高 コスト、不安定であったりなどでは実際のPJ で使いづらい ◼ メリットだけ求めて障害を起こすと、次に別
件でメリットを訴えても訴求力が下がる ◼ 新しい試みだからこそ検証や導入まで丁寧に してこそメリットが生かせる
27/36 本番導入準備: なぜここが大事か 次の新しい試みがやりやすくなる ◼ 検証を十分に行いリリースに万全を期すことで、 新しい挑戦がしやすくなる ◼ 副次的にどのような点を事前に考慮しておくと 安全にリリースできるかのノウハウが貯まる
28/36 本番導入準備: 行ったこと 負荷試験 耐久試験 デプロイ手順の策定 切り戻し・代替手段の準備
29/36 本番導入準備: 負荷試験 実際に改善したか必ず実測して確認 「これで速くなったハズ」で終わっては危険 ※レスポンスを遅い順に並べたときの上位10% 極端に遅いレスポンスがないか? ◼ GCのスパイクなどで一時的に遅くなるケースが ないか注意する
◼ 90パーセンタイル(※)以上と中央値で大きくか け離れていないかにも注目
30/36 本番導入準備: 耐久試験 時間がたってからメモリの使用量が増えていないか メモリリークを確認 安定度を確認 ◼ 次第にレスポンスが悪化していないか? ◼ ログにSegmentation
Faultなどエラーはでていないか? ◼ PHPのプロセスが作り直されたときに不具合は起きないか?
31/36 本番導入準備: デプロイ手順の策定 ミドルウェアのバージョンを把握 意図したとおりに配置できるように ◼ バージョンの違いによる意図しない動作を防ぐ ◼ マイナーバージョンまで確定するのが望ましい ◼
手順やシェルを用意しておく ◼ 新しい環境やほかのメンバの環境で再現できるか
32/36 本番導入準備: 切り戻し、代替手段の準備 関係者と認識を合わせておく 元に戻す方法を必ず用意 ◼ プロジェクトメンバや監視をするインフラチームとも “どうなったらまずい”というポイントを共有しておく ◼ 緊急時の対応をスムーズにするためにも重要
◼ いわゆる切り戻しの手順を策定 ◼ いつでも予期せぬ不具合の発生を考慮し今回は、 FFI版➡PurePHP版➡動作スキップとフォールバックを準備
33/36 本番導入準備: 導入タイトル
34/36 まとめ
35/36 まとめ 手段が目的化しないように注意 目的に対して適切な手段を選ぶ 似た複数ソフトウェア製品の特徴を理解しておく 技術の仕組みまで理解しておくのがベスト 多様な手段を知っておく 安全に実用化できるまでを考える プロジェクトの課題解決が目的という点を忘れない 導入フローまで考える
36/36