¡Hola!
マッチングエージェントでサーバーサイドエンジニアをやっているアントニオです。

この記事はCA Advent Calendar 2017 22日目の記事です。
あわせて4日間、株式会社マッチングエージェントのメンバーがそれぞれの視点でタップル誕生のサービス開発にまつわることをアップしてきた「CA Developers Blog 自主的なマッチング祭り」はこの記事で終わります。

前回はタップル誕生Androidエンジニアnamikiの申請文言に添えるもの〜タップル誕生の場合〜でした!

マッチングエージェントのサービス「タップル誕生」のアプリサーバーはNode.jsで運用しています。今回は今年行われたメージャーバージョンアップグレードについて紹介したいと思います。

この記事を書こうと思ったきっかけ

他サービスの話を聞くと、割と古いバージョンが使われていることが多いと感じました。大体アップグレードしない理由は「本番環境でアップグレードするのは怖い」ということです。アップグレードの影響範囲は広いので、怖い気持ちはその通りですが、きちんとした手順で行けば恐れるものではないと思います。

「タップル誕生」で行ったアップグレード手順やその後の効果を参考にしていただけたら嬉しいです。

手順について

手順は下記となりました。

  • 手順をリストアップする
  • スケジュールを立てる
  • 変更の確認
    • Breaking Changes
    • ChangeLog
  • Dependenciesの確認
    • モジュールの情報
    • ビルドを実行
  • テスト
    • ユニットテスト
    • 操作テスト
  • アップグレード自体

1. 手順をリストアップする

手順をリストアップすることで下記のメリットがあります。

  • 自分の頭の整理になる
  • 他のメンバーと進捗をシェアしやすい
  • 資料として残る。次回他のメンバーが行うときに参考にできる

私達の場合はチェックリストの形でGitHubのissueで管理しました。書かれたタスクが終わり次第チェックを付けていきました。

github-procedure

2. スケジュールを立てる

手順のリストアップに書かれたものをベースして、スケジュールを立てました。施策や新機能の追加と違って内部の改善ですので、エンジニア以外のメンバーにはどういう作業なのかわかりづらいかもしれません。

手順のリストアップと一緒にスケジュールを書くと、アップグレードに時間を使うことの理解がされやすくなります。スケジュールも同じGitHubのissueに反映しました。

github-schedule

アップグレードの規模によりますが、全部で一週間ぐらいかかるイメージです。

3. Breaking ChangesとChangeLogの確認

こちらはNode.js自体の変更の確認となります。

Breaking ChangesはNode.jsのレポジトリーのWikiに書いてあります。Breaking Changesはメージャーバージョンにおいて互換性を破る変更です。

breaking-changes

ChangeLogはNode.jsのレポジトリのdocフォルダー にまとめてあります。

changelog

上記のリンクを参考して、自分のコードベースで使っているコアモジュール(fs, util, http, 等)の変更や全体的に影響がある変更を確認すればいいと思います。

4. Dependenciesの確認

こちらはrequireしている第三者モジュールの確認になります。ハマりそうな部分ですので、一番時間かかるステップになる可能性があります。モジュールを一通り確認して、package.jsonのenginesプロパティを見ることができます。残念ながらenginesプロパティが書かれてないモジュールが多いです。

enginesプロパティがなければ、他の情報も見る可能性があります。例えば、travisを利用するモジュールだったら、YAMLの設定ファイルは参考になることがあります。また、モジュールのpackage.jsonのメタデータからもヒントもらえられます。_nodeVersionをみると、publishされたNode.jsのバージョンはわかります。

しかし、最終的に実際にビルドしてみるのが一番だと思います。正常にインストールされないモジュールがあればケースバイケースで解決するべきです。上記に書いてあるものを確認したうえで、下記のアクションはおすすめです。

  • レポジトリのissue等を閲覧する
  • モジュールのバージョンアップを行う

npmにあるモジュールはほとんどオープンソースですので、自分で修正することもできます。もしくは、代わりに似たようなモジュールを利用することができます。場合によって、難易度高くなる可能性があります。

環境によってビルドの結果は異なりますので、本番と同じ環境で行うべきです。また、ビルドの仕方も(直接npm install, yarnの利用、等)本番環境と同じじゃないと危険です。特にネイティブモジュールに注意です。

5. テスト

ビルドは正常にできてから、まずはユニットテストが通るか確認します。余裕があればユニットテストを増やすと良いと思います。

次は操作テスト行います。影響範囲は大きいので、ユニットテストはカバーしない部分があるかもしれません。テストケースを細かく指定して、リグレッションテストを行うのもおすすめです。

6. アップグレード自体

アップグレード作業はシステムによって異なりますが、ゼロダウンタイムですとローリングアップグレードをすることが多いです。また、blue/greenデプロイが可能であればアップグレードは楽になります。

改善された部分

「タップル誕生」では最後に行ったメージャーバージョンのアップグレードは6系から8系まででした。本番環境で使う場合LTS(Long Term Service)をおすすめします。現在8系はLTSとなっています。LTS等の説明はこちらです。

アップグレード行ったことで改善されたものは下記となります。

  • パーフォマンス
  • 新機能の利用可能
  • セキュリティ

パーフォマンス

パーフォマンスに関して、大きく改善されて、サーバーインスタンスのロードアベレージは約半分になりました。Node.jsが使うV8エンジンに大きく改善されたので、そのおかげだと思われます。

performance

必要なインスタンス数が減るので、システムによってかかる金額も減ります。

新機能の利用可能

コアモジュールとECMAScriptの新機能は使えるようになりました。ECMAScriptのサポートについてこちらは参考になります。

たとえば、コアモジュールだとutil.promisify()をよく利用しています。ECMAScriptの新機能も積極的に利用しています。

とりたてて言うと、一番大きかったのは8系から使えるようになった async/awaitです。チーム内にasync/awaitの使い方について勉強会を開催して、他のチームメンバーと意識を合わせ等をできました。

勉強会はワークショップの形でした。使った資料は私のGitHubに公開してます。

方針として新しいコードはasync/awaitで書くことになりました。そして、既存のコードのリファクタも行っています。下記は差分です。

github-diff

コードの量が減ったり、書きやすくなったり、分かりやすくなりました。

セキュリティ

私達の場合ですと、アップグレード前まだメンテされているバージョンを利用していましたが、メンテされていないバージョンの利用の場合はセキュリティ的なアップデートが出ませんので、危険です。

まとめ

いかがでしたでしょうか。

よく変わる業界の中で最新の技術を使うのが大事だと思っています。メリットは多いので、頑張ってアップグレードしてみましょう

きちんと手順を行うのと主にテストしっかりすることがおすすめです。

¡Muchas gracias!

マッチングエージェントでサーバーサイドエンジニアをやっているアントニオです。 得意な技術はJavaScriptとElasticsearchです。 オープンソースもやっています。よかったら私のGitHubのアカウントをご覧ください〜