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
NestJS で 重たい処理と軽い処理が 干渉しないようにデプロイするには
Search
whatasoda
March 16, 2025
Technology
1
170
NestJS で 重たい処理と軽い処理が 干渉しないようにデプロイするには
NestJS Meetup #6 2025/3/17
whatasoda
March 16, 2025
Tweet
Share
More Decks by whatasoda
See All by whatasoda
急速に利用拡大を続ける飲食店向けサービスで 店内端末同士のローカル通信を追加設定なしで実現した話
whatasoda
0
300
ReactNative アプリ同士の通信のために型情報をサクッと共有した話 #TSKaigi サブイベント
whatasoda
1
850
GraphQL でネストしたクエリを書いたら Apollo Client が無限に計算し続けるようになった話
whatasoda
0
510
Other Decks in Technology
See All in Technology
Alpine.js を活用した Laravel MPA フロントエンド最適化戦略 / Alpine.js MPA
tzmfreedom
1
830
IAMのマニアックな話 2025 ~40分バージョン ~
nrinetcom
PRO
4
660
空が堕ち、大地が割れ、海が涸れた日~もしも愛用しているフレームワークが開発停止したら?~ #phperkaigi 2025
77web
2
970
コード品質向上で得られる効果と実践的取り組み
ham0215
1
190
グループポリシー再確認
murachiakira
0
150
3/26 クラウド食堂LT #2 GenU案件を通して学んだ教訓 登壇資料
ymae
1
140
AIエージェントキャッチアップと論文リサーチ
os1ma
6
940
30代エンジニアが考える、エンジニア生存戦略~~セキュリティを添えて~~
masakiokuda
4
1.9k
ペアプログラミングにQAが加わった!職能を超えたモブプログラミングの事例と学び
tonionagauzzi
1
120
KCD Brazil '25: Enabling Developers with Dapr & Backstage
salaboy
1
120
ソフトウェア開発におけるインターフェイスという考え方 / PHPerKaigi 2025
k1low
9
3.7k
バクラクでのSystem Risk Records導入による変化と改善の取り組み/Changes and Improvement Initiatives Resulting from the Implementation of System Risk Records
taddy_919
0
190
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
53
5.4k
Reflections from 52 weeks, 52 projects
jeffersonlam
349
20k
Large-scale JavaScript Application Architecture
addyosmani
511
110k
Designing for humans not robots
tammielis
250
25k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
27
1.6k
Thoughts on Productivity
jonyablonski
69
4.5k
Bash Introduction
62gerente
611
210k
Rails Girls Zürich Keynote
gr2m
94
13k
It's Worth the Effort
3n
184
28k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.4k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Rebuilding a faster, lazier Slack
samanthasiow
80
8.9k
Transcript
© 2025 Dinii Inc. NestJS Meetup #6 2025/3/17 NestJS で
重たい処理と軽い処理が 干渉しないようにデプロイするには Shota Hatada (@whatasoda)
株式会社 ダイニー © 2025 Dinii Inc. NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS
Meetup #6 2025/3/17 自己紹介 2020 - 2022 SWE (Frontend) at mercari 2022 - Platform Engineer at Dinii Inc. Shota Hatada (@whatasoda) やっていること • Google Cloud を使ったインフラ整備 • NestJS / React Native アプリの基盤実装 • サービス安定性・拡張性向上に向けた活動 すきなもの/こと • TypeScript • スパラクーア • アニメ・ゲーム
株式会社 ダイニー © 2025 Dinii Inc. NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS
Meetup #6 2025/3/17 3行で要約 • モノリスなサービスでは重たい処理が軽い処理を邪魔することがある • Node.js の特性を知り、避けられない運命であることを知る • NestJS でインターフェイス層だけ分割してデプロイしてみよう!
株式会社 ダイニー © 2025 Dinii Inc. 重たい処理が軽い処理を邪魔する NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━
NestJS Meetup #6 2025/3/17 色々あると思うが… 1つのアプリケーションはいろいろな処理の集合体として存在している (括弧内はダイニーの例) • リアルタイム性が求められる処理 ◦ レイテンシをできるだけ下げたい(注文・会計) • 大量のデータを元に大量の計算を行う処理 ◦ 多少時間がかかっても許容できる(売上集計・分析) • 定期的に実行したいバッチ処理 ◦ 数分かかる処理もあるが、許容できる(メッセージ配信・送金) • 高頻度で Polling される処理 ◦ たまに失敗してもいいが、数がとにかく多い(プリンターに印刷物を配信する) モノリスなアプリケーションの特徴
株式会社 ダイニー © 2025 Dinii Inc. 重たい処理が軽い処理を邪魔する NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━
NestJS Meetup #6 2025/3/17 色々あると思うが… 1つのアプリケーションはいろいろな処理の集合体として存在している (括弧内はダイニーの例) • リアルタイム性が求められる処理 ◦ レイテンシをできるだけ下げたい(注文・会計) • 大量のデータを元に大量の計算を行う処理 ◦ 多少時間がかかっても許容できる(売上集計・分析) • 定期的に実行したいバッチ処理 ◦ 数分かかる処理もあるが、許容できる(メッセージ配信・送金) • 高頻度で Polling される処理 ◦ たまに失敗してもいいが、数がとにかく多い(プリンターに印刷物を配信する) モノリスなアプリケーションの特徴 この2つが同じ Cloud Run に デプロイされていた時期がある
株式会社 ダイニー © 2025 Dinii Inc. • Cloud Run +
AlloyDB な構成 ◦ Google Cloud 内の通信経路を利用している • タイムアウトのエラーは node-postgres 由来のもの ◦ setTimeout が使われていて、初回は 3 秒に設定している • 全く同じタイミングで走っている処理では成功していそう ◦ 通信部分に問題はなさそう…? 重たい処理が軽い処理を邪魔する NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS Meetup #6 2025/3/17 データベースとの接続にタイムアウトすることがあった
株式会社 ダイニー © 2025 Dinii Inc. • タイムアウトのログの直前に Slow な
Query が完了したことを示すログがある ◦ 怪しい • Slow な Query のログの直前、そのインスタンスのログが不自然に抜けている ◦ 怪しい……! • 大量のデータを取得するクエリが実行されていた! ◦ 怪しすぎる………!!! 重たい処理が軽い処理を邪魔する NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS Meetup #6 2025/3/17 更に調査を進めると…
株式会社 ダイニー © 2025 Dinii Inc. 重たい処理が軽い処理を邪魔する NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━
NestJS Meetup #6 2025/3/17 ※諸々のログを追加した後の様子 9.6秒
株式会社 ダイニー © 2025 Dinii Inc. なのにどうして最終的にはタイムアウトになってしまうのか… (時系列的には接続成功のほうが先のハズ…) • 受け取ったデータを読み込む
or パースする処理がスレッドを占有している • 実は接続に成功しているが、成功したときに行う処理ができていない • ただ、タイムアウトが来ても setTimeout のコールバックも処理できていない Node.js の特性を知る NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS Meetup #6 2025/3/17 ① Node.js はシングルスレッド (同時に1つの処理しかできない ※) ※ libuv のスレッドプールに空きがある場合、内部的には一部の処理がマルチスレッドで処理される場合があります。 しかし、今回は vCPU x 1 の構成をとっているため、 JavaScript としての処理と libuv 内部の処理のどちらがスレッドを利用しているかどうかの区 別をつけられていません。 (そもそも今回は DB との IO についての話なので、仮にマルチスレッド環境だったとしてもあんまり関係ないかも…)
株式会社 ダイニー © 2025 Dinii Inc. 1. poll でデータ量の多いクエリの結果を受け取る 2.
micro task で結果を処理する ↑ ここに時間がかかかる 3. timers が評価され、Promise が reject される 4. 接続できたことは次の poll でわかるが、 その前に Promise が reject されてしまっている… Node.js の特性を知る NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS Meetup #6 2025/3/17 ② Node.js は イベントループに従って処理が進む https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick
株式会社 ダイニー © 2025 Dinii Inc. • setImmediate を使い、時間がかかったイベントをログに出す (check
で評価される) • async_hooks を使い、時間がかかった micro task をログに出す • node-postgres のログもちょっぴり改善して詳細がわかるようにした Node.js の特性を知る NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS Meetup #6 2025/3/17 check check poll + micro tasks timers 12.6秒
株式会社 ダイニー © 2025 Dinii Inc. • データベースへの接続に関する処理がブロックされる • レスポンスやリクエストに関する処理も遅れる
• タイムアウトが絡むと、ただ遅れる以外の問題も発生する Node.js の特性を知る NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS Meetup #6 2025/3/17 check check poll + micro tasks timers 12.6秒
重たいデータを扱うときは 他の処理を止める覚悟を持つべし
株式会社 ダイニー © 2025 Dinii Inc. • 本来は処理に 1 秒もかからないものでも、スレッドがブロックされると数秒かかる
• 「ログが出ない」という挙動になりがちなので、気が付きにくい • Node.js の特性上、発生そのものを回避することはできない(抑制はできるヨ) 重たい処理と軽い処理を別々のスレッドで処理する NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS Meetup #6 2025/3/17 重たいデータを扱うときは処理が止まる覚悟を持つべし もう、別々のスレッドで処理するしかない…
株式会社 ダイニー © 2025 Dinii Inc. 全部分けるのは大変なので… インターフェイスだけ分割してデプロイしてみる • controller
や resolver を含む Module をまとめる Module をつくる ◦ まずはリクエストを分類する必要がある ◦ 命名例: primary, task, batch, etc. • 環境変数によって選択的に Module を import する ◦ アプリケーションレベルでも分割が行われる ◦ 副次的にモジュールの読み込み時間も短縮できる • 同じ Docker Image を使って複数の Cloud Run サービスをデプロイする ◦ インフラを分ける ◦ クライアント側は呼び出し先をよしなに切り替える 重たい処理と軽い処理を別々のスレッドで処理する NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS Meetup #6 2025/3/17
株式会社 ダイニー © 2025 Dinii Inc. 重たい処理と軽い処理を別々のスレッドで処理する NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━
NestJS Meetup #6 2025/3/17 ← 選択的 import 先のマッピング ↙ モジュールをまとめる ↓ 選択的 import を行う Module
株式会社 ダイニー © 2025 Dinii Inc. 分け方のすすめ • リクエストの量 ◦
同じ傾向でリクエスト量が増えるのであればインフラのスケールも揃えたい • リクエストに求められるリアルタイム性(リアルタイム性 ≠ レイテンシの低さ) ◦ リアルタイム性が要求されずとも、たまたまレイテンシが低いものもある • 明らかにスレッドブロックを発生させることがわかっているもの ◦ バッチ処理や分析系の処理は分ける ◦ 理想的にはバッチ処理は 1 プロセス 1 リクエストがいい 重たい処理と軽い処理を別々のスレッドで処理する NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━ NestJS Meetup #6 2025/3/17
株式会社 ダイニー © 2025 Dinii Inc. おしらせ NestJS で重たい処理と軽い処理が干渉しないようにデプロイするには ━━
NestJS Meetup #6 2025/3/17 https://dinii.connpass.com/event/348179/