Slide 1

Slide 1 text

正攻法はあるのか 泥臭く戦った バージョンアップ一部始終 株式会社ラクス 西原

Slide 2

Slide 2 text

自己紹介 名前:西原 優人(ニシハラ マサト) 所属:株式会社ラクス 経歴:2015年入社(5年目) MailDealer・ChatDealerの開発にて Node.jsを用いた開発を経験(Node.js歴は当時2~3年) 現在はメール配信サービスの配配メールを担当 2

Slide 3

Slide 3 text

発表の主なターゲット ● プロダクトのNode.jsのバージョンアップについて正攻法を持っ ていない人 ● 泥臭いバージョンアップが気になる人 ● Node.js初級者が悪戦苦闘している頑張っている姿が 気になる人 3

Slide 4

Slide 4 text

今日話すこと ● チャットディーラーとは ● ノウハウの無さが生んだ泥臭い作業 ● リリース ● トラブルのお話 ● Node.jsバージョンアップの振り返り ● これからのNode.jsとの付き合い方 ● まとめ 4

Slide 5

Slide 5 text

チャットディーラーとは

Slide 6

Slide 6 text

チャットディーラーとは 6 よくWebサイトの右下に 埋め込まれているチャット

Slide 7

Slide 7 text

チャットディーラーとは ● サイトに専用スクリプトを埋め込んで利用する チャットシステム ● ボットを用いて自動的に応答する事が可能 ● https://www.chatdealer.jp/products/ この発表では以降チャットディーラーをCDと表記します 7

Slide 8

Slide 8 text

サーバ構成紹介 チャット画面サーバ( ) サーバ 管理画面サーバ( ) チャットサーバ( ) 8 エンドユーザ 管理ユーザ

Slide 9

Slide 9 text

サーバ構成紹介 チャット画面サーバ( ) サーバ 管理画面サーバ( ) チャットサーバ( ) 9 エンドユーザ 管理ユーザ Webサイトに埋め込まれて いるチャットを利用

Slide 10

Slide 10 text

サーバ構成紹介 チャット画面サーバ( ) サーバ 管理画面サーバ( ) チャットサーバ( ) 10 エンドユーザ 管理ユーザ CDを契約しているユーザが 管理画面を利用

Slide 11

Slide 11 text

サーバ構成紹介 チャット画面サーバ( ) サーバ 管理画面サーバ( ) チャットサーバ( ) 11 エンドユーザ 管理ユーザ

Slide 12

Slide 12 text

サーバ構成紹介 チャット画面サーバ( ) サーバ 管理画面サーバ( ) チャットサーバ( ) 12 エンドユーザ 管理ユーザ

Slide 13

Slide 13 text

Node.jsバージョンアップ経緯 ● Node.jsをバージョンアップすることになったきっかけ ○ 6系を利用していたが2019年4月でEOLを迎える ● 8系ではなく10系にした理由 ○ 社内的にLTSである必要があった ○ 8系のEOLは2019年10月と次のリミットが近い ○ 10系はEOLまで2021年4月までなので採用 13

Slide 14

Slide 14 text

Node.jsバージョンアップ経緯 ● 社内での実績はあったのか? ○ 過去別サービスでバージョンを上げた事はあるが… ● ドキュメントなどの証跡は? ○ 残っていない ● 経験者からヒントは得られないか? ○ 恐らく動作確認をしただけだろうとのこと ○ Node.jsに精通したエンジニアが少なくヒントは 得られなかった… 14

Slide 15

Slide 15 text

作業時系列 10月 11月 12月 1月 2月 3月 計画作成 調査開始   15 調査完了 全機能テスト準備 全機能テスト1回目   負荷試験準備 改修作業  改修作業 全機能テスト2回目 負荷試験  全機能テスト3回目 リリース  年 年

Slide 16

Slide 16 text

ノウハウの無さが生んだ泥臭い作業

Slide 17

Slide 17 text

ノウハウの無さが生んだ泥臭い作業 ● なぜ、泥臭かったのか? ○ アナログな作業が多く、効率的では無かった 17

Slide 18

Slide 18 text

ノウハウの無さが生んだ泥臭い作業 ● なぜ、泥臭かったのか? ○ アナログな作業が多く、効率的では無かった ● なぜ、他の方法が無かったのか? ○ ノウハウが無く、他の方法が分からなかった 18

