正攻法はあるのか!?泥臭く戦ったNode.jsバージョンアップ一部始終

 正攻法はあるのか!?泥臭く戦ったNode.jsバージョンアップ一部始終

83c3e0e87371c50399ac898308bdbb92?s=128

Masato Nishihara

December 02, 2019
Tweet

Transcript

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

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

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

  4. 今日話すこと • チャットディーラーとは • ノウハウの無さが生んだ泥臭い作業 • リリース • トラブルのお話 •

    Node.jsバージョンアップの振り返り • これからのNode.jsとの付き合い方 • まとめ 4
  5. チャットディーラーとは

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

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

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

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

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

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

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

    管理ユーザ
  13. Node.jsバージョンアップ経緯 • Node.jsをバージョンアップすることになったきっかけ ◦ 6系を利用していたが2019年4月でEOLを迎える • 8系ではなく10系にした理由 ◦ 社内的にLTSである必要があった ◦

    8系のEOLは2019年10月と次のリミットが近い ◦ 10系はEOLまで2021年4月までなので採用 13
  14. Node.jsバージョンアップ経緯 • 社内での実績はあったのか? ◦ 過去別サービスでバージョンを上げた事はあるが… • ドキュメントなどの証跡は? ◦ 残っていない •

    経験者からヒントは得られないか? ◦ 恐らく動作確認をしただけだろうとのこと ◦ Node.jsに精通したエンジニアが少なくヒントは 得られなかった… 14
  15. 作業時系列 10月 11月 12月 1月 2月 3月 計画作成 調査開始  

    15 調査完了 全機能テスト準備 全機能テスト1回目   負荷試験準備 改修作業  改修作業 全機能テスト2回目 負荷試験  全機能テスト3回目 リリース  年 年
  16. ノウハウの無さが生んだ泥臭い作業

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

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

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

    なぜ、調べなかったのか? ◦ 調査に使える時間が少なかった 19
  20. ノウハウの無さが生んだ泥臭い作業 具体的には何が泥臭かったのか? • バージョンの変更確認 ◦ Node.jsの変更差分確認 ◦ 依存パッケージの変更差分確認 • 全機能テストを複数回実施

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

    ◦ チャット機能の全操作を網羅するテスト ◦ 合計3回の全機能テストを実施 21
  22. ノウハウの無さが生んだ泥臭い作業 依存パッケージの変更差分確認 • 利用している依存パッケージは25個 ◦ 単純に数が多い • 全てのバージョン差分確認 ◦ 全てをドキュメントで確認するにも限界がある

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

    10系で利用可否が明記されてないものもあった ◦ 公式のユニットテストを信頼 23
  24. ノウハウの無さが生んだ泥臭い作業 • 深い追いしなかった小さな変更の確認方法は? ◦ 全機能テストで挙動を確認 • ユニットテストが実施されていない場合の確認方法は? ◦ 全機能テストで挙動を確認 24

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

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

  27. ノウハウの無さが生んだ泥臭い作業 • 全機能テストって大変なの? ◦ 全て手動 ◦ 約500ケース ◦ 慣れている人が実施しても1日では終わらない ◦

    場合によってはマルチブラウザで実施 27
  28. ノウハウの無さが生んだ泥臭い作業 • 全機能テスト計画 ◦ 1回目:検証環境で10系の動作確認 ▪ 不具合洗い出しテスト ◦ 2回目:改修作業後に再度確認 ▪

    改修後の動作確認テスト ◦ 3回目:結合環境でリリース前確認 ▪ ステージング環境で動作検証テスト 28
  29. ノウハウの無さが生んだ泥臭い作業 • なぜ複数回実施する計画にした? ◦ 全機能で担保する重要性が増えたから ◦ 自信を持ってOKと言えなかったから ▪ 経験不足        → 不安 ▪

    社内で聞ける人がいない → 不安 不安の現れから複数回実行することに 29
  30. ノウハウの無さが生んだ泥臭い作業 • 全機能テスト1回目 ◦ 検証環境で10系の動作確認 ▪ 初作業ということもあり12時間かかる ▪ テストは問題なく完了 ▪

    改修箇所の洗い出し完了 ▪ 少なくとも後2回全機能テスト... 30
  31. ノウハウの無さが生んだ泥臭い作業 • 全機能テスト2回目 • 全機能テスト3回目 ◦ 一部、複数ブラウザも対応 ◦ 2回目、3回目共に約10時間ほどで実施 ◦

    テストは問題なく完了 ◦ 成功しそうという自信(根拠はない) 31
  32. リリース

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

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

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

  36. トラブルのお話

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

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

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

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

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

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

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

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

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

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

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

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

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

    ▪ 並列処理の際に使用される機能 49
  50. 新たな疑問 • Node.jsはシングルスレッドでは? ◦ シングルスレッドならContext switchは動かないはず ◦ Node.jsは内部でマルチスレッドとして動いていると聞いた 事がある… 50

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

  52. Node.jsがマルチスレッドなのか調べよう • libuvの中でマルチスレッドを利用している ◦ Node.jsを使用する際は隠蔽されているので 挙動はシングルスレッド ◦ 内部でマルチスレッドを利用している場合もある ▪ ファイルI/O・Crypto

    ▪ 他にはどんな時にマルチスレッドになるのか? • ご存知の方がいれば教えて頂きたい 52
  53. 現時点までで分かった事 • CPU使用率の負荷とContext switchには関連がある • Context switchの値が増加 ◦ 待ち状態が発生し別スレッドを処理 ▪

    マルチスレッド処理になるような箇所が怪しい 53
  54. トラブルの原因発覚 • DBサーバを調査していたメンバーからの連絡 ◦ スロークエリが発生している ◦ スロークエリの原因は管理画面サーバ チャットサーバ(Node.js)が原因では無かった 54

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

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

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

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

    3. スレッドを切り替えるが全て待ち状態となり CPU使用率が上昇 58
  59. 何故CPU使用率が100%に? • CPU使用率って何? ◦ CPU使用率はidle状態以外の状態とされている ◦ 待ち状態でもCPU使用率は上昇する 今回CPU使用率が100%になった理由は恐らくこれ 59

  60. トラブル解決に至るまでの問題点 • チャットサーバ側に問題があると決めてしまった ◦ 不安があったのですぐに疑った • 複数の要因により調査が難航した ◦ Node.jsに対する知識不足 ◦

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

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

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

    次回はもっと楽にしたい 63
  64. Node.jsバージョンアップを振り返り 具体的には何が泥臭かったのか?(おさらい) • バージョンの変更確認 ◦ Node.jsの変更差分確認 ◦ 依存パッケージの変更差分確認 • 全機能テストを複数回実施

    ◦ チャット機能の全操作を網羅するテスト ◦ 合計3回の全機能テストを実施 64
  65. Node.jsバージョンアップを振り返り • もっと楽に出来そうなところ ◦ 依存パッケージの変更差分確認 ▪ CDにとって重要な機能を洗い出しておく ▪ 短いスパンでバージョンを上げる ◦

    全機能テスト ▪ 全機能テストの自動化 65
  66. これからの との付き合い方

  67. これからのNode.jsとの付き合い方 • もっとNode.jsの知識が必要 ◦ 内部のプログラムを積極的に読む等 • Node.jsに精通したエンジニアを増やす ◦ 相談相手が欲しい… •

    次のバージョンアップを見据えた活動が必要 ◦ より良いバージョンアップ方法を探す 67
  68. これからのNode.jsとの付き合い方 • より良いバージョンアップ方法を探す ◦ 現時点で検討できること ▪ 自動テスト(ユニットテスト・EtoEテスト)作成 ▪ 余裕を持ったバージョンアップ作業の計画 ▪

    情報交換を積極的に実施する • 今回の発表もその一環 68
  69. まとめ

  70. まとめ • 昔ながらの方法でNode.jsをバージョンアップした • 苦労はあったが無事リリースすることができた • トラブル調査でNode.jsに対する理解が深まった ◦ トラブルで得られる知識は一生もの •

    同じ悩みを抱えている or 解決した人がいれば 情報交換したいです ◦ それ以外も大歓迎です 70
  71. ご清聴ありがとうございました 71