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
470
NestJS で 重たい処理と軽い処理が 干渉しないようにデプロイするには
NestJS Meetup #6 2025/3/17
whatasoda
March 16, 2025
Tweet
Share
More Decks by whatasoda
See All by whatasoda
バランスを見極めよう!実装の意味を明示するための型定義 TSKaigi 2025 Day2 (5/24)
whatasoda
2
840
急速に利用拡大を続ける飲食店向けサービスで 店内端末同士のローカル通信を追加設定なしで実現した話
whatasoda
0
320
ReactNative アプリ同士の通信のために型情報をサクッと共有した話 #TSKaigi サブイベント
whatasoda
1
990
GraphQL でネストしたクエリを書いたら Apollo Client が無限に計算し続けるようになった話
whatasoda
0
560
Other Decks in Technology
See All in Technology
Observability infrastructure behind the trillion-messages scale Kafka platform
lycorptech_jp
PRO
0
140
HiMoR: Monocular Deformable Gaussian Reconstruction with Hierarchical Motion Representation
spatial_ai_network
0
110
LinkX_GitHubを基点にした_AI時代のプロジェクトマネジメント.pdf
iotcomjpadmin
0
170
TechLION vol.41~MySQLユーザ会のほうから来ました / techlion41_mysql
sakaik
0
180
Node-REDのFunctionノードでMCPサーバーの実装を試してみた / Node-RED × MCP 勉強会 vol.1
you
PRO
0
110
M3 Expressiveの思想に迫る
chnotchy
0
100
SalesforceArchitectGroupOsaka#20_CNX'25_Report
atomica7sei
0
160
Wasm元年
askua
0
140
標準技術と独自システムで作る「つらくない」SaaS アカウント管理 / Effortless SaaS Account Management with Standard Technologies & Custom Systems
yuyatakeyama
3
1.2k
解析の定理証明実践@Lean 4
dec9ue
0
170
監視のこれまでとこれから/sakura monitoring seminar 2025
fujiwara3
11
3.9k
PostgreSQL 18 cancel request key長の変更とRailsへの関連
yahonda
0
120
Featured
See All Featured
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Making Projects Easy
brettharned
116
6.3k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.8k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.6k
It's Worth the Effort
3n
185
28k
For a Future-Friendly Web
brad_frost
179
9.8k
Testing 201, or: Great Expectations
jmmastey
42
7.5k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Art, The Web, and Tiny UX
lynnandtonic
299
21k
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/