Slide 19

Slide 19 text

ノウハウの無さが生んだ泥臭い作業 ● なぜ、泥臭かったのか? ○ アナログな作業が多く、効率的では無かった ● なぜ、他の方法が無かったのか? ○ ノウハウが無く、他の方法が分からなかった ● なぜ、調べなかったのか? ○ 調査に使える時間が少なかった 19

Slide 20

Slide 20 text

ノウハウの無さが生んだ泥臭い作業 具体的には何が泥臭かったのか? ● バージョンの変更確認 ○ Node.jsの変更差分確認 ○ 依存パッケージの変更差分確認 ● 全機能テストを複数回実施 ○ チャット機能の全操作を網羅するテスト ○ 合計3回の全機能テストを実施 20

Slide 21

Slide 21 text

ノウハウの無さが生んだ泥臭い作業 具体的には何が泥臭かったのか? ● バージョンの変更確認 ○ Node.jsの変更差分確認 ○ 依存パッケージの変更差分確認 ● 全機能テストを複数回実施 ○ チャット機能の全操作を網羅するテスト ○ 合計3回の全機能テストを実施 21

Slide 22

Slide 22 text

ノウハウの無さが生んだ泥臭い作業 依存パッケージの変更差分確認 ● 利用している依存パッケージは25個 ○ 単純に数が多い ● 全てのバージョン差分確認 ○ 全てをドキュメントで確認するにも限界がある ● Node.js 10系で利用可否確認 ○ 明記されてないものもあった 22

Slide 23

Slide 23 text

ノウハウの無さが生んだ泥臭い作業 ● 単純に数が多い ● 全てをドキュメントで確認するにも限界がある ○ 大きな変更のみ確認(深追いをしない) ○ CDに影響のありそうなものだけに絞る ● 10系で利用可否が明記されてないものもあった ○ 公式のユニットテストを信頼 23

Slide 24

Slide 24 text

ノウハウの無さが生んだ泥臭い作業 ● 深い追いしなかった小さな変更の確認方法は? ○ 全機能テストで挙動を確認 ● ユニットテストが実施されていない場合の確認方法は? ○ 全機能テストで挙動を確認 24

Slide 25

Slide 25 text

ノウハウの無さが生んだ泥臭い作業 担保する方法が同じ 25

Slide 26

Slide 26 text

ノウハウの無さが生んだ泥臭い作業 全機能テストの重要性が上がる 26

Slide 27

Slide 27 text

ノウハウの無さが生んだ泥臭い作業 ● 全機能テストって大変なの? ○ 全て手動 ○ 約500ケース ○ 慣れている人が実施しても1日では終わらない ○ 場合によってはマルチブラウザで実施 27

Slide 28

Slide 28 text

ノウハウの無さが生んだ泥臭い作業 ● 全機能テスト計画 ○ 1回目:検証環境で10系の動作確認 ■ 不具合洗い出しテスト ○ 2回目:改修作業後に再度確認 ■ 改修後の動作確認テスト ○ 3回目:結合環境でリリース前確認 ■ ステージング環境で動作検証テスト 28

Slide 29

Slide 29 text

ノウハウの無さが生んだ泥臭い作業 ● なぜ複数回実施する計画にした? ○ 全機能で担保する重要性が増えたから ○ 自信を持ってOKと言えなかったから ■ 経験不足        → 不安 ■ 社内で聞ける人がいない → 不安 不安の現れから複数回実行することに 29

Slide 30

Slide 30 text

ノウハウの無さが生んだ泥臭い作業 ● 全機能テスト1回目 ○ 検証環境で10系の動作確認 ■ 初作業ということもあり12時間かかる ■ テストは問題なく完了 ■ 改修箇所の洗い出し完了 ■ 少なくとも後2回全機能テスト... 30

Slide 31

Slide 31 text

ノウハウの無さが生んだ泥臭い作業 ● 全機能テスト2回目 ● 全機能テスト3回目 ○ 一部、複数ブラウザも対応 ○ 2回目、3回目共に約10時間ほどで実施 ○ テストは問題なく完了 ○ 成功しそうという自信(根拠はない) 31

Slide 32

Slide 32 text

リリース

Slide 33

Slide 33 text

たどり着いたリリース ● いろいろあったがスケジュール通りリリースを実施 ● リリース後の動作確認でも問題なし 33

