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
1k
2
Share
NestJS で 重たい処理と軽い処理が 干渉しないようにデプロイするには
NestJS Meetup #6 2025/3/17
whatasoda
March 16, 2025
More Decks by whatasoda
See All by whatasoda
バランスを見極めよう!実装の意味を明示するための型定義 TSKaigi 2025 Day2 (5/24)
whatasoda
3
1.2k
急速に利用拡大を続ける飲食店向けサービスで 店内端末同士のローカル通信を追加設定なしで実現した話
whatasoda
0
380
ReactNative アプリ同士の通信のために型情報をサクッと共有した話 #TSKaigi サブイベント
whatasoda
1
1.2k
GraphQL でネストしたクエリを書いたら Apollo Client が無限に計算し続けるようになった話
whatasoda
0
700
Other Decks in Technology
See All in Technology
Claude Codeを組織で使いこなす— サーバサイドAIエージェント運用の実践知
techtekt
PRO
0
200
電子辞書Brainをネットに繋げてみた(自力編)
raspython3
0
430
AI Adaptable なテストを整える工夫 / Ways to Make Your Tests AI-Adaptable
bitkey
PRO
2
210
Strands Agents超入門
kintotechdev
1
160
関西に縁あるMicrosoft MVPsが語るCopilotの未来
kasada
0
1k
Dynamic Workersについて
yusukebe
2
580
Platform engineering for developers, architects & the rest of us (AI agents)
danielbryantuk
0
180
React、まだ楽しくて草
uhyo
7
4k
Databricks における 生成AIガバナンスの実践
taka_aki
1
300
「コーディング」しない人のための Claude Code 入門 ChatGPT の次の一歩 — 業務に組み込む 育成・共有・自動化
rfdnxbro
2
1.2k
AI活用を推進するために ファインディが下した、一つの小さな決断
starfish719
0
240
Agentic ERPをどう設計するか ー 受発注エージェントを動かす、現場の知見と設計思想ー
recerqainc
1
1.4k
Featured
See All Featured
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
A Tale of Four Properties
chriscoyier
163
24k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Navigating Weather and Climate Data
rabernat
0
210
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
380
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Bash Introduction
62gerente
615
210k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.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/