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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
14k
【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
680
【CEDEC2025】LLMを活用したゲーム開発支援と、生成AIの利活用を進める組織的な取り組み
cygames
PRO
1
5k
Other Decks in Technology
See All in Technology
Kubernetesにおける学習基盤とLLMOpsの概要
ry
1
200
スキルと MCP ツール、責務をどう分けるか? AI が迷わないインターフェース設計の戦略
cdataj
1
860
「気づいたら仕事が終わっている」バクラクAIエージェント本番運用の裏側 / layerx-bakuraku-aie2026
yuya4
19
11k
2026.06.13_AI時代に事業会社が「SIer出身エンジニア」を求める理由 / Why Businesses Seek Engineers with a System Integrator Background in the AI Era
jumtech
0
1k
Bucharest Tech Week 2026 - Reinventing testing practices in the AI era
edeandrea
PRO
1
130
運用を見据えたAIエージェント設計実践
amacbee
1
3.5k
FDE という解 ― 暗黙知と明示知をつなぐ、伴走型エンジニアリング ―
otanet
0
110
MCP Appsを作ってみよう
iwamot
PRO
4
360
Building applications in the Gemini API family.
line_developers_tw
PRO
0
2.6k
2026TECHFRESH畢業分享會 - 原生還是跨平台? App 開發踩坑實錄
line_developers_tw
PRO
0
550
2026 TECHFRESH 畢業分享會 - AI-Native 重塑軟體工程與虛擬講師
line_developers_tw
PRO
0
540
LLMと共に進化するプロセスを目指して
ymatsuwitter
12
3.8k
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
55k
Chasing Engaging Ingredients in Design
codingconduct
0
220
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.6k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.8k
RailsConf 2023
tenderlove
30
1.5k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
390
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
320
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
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