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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
15k
【CEDEC+KYUSHU2025】学生・若手必見!テクニカルアーティスト 大全 ~仕事・スキル・キャリアパス、TAの「わからない」を徹底解剖~
cygames
PRO
1
1.2k
【TiDB User Day2025】リリース時のアクセス急増をいかにしてノーメンテで乗り越えたか 〜『Shadowverse: Worlds Beyond』におけるTiDB採用のゲームサーバー設計〜
cygames
PRO
1
2.8k
【CEDEC2025】『Shadowverse: Worlds Beyond』二度目のDCG開発でゲームをリデザインする~遊びやすさと競技性の両立~
cygames
PRO
2
850
【CEDEC2025】大規模言語モデルを活用したゲーム内会話パートのスクリプト作成支援への取り組み
cygames
PRO
2
2.5k
【CEDEC2025】現場を理解して実現!ゲーム開発を効率化するWebサービスの開発と、利用促進のための継続的な改善
cygames
PRO
0
1.8k
【CEDEC2025】ブランド力アップのためのコンテンツマーケティング~ゲーム会社における情報資産の活かし方~
cygames
PRO
0
1.9k
【CEDEC2025】『ウマ娘 プリティーダービー』における映像制作のさらなる高品質化へ!~ 豊富な素材出力と制作フローの改善を実現するツールについて~
cygames
PRO
0
690
【CEDEC2025】LLMを活用したゲーム開発支援と、生成AIの利活用を進める組織的な取り組み
cygames
PRO
1
5k
Other Decks in Technology
See All in Technology
【2026年版】 ベクトル検索䛸 Embedding最前線
mocobeta
0
180
【セミナー資料】Claude Code をセキュアに使うための考え方と設定の勘どころ / Claude Code Webinar 20260616
masahirokawahara
2
360
気づかぬうちにセキュリティ負債を生むAPIキー運用
sgwrmctk
0
130
200個のGitHubリポジトリを横断調査したかった
icck
0
130
【Cyber-sec+】経営層を"動かす"ための考え方
hssh2_bin
0
190
新しいVibe Codingと”自走”について
watany
6
330
小さくはじめるSLI/SLO ~育てながら組織に定着させる実践知~ / Starting Small with SLI/SLOs: Building Adoption Through Continuous Growth
nari_ex
7
2k
NAB Show 2026 動画技術関連レポート / NAB Show 2026 Report
cyberagentdevelopers
PRO
0
200
AAIFに入ってみた ~内から見えるコミュニティ動向~
sato4
0
240
Socrates × Looker 〜セマンティックレイヤーで進化するデータ分析エージェント〜
hanon52_
3
2.4k
AIエージェントが名古屋の猛暑からあなたを守る
happysamurai294
0
120
不要なレビューをAIにまかせて AIコーディングの環境改善を加速した
shoota
1
140
Featured
See All Featured
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Building Applications with DynamoDB
mza
96
7.1k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
My Coaching Mixtape
mlcsv
0
150
Visualization
eitanlees
152
17k
What does AI have to do with Human Rights?
axbom
PRO
1
2.2k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
420
Faster Mobile Websites
deanohume
310
31k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
300
Context Engineering - Making Every Token Count
addyosmani
9
960
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