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
An introduction to Node.js
Search
shimataro
August 04, 2020
Technology
0
280
An introduction to Node.js
さくらの夕べ Tech Night #2 Onlineの発表資料です
https://sakura-tokyo.connpass.com/event/182387/
shimataro
August 04, 2020
Tweet
Share
More Decks by shimataro
See All by shimataro
Single Executable Applicationsについて / About Single Executable Applications
shimataro
0
1.8k
パッケージ開発者の苦悩 -JavaScriptランタイム群雄割拠- / distress of package developer
shimataro
0
670
KFDのススメ / About KFD
shimataro
3
790
Node.js v12のES Modules / ES Modules on NodeJS v12
shimataro
1
1.1k
おまいらちゃんとリソース解放してますか / Remember to close resources!
shimataro
2
1.2k
CJSとESMとnpmパッケージ / CommonJS and ES Modules and npm package
shimataro
0
770
BigInt あれこれ / overview about BigInt
shimataro
0
890
dynamic import あれこれ / dynamic import - overview and pitfalls
shimataro
1
810
レスポンシブから逆戻り!?Webサービスのマルチデバイス対応方法 / Multi-Device Support Method for Web Services
shimataro
1
260
Other Decks in Technology
See All in Technology
退屈なことはDevinにやらせよう〜〜Devin APIを使ったVisual Regression Testの自動追加〜
kawamataryo
4
940
現場が抱える様々な問題は “組織設計上” の問題によって生じていることがある / Team-oriented Organization Design 20250827
mtx2s
7
67k
トヨタ生産方式(TPS)入門
recruitengineers
PRO
5
1.3k
『FailNet~やらかし共有SNS~』エレベーターピッチ
yokomachi
1
180
JavaScript 研修
recruitengineers
PRO
6
1.3k
実践AIガバナンス
asei
3
240
Browser
recruitengineers
PRO
6
1.9k
オブザーバビリティが広げる AIOps の世界 / The World of AIOps Expanded by Observability
aoto
PRO
0
110
知られざるprops命名の慣習 アクション編
uhyo
11
2.8k
コスト削減の基本の「キ」~ コスト消費3大リソースへの対策 ~
smt7174
2
290
ZOZOTOWNフロントエンドにおけるディレクトリの分割戦略
zozotech
PRO
18
5.9k
Vault meets Kubernetes
mochizuki875
0
140
Featured
See All Featured
Practical Orchestrator
shlominoach
190
11k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Raft: Consensus for Rubyists
vanstee
140
7.1k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.6k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
8
500
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
6k
YesSQL, Process and Tooling at Scale
rocio
173
14k
Side Projects
sachag
455
43k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
33
2.4k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.5k
The Pragmatic Product Professional
lauravandoore
36
6.8k
Transcript
いまさら聞けないNode.js 小田島 太郎 @shimataro999 2020/8/4 さくらの夕べ Tech Night #2 Online
https://shimataro.me/ 自己紹介 • 小田島 太郎 / https://shimataro.me/ • ウェブエンジニア ◦
フロントエンドとかバックエンドとか ◦ インフラもちょこっとだけ • 趣味は手品 ◦ 手品業界→ウェブ業界 2
この発表について 対象者 • Node.js=サーバーサイドJSってことぐらいしか知らない • バックエンドをPHPとかRubyからNode.jsに書き直しを検討中 • C10K問題のことをよく知らない 3 Node.js完全に理解した
なにもわからない チョットデキル このへん対象 半分くらいこの説明です
この発表について 目標 • Node.jsが解決するものを理解する(何がうれしいの?) • 他の言語との違いを理解する(他とどう違うの?) • バックエンド開発の注意点を理解する(何に気をつければいいの?) 4 スライドは公開しています
https://speakerdeck.com/shimataro https://shimataro.me/slides/
それでは始めます 5
Node.jsとは? 6
Node.jsとは? 7 JavaScriptの実行環境の1つ • コマンドラインからJavaScriptを実行できる • Chromeで使われているV8エンジンを搭載 • C10K問題を解決するためのバックエンド言語として開発された •
名前の由来は “Node in Network”
Node.jsとは? 8 使われている場所 • ウェブサービスのバックエンド • フロントエンド ◦ WebpackとかVue.jsのビルドとか •
デスクトップアプリ ◦ Electron(Visual Studio CodeとかSlackとか) • 組み込み
C10K問題とは? 9
C10K問題(クライアント1万台問題)とは? 10 突然ですが問題です。 クライアント1万台問題とは何でしょう?
C10K問題(クライアント1万台問題)とは? 11 解答1: クライアントが1万台になると何かおかしくなる ❌ • 1万という数値には特別な意味はない ◦ 単に「クライアントの台数が多い」という意味 ◦
9999台まではOKで、1万台になった瞬間におかしくなるわけではない • 何がおかしくなる? ◦ サービスの応答が遅くなる
C10K問題(クライアント1万台問題)とは? 12 解答2: クライアントの数が多くなると応答が遅くなる ❌ • 「クライアントの数が多くなる」とは? ◦ 1秒に1台ずつ、1万秒かけて接続がある場合でも「クライアントが1万台」には変 わりない
◦ 問題は同時接続数
C10K問題(クライアント1万台問題)とは? 13 解答3: クライアントの同時接続数が多くなると応答が遅くなる ❌ • なぜ遅くなる? ◦ マシンスペックが足りなくて応答が遅くなるのは当たり前 ▪
そんなもんにわざわざ C10K問題なんて名前つける必要はない ▪ マシンを買い直せば済む話 ◦ マシンスペック以外の原因があるからこそのC10K問題
C10K問題(クライアント1万台問題)とは? 14 解答4: マシンスペックは問題ないにもかかわらず、クライアントの同時接続数が 多くなると応答が遅くなる ⭕ • 何が原因? • どうすればいい?
C10K問題の原因 15
C10K問題の原因1: プロセス数の上限 16 Apache HTTP Serverの駆動方式 • 以前はprefork方式(1リクエスト1プロセス)が一般的 OSのプロセス数制限 •
プロセスにはIDが割り当てられている ◦ 32bit Linuxでは32767が上限 • OSごとに同時に実行できるプロセス数の上限が決まっている prefork方式では、OSごとに決められた数以上のリクエストを処理できない
ウェブサーバー プロセス プロセス プロセス C10K問題の原因1: プロセス数の上限 17 リクエスト プロセス プロセス上限オーバー!
(処理できない!) リクエスト リクエスト リクエスト プロセスIDを使い切った
【コンテキストスイッチ】 CPUが複数のプロセスを並行処理するために、それまで実行していたプロセス の内容を記録し、新たなプロセスの内容を復元すること C10K問題の原因2: コンテキストスイッチのコスト 18 時間軸 プロセスA プロセスB プロセスC
B復元 A保存 C復元 B保存 コンテキストスイッチ
プロセスが増えると、コンテキストスイッチがCPUに対して占める割合が大きく なり、CPUリソースの大部分を消費する prefork方式(リクエストが増える=プロセスが増える)では、リクエストが増える ほどリクエストを捌けるリソースが少なくなる C10K問題の原因2: コンテキストスイッチのコスト 19 時間軸 プロセスA プロセスB
プロセスC B復元 A保存 C復元 B保存 プロセスD D復元 C保存
【ファイルディスクリプター】 OSが読み書きしているファイルのID OS全体やプロセスごとに上限が決まっている Linuxでは、1プロセスにつき1024が上限のことが多い C10K問題の原因3: ファイルディスクリプターの上限 20
Unix系OSでは、ファイルだけでなくネットワークアクセスにもファイルディスクリ プターを使う DBとのコネクションにもファイルディスクリプターを使う リクエストごとにDBコネクションを張る構成だと、ファイルディスクリプターの上 限を超える同時接続ができない C10K問題の原因3: ファイルディスクリプターの上限 21
C10K問題の解決方法 22
札束で解決 • 1台で捌けないなら10台用意すればいい • 10台で捌けないなら100台用意すればいい • 用意したサーバーにいい感じに負荷分散する C10K問題の解決方法1: サーバーの台数を増やす 23
ロードバランサー側にもC10K問題が発生しないように注意
C10K問題の解決方法2: シングルプロセスで捌く 頭のいい人は考えました 「マルチプロセス方式でプロセスIDの上限に引っかかるなら、シングルプロセス ・シングルスレッドで全リクエストを捌けばいいんじゃね?」 「これならコンテキストスイッチも必要なくね?」 「1つのDBコネクションを複数リクエストで使いまわせばファイルディスクリプター の問題もなくなるんじゃね?」 24 非同期・ノンブロッキングI/O
C10K問題の解決方法2: シングルプロセスで捌く 【同期・ブロッキングI/O(従来型)】 指示を出したら処理が終わるまでCPU側でひたすら待つ 25 炊飯 洗濯指示 炊飯指示 炊飯完了 洗濯完了
洗濯 ゲーム 料理 アイロンがけ 待機 待機
C10K問題の解決方法2: シングルプロセスで捌く 【非同期・ノンブロッキングI/O】 指示を出したら完了を待たずに別の処理を行う 26 洗濯指示 炊飯指示 炊飯完了 洗濯完了 炊飯
洗濯 ゲーム 料理 アイロンがけ 待機
C10K問題の解決方法2: シングルプロセスで捌く 非同期・ノンブロッキングI/Oの特徴 • ⭕処理の完了を待っている間に別の処理をできる ◦ CPUの待ち時間が減るので効率的 • ⭕CPUを使わない複数の処理を並列で実行できる •
❌非同期処理の記述が複雑になりがち ◦ 投げっぱなしで済む処理はあまり多くないので、どこかで完了を待ち合わせる 必要がある 27
Node.jsのアプローチ 28
Node.jsのアプローチ • シングルプロセス・シングルスレッド ◦ 処理がキューに追加され、先に入ったものから順次処理される ◦ コンテキストスイッチが発生しない • CPUを使わない処理(通信など)は非同期で行われる ◦
処理が終わったらコールバック関数が呼ばれる ◦ コネクション(ファイルディスクリプター)を使いまわせる 29 (きちんとプログラミングすれば)C10K問題は発生しない
Node.jsのアプローチ 30 いい感じにHTML出力 リクエストC リクエストB リクエストA キュー リクエストC リクエストB リクエストA
1. DBからデータを取り出す 2. いい感じにHTML出力 リクエストC リクエストB DB 1. データ取得指示 2. データ取得後に 次の処理がキューに積まれる キューの処理はできるだけ短い時間で終わらせるのが鉄則
Node.jsを使うときの注意 31
Node.jsを使うときの注意1: 非同期処理 32 • コールバック関数を使いまくるとネストが深くなって見づらい • コールバック方式だと例外処理を書きづらい ◦ Promiseやasync/awaitを使いこなそう •
面倒だからといって絶対に同期版を使わないこと ◦ 処理に時間がかかる=キューが詰まる=他のリクエストを処理できない 他の言語からの移行者は要注意
Node.jsを使うときの注意2: グローバル変数 33 • Node.jsはシングルプロセス・シングルスレッド • つまりグローバル変数は全リクエストで共有される • つまりリクエストの内部状態をグローバル変数で管理すると別のリクエスト によって突然書き換えられてしまう
◦ 例えばAccept-Languageの値(ja, en-US等) 他の言語からの移行者は要注意
Node.jsを使うときの注意3: リソース管理 34 • Node.jsはシングルプロセス・シングルスレッド • つまりプロセスは動き続けることが前提 • つまりリソースは自動的に解放されない=明示的に解放しないと枯渇し、 新しいリクエストを処理できなくなる
◦ メモリーはGCが回収してくれるが… 他の言語からの移行者は要注意
Node.jsを使うときの注意4: 一部のバグが全体に影響 35 • Node.jsはシングルプロセス・シングルスレッド • つまり接続が切れてもプロセスは実行され続ける • つまり間違えて無限ループを入れてしまったら最後、新しいリクエストを処 理できなくなる
◦ マルチプロセスでは接続を切れば無限ループは消える 他の言語からの移行者は要注意
Node.jsを使うときの注意5: CPUを使いまくる処理 36 • Node.jsはシングルプロセス・シングルスレッド • つまり1つの関数が終わるまで他のリクエストを処理できない • つまりCPUリソースを大量に消費する処理には不向き ◦
別プロセスや別サービスとしてNode.jsの外側に置く工夫が必要 他の言語からの移行者は要注意
まとめ 37
まとめ • Node.jsはJavaScriptの実行環境だよ • C10K問題を解決できるよ • シングルプロセス・シングルスレッドだよ • 非同期I/Oを使ってるよ •
他の言語から移行するときは色々注意しようね • 手品に興味がある人はおはなししましょう 38
まとめ 目標(再掲) • Node.jsが解決するものを理解する(何がうれしいの?) • 他の言語との違いを理解する(他とどう違うの?) • バックエンド開発の注意点を理解する(何に気をつければいいの?) 39 お
わ か り い た だ け た だ ろ う か
https://shimataro.me/ 40 「さくらのナレッジ」にも投稿しています https://knowledge.sakura.ad.jp/24148/