Slide 34

Slide 34 text

たどり着いたリリース リリースしNode.jsバージョンアップは完了 34

Slide 35

Slide 35 text

たどり着いたリリース リリースしNode.jsバージョンアップは完了 トラブル発生 35

Slide 36

Slide 36 text

トラブルのお話

Slide 37

Slide 37 text

これから本番で起きたトラブルに関する話をしますが 先にお伝えしておくことがございます 37

Slide 38

Slide 38 text

Node.jsのバージョンアップが怪しいと 調査を進めましたが… 38

Slide 39

Slide 39 text

Node.jsのバージョンアップが怪しいと 調査を進めましたが… 実は関係無かったというオチです 39

Slide 40

Slide 40 text

トラブル調査の過程でNode.jsの知見を 得ることが出来たのでお話します 40

Slide 41

Slide 41 text

トラブル発生 ● リリース後、数日が経ちCDに異変が発生 ○ エンドユーザ利用側で動作遅延が発生 41

Slide 42

Slide 42 text

トラブル発生 ● サーバ監視ツールで確認 ○ 2台あるチャットサーバ(Node.js)の1台で負荷が発生 ➔ CPU使用率が100%に 42

Slide 43

Slide 43 text

サーバ構成紹介 チャット画面サーバ( ) サーバ 管理画面サーバ( ) チャットサーバ( ) 43 エンドユーザ 管理ユーザ 遅延

Slide 44

Slide 44 text

調査開始 ● Node.jsを使用しているサーバが怪しい ○ 負荷が高まっているのはチャットサーバのみ ○ 数日前にバージョンアップを実施したばかり ○ 前述した泥臭い部分等の不安がある 別のサーバも調査するが、メインはチャットサーバ 44

Slide 45

Slide 45 text

調査開始 ● 普段実施している調査を行うも原因特定ならず ○ ログ調査 ○ 改修箇所の調査 45

Slide 46

Slide 46 text

調査難航 ● CPU使用率上昇の原因は何なのか? 46

Slide 47

Slide 47 text

調査難航 ● 普段見ない箇所を調査 ○ サーバ監視ツールで普段見る事無いグラフを確認 ■ CPU使用率が上がるには何かしら兆候があるはず 47

Slide 48

Slide 48 text

CPU使用率の調査 ● とあるグラフの波形がCPU使用率と一致する事が判明 48

Slide 49

Slide 49 text

CPU使用率の調査 ● 一体何のグラフなのか? ○ Context switch ■ CPUが現在実行している処理の流れ(プロセス、スレッ ド)を一時停止し、別のものに切り替えて実行を再開す ることで複数の処理を同時に実行することができる ■ 並列処理の際に使用される機能 49

Slide 50

Slide 50 text

新たな疑問 ● Node.jsはシングルスレッドでは? ○ シングルスレッドならContext switchは動かないはず ○ Node.jsは内部でマルチスレッドとして動いていると聞いた 事がある… 50

Slide 51

Slide 51 text

Node.jsがマルチスレッドなのか調べよう ● Node.jsではlibuvというライブラリを利用 ○ libuvはイベントループ機能を提供 ● 下記プログラムにてデフォルトで複数スレッドを利用 ○ node/deps/uv/src/threadpool.c 51

Slide 52

Slide 52 text

Node.jsがマルチスレッドなのか調べよう ● libuvの中でマルチスレッドを利用している ○ Node.jsを使用する際は隠蔽されているので 挙動はシングルスレッド ○ 内部でマルチスレッドを利用している場合もある ■ ファイルI/O・Crypto ■ 他にはどんな時にマルチスレッドになるのか? ● ご存知の方がいれば教えて頂きたい 52

Slide 53

Slide 53 text

現時点までで分かった事 ● CPU使用率の負荷とContext switchには関連がある ● Context switchの値が増加 ○ 待ち状態が発生し別スレッドを処理 ■ マルチスレッド処理になるような箇所が怪しい 53

Slide 54

Slide 54 text

トラブルの原因発覚 ● DBサーバを調査していたメンバーからの連絡 ○ スロークエリが発生している ○ スロークエリの原因は管理画面サーバ チャットサーバ(Node.js)が原因では無かった 54

Slide 55

Slide 55 text

サーバ構成紹介 チャット画面サーバ( ) サーバ 管理画面サーバ( ) チャットサーバ( ) 55 エンドユーザ 管理ユーザ 遅延

Slide 56

Slide 56 text

トラブルの原因 1. 管理画面サーバから投げたSQLが原因でDBサーバが遅延 2. 共通のDBサーバを利用しているのでチャットサーバからの問 い合わせも待ち状態に 3. 待ち状態のプロセスが増え遅延が発生 ● チャットサーバは通信数も多いので遅延が顕著に発生 56

Slide 57

Slide 57 text

トラブルの原因 CPU使用率の上昇が遅延の原因と考えていたが DBサーバでの遅延が原因で チャットサーバのCPU使用率が上昇していた 57

Slide 58

Slide 58 text

何故CPU使用率が100%に? ● CPU使用率100%の原因予測 1. 同一処理の中でファイルへの書き込みと DBを利用する箇所があった 2. Node.js内部でマルチスレッド化しContext switchを 利用するが、DB処理部分で待ち状態となる 3. スレッドを切り替えるが全て待ち状態となり CPU使用率が上昇 58

Slide 59

Slide 59 text

何故CPU使用率が100%に? ● CPU使用率って何? ○ CPU使用率はidle状態以外の状態とされている ○ 待ち状態でもCPU使用率は上昇する 今回CPU使用率が100%になった理由は恐らくこれ 59

Slide 60

Slide 60 text

トラブル解決に至るまでの問題点 ● チャットサーバ側に問題があると決めてしまった ○ 不安があったのですぐに疑った ● 複数の要因により調査が難航した ○ Node.jsに対する知識不足 ○ Context switchやLinux低レイヤーなどの知識不足 60

Slide 61

Slide 61 text

トラブルが終結 ● Node.jsのバージョンアップによるものではなく一安心 ● 知識・経験不足を痛感 ○ libuvなどのプログラムを読む良い機会になった ○ 今後も利用していくうえで、学習が必要 61

Slide 62

Slide 62 text

バージョンアップを振り返り

Slide 63

Slide 63 text

Node.jsバージョンアップを振り返り ● 予定通りリリースできた ● 結果的にバージョンアップ起因でのトラブルは無い ● 社内での成功事例が出来た ● 泥臭い作業がしんどかった ○ 次回はもっと楽にしたい 63

Slide 64

Slide 64 text

Node.jsバージョンアップを振り返り 具体的には何が泥臭かったのか?(おさらい) ● バージョンの変更確認 ○ Node.jsの変更差分確認 ○ 依存パッケージの変更差分確認 ● 全機能テストを複数回実施 ○ チャット機能の全操作を網羅するテスト ○ 合計3回の全機能テストを実施 64

Slide 65

Slide 65 text

Node.jsバージョンアップを振り返り ● もっと楽に出来そうなところ ○ 依存パッケージの変更差分確認 ■ CDにとって重要な機能を洗い出しておく ■ 短いスパンでバージョンを上げる ○ 全機能テスト ■ 全機能テストの自動化 65

Slide 66

Slide 66 text

これからの との付き合い方

Slide 67

Slide 67 text

これからのNode.jsとの付き合い方 ● もっとNode.jsの知識が必要 ○ 内部のプログラムを積極的に読む等 ● Node.jsに精通したエンジニアを増やす ○ 相談相手が欲しい… ● 次のバージョンアップを見据えた活動が必要 ○ より良いバージョンアップ方法を探す 67

Slide 68

Slide 68 text

これからのNode.jsとの付き合い方 ● より良いバージョンアップ方法を探す ○ 現時点で検討できること ■ 自動テスト(ユニットテスト・EtoEテスト)作成 ■ 余裕を持ったバージョンアップ作業の計画 ■ 情報交換を積極的に実施する ● 今回の発表もその一環 68

Slide 69

Slide 69 text

まとめ

Slide 70

Slide 70 text

まとめ ● 昔ながらの方法でNode.jsをバージョンアップした ● 苦労はあったが無事リリースすることができた ● トラブル調査でNode.jsに対する理解が深まった ○ トラブルで得られる知識は一生もの ● 同じ悩みを抱えている or 解決した人がいれば 情報交換したいです ○ それ以外も大歓迎です 70

Slide 71

Slide 71 text

ご清聴ありがとうございました 71