node.js×mongo dbで3年間サービス運用してみた話
TRANSCRIPT
![Page 1: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/1.jpg)
Node.js×MongoDB で3 年間サービス運用してみた話ヒカ☆ラボ2015 / 11 / 12Atsushi HashimotoCyberagent 、 Inc
1
![Page 2: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/2.jpg)
自己紹介
○橋本 純(はしもと あつし)○32歳○サーバサイド エンジニア○Node.js 、 Java 、 Python 、 PHP
担当したサービス:ピグサバゲー、ピグアイランド、ピグライフ、ピグワールド、ピグブレイブ(今ココ)
2
ふふふっ。こんにちは、ハッシーです。
![Page 3: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/3.jpg)
アジェンダ
ざっくりサービス説明Node.js で嵌ったMongoDB で嵌ったまとめ
3
![Page 4: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/4.jpg)
ざっくりサービス説明
4
![Page 5: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/5.jpg)
5
ライフ アイランド
カフェ ワールド
![Page 6: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/6.jpg)
6
ブレイブ
![Page 7: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/7.jpg)
サーバー構成
7
![Page 8: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/8.jpg)
8
![Page 9: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/9.jpg)
フロントWebsocket と Flash
全盛期は、同時接続 20 万9
![Page 10: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/10.jpg)
10
実際の仕様バージョンやモジュールなど
○Node.js v 0.8.26 v 0.10.29○MongoDB 2.2 、 2.4○Npm モジュール express, ws, socket.io, async, request, lodash, moment, ghooks, node-mongodb-native, supertest, sinon, power-assert, istanbul, etc..
![Page 11: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/11.jpg)
ここまでで、ざっくり説明は終了です。
11
![Page 12: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/12.jpg)
Node.js で嵌った
12
![Page 13: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/13.jpg)
イベントループ系の話
13
![Page 14: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/14.jpg)
イベントループをざっくり説明
14
に行く前に
![Page 15: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/15.jpg)
15
Node.js は、イベントループを止めちゃダメ
イメージ的には、関数を積み上げて順番に処理していく感じ。
DB コールや Http リクエストなど、同期的に処理すると止まってしまう処理は、叩くだけにして、戻ったらクロージャを実行する感じ。(非同期に処理)
どこかで止めてしまうと、全てが止まる。。。
![Page 16: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/16.jpg)
console.log 使っていると固まるような。。
16
エピソード1
![Page 17: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/17.jpg)
17
console.log() は、時を止める
使うと標準出力へ同期的に書き出す(サイズが大きいと結構止まる)(本番のコードには残さないように)
通常のログは、ログ出力用のライブラリなど使ってください。
![Page 18: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/18.jpg)
高負荷でも無いのに、なぜか Httpリクエストがタイムアウトする。。。
18
エピソード2
![Page 19: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/19.jpg)
19
重い or 回数の多い for 文のループも時を止める
原因は、アイテム数が多いユーザが特定の行動をすると、回数の多い for 文の処理となり、時が止まってしまった。
500 ループぐらいで、 setImmediate を挟んで対応。
![Page 20: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/20.jpg)
時を止めないように起動時もがんばって非同期で書いたが、処理が複雑になってしまった。。。
20
エピソード3
![Page 21: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/21.jpg)
21
初回起動時のみなら、同期的に行っても問題ない
コンフィグファイルの読み込みHttp サーバの起動DB 接続各種セットアップ ... などなど
起動時してすぐに、リクエストが飛んでこないなら、最初は同期的にやったほうが処理がシンプルになる。
![Page 22: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/22.jpg)
コーディング時の失敗の話
22
![Page 23: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/23.jpg)
require した時点で、処理が動くように書いたが、バッチ時など動いてほしくない時も動いてしまった。。。
23
エピソード1
![Page 24: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/24.jpg)
24
Require した時点で動く処理は書かないほうがよい空関数をセットしたりなども出来ないので、面倒でもセットアップ処理などある場合でも、使う側で呼んだほうが良いと思います。
![Page 25: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/25.jpg)
エラー時に、 try catch の部分で、なぜか callback が2回呼ばれた。。。
25
エピソード2
![Page 26: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/26.jpg)
26
try catch finally を使ったほうがよい。
NG パターンは、 callback 内でエラーが throw されると、catch 内の callback が呼ばれるため、2回呼ばれる。
![Page 27: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/27.jpg)
同期的にコーディングしていた部分に、非同期処理を入れることになったが、修正が大変だった。。。
27
エピソード3
![Page 28: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/28.jpg)
28
基本 callback 形式で書いておいたほうが良い。
メソッドの粒度など、色々とあるかと思いますが、Private 以外の関数や修正が多そうな関数は、callback 形式で書いておいたほうが、無難かと。
![Page 29: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/29.jpg)
スタックオーバーエラーにならなそうなコードで、スタックオーバーエラー。
29
エピソード4
![Page 30: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/30.jpg)
30
スキップ系は、 setImmeiate 挟むようにする。
![Page 31: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/31.jpg)
TypeError (ぬるぽ)が起きて、ギフトが受け取り放題になった。。。
31
エピソード5
![Page 32: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/32.jpg)
32
ESLint などのリンター導入とテストの充実を図る
TypeError は、なんちゃってロールバックも出来なくなるので、致命的です。。。
無いように実装&テストせねばならないです。
![Page 33: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/33.jpg)
その他
33
![Page 34: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/34.jpg)
複数 CPU を使用したい場合、クラスターモジュールを使う必要がある。
34
エピソード1
![Page 35: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/35.jpg)
35
でも、クラスターモジュール使ってません。
Node.js v0.4 の当時は、複数プロセス立ち上げることが必要だったので、歴史に引きづられているだけです。
なお、 v0.10 は、均等に処理が振られないので↑の手法を試すのも良いかもです。 v0.12 以上は直ってます。
Node.js を 0.12 以上で使うなら素直にクラスターモジュールを使用してください。
![Page 36: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/36.jpg)
Node.js でバッチ処理を書いたら、メモリ 1.4Gbyte超えた当たりからめっちゃ遅い
36
エピソード2
![Page 37: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/37.jpg)
37
リミットが 1.4Gbyte くらいなので注意です。
node app.js --max-old-space-size=8192 --nouse-idle-notification↑のような感じで起動すると8 G くらい使えます。
バッチとかでワザとメモリを使う仕様にしないと、あまり上限に当たらない気もしますが。。。
ググると、起動時パラメータの話とか色々とあると思います。
![Page 38: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/38.jpg)
Websocket を使っているが、処理計測がしづらい。
38
エピソード3
![Page 39: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/39.jpg)
39
力技で計測処理を入れました。。。
Java とかと違って、非同期の処理は測りづらいです。結果Controller層で、処理の終わりで計測メソッドを呼び出すようにしました。。。http のように、リクエスト&レスポンスが必ずある前提でwebsocket を使えば、仕込むのは容易だったのですが。。。
賛否あるかと思いますが、僕が次回やるなら仕込めるような形で実装します。
![Page 40: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/40.jpg)
ここまでで、 Node.js の話は終わりです。
40
![Page 41: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/41.jpg)
MongoDB で嵌った
41
![Page 42: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/42.jpg)
注意
この資料は、 MongoDB2.2 系と 2.4 系で起こった出来事をありのまま描いた物です。3 系だと起こらないものもあるかもなので、過度な期待はしないでください。
42
![Page 43: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/43.jpg)
MongoDB について
43
■コレクションのシャードキー単位で、自動で分散してデータ保持
■Shard はレプリカセット単位
![Page 44: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/44.jpg)
MongoDB について
44
Shard に直接接続することもできるが、全データ取得できないため、通常は、mogos経由でアクセス。
![Page 45: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/45.jpg)
シャーディング編
45
![Page 46: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/46.jpg)
サービス公開時に、プライマリシャードに更新が偏ってエラーが出た。
46
エピソード1
![Page 47: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/47.jpg)
47
予測し得るデータを、予めデータを投入しておく
MongoDB は、プライマリシャードというものがあり、空のコレクションは、まずそこに書き込まれる。ある程度、量が増えると chunk移動がおこり、データがレプリカセットごとに移動する。
先にデータを用意しておけば、 chunk移動をあらかじめ起こすことが出来るので、負荷分散出来る。
![Page 48: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/48.jpg)
コレクションを追加したが、シャーディング設定が入ってなかった。。。
48
エピソード2
![Page 49: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/49.jpg)
49
コンフィグファイルとのチェック機構を追加
プライマリシャードの件でもそうですが、一箇所に更新が固まると、まずいです。
シャーディング設定を入れないと、データが分散されないので、注意です。
![Page 50: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/50.jpg)
チャンク移動時に、たまに前のシャードに書き込みが起きる。
50
エピソード3
![Page 51: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/51.jpg)
51
mongod単位で見ると、 _id が複数ある状態に。。。Chunk の移動が自動で行われると、ロックをかけてから、データ移動という順番ですが、なぜか移動前のシャードに対してクエリが発行されている場合があります。
全部のクエリがそうでは無いので、自動ではなく手動でchunk移動するか?とか、検討中です。
![Page 52: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/52.jpg)
ローカルではエラーにならなかったが、ステージング環境でエラーが発生
52
エピソード4
![Page 53: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/53.jpg)
53
シャーディング環境でないと出ない update エラー
シャーディング環境だと、シャードキーが無い更新をするとエラーになります。(オプションを指定すれば大丈夫。)
ローカル環境と Dev環境を、シャーディング設定入れました。
そもそもコードのバグなので、 DB アクセス層を工夫すれば、起こらない問題でもあるかと。
![Page 54: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/54.jpg)
データ編
54
![Page 55: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/55.jpg)
文字列のデータが入るプロパティに、配列のデータが入ってる。
55
エピソード1
![Page 56: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/56.jpg)
56
スキーマレスだけど、スキーマほしいです。
とあるデータは、プロパティが無い状態などもあり、データの全容が把握しづらかったりします。
RDBMS なら、テーブル定義で分かったりとか出来る部分なので、スキーマレスでもスキーマがほしい所です。
json-schema 入れたり、 Mongoose利用すれば解消します。
![Page 57: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/57.jpg)
マスターデータは、 Excel と親和性が良い物にしたほうが良い。
57
エピソード2
![Page 58: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/58.jpg)
58
結局マスタの作成は Excel なのです。
管理画面のフォームを作ったは良いが、 Excel アップロードしか使われなかったり。。。
エンジニア的には、フォームと Excel アップロード両方作成したり、 json とテーブルのインピーダンスミスマッチの解消をするコードを書かなければなりません。。。
![Page 59: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/59.jpg)
ユーザデータの構成は、基本的に1コレクション、1ドキュメント
59
エピソード3
![Page 60: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/60.jpg)
60
使い方にもよるかと思いますが、うまくいってます。各種コレクションごとに、ユーザコードを _id にして、ドキュメントがあります。
リファレンス式という使い方もあるかと思いますが、特に問題は出てません。
![Page 61: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/61.jpg)
行動ログのコレクションを Capped Collection にしたら耐えられなかった件
61
エピソード4
![Page 62: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/62.jpg)
62
テラバイト級は、 index すらメモリに入らず。。
元々の、時間ごとに普通のコレクションを作成して、ログを検索する仕様に戻す。
↑こちらの仕様だと、データ量が、ある一定量に到達するとnamespace が枯渇してエラーが出ます。なので、サーバーを切り替える仕組みにして運用していたのですが、それが大変だったから切り替えたかったのですが。。。
![Page 63: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/63.jpg)
知らぬ間にオブジェクトサイズが肥大化しており、パースエラーが発生
63
エピソード5
![Page 64: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/64.jpg)
64
定期的にドキュメントサイズを計測するようにした
対象のデータは、配列のプロパティだったのですが、不具合でコードのチェックが働いておらず、無限に追加していく形になっていた。
![Page 65: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/65.jpg)
バッチ編
65
![Page 66: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/66.jpg)
バッチで一括削除したはずのデータが読み込まれる
66
エピソード1
![Page 67: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/67.jpg)
67
mongos にキャッシュが残っていたのが原因
db.adminCommand(‘flushRouterConfig’)
↑か、 mongos の再起動で解決する。
現状では、バッチ系を流した後は、上記コマンドを実施している。
![Page 68: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/68.jpg)
ローカルでは問題ないのに、本番だとバッチの実行が完了しない。
68
エピソード2
![Page 69: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/69.jpg)
69
更新対象の問題( Hoge でなければ無問題)
![Page 70: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/70.jpg)
その他
70
![Page 71: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/71.jpg)
ObjectId で、時間の範囲検索をしたい。
71
チップス的な
![Page 72: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/72.jpg)
72
更新対象の問題( Hoge でなければ無問題)
先頭が 4 バイトの Unix 時間なので、↑の用にやるとできます。Node.js からやるなら、 ObjectID.createFromTime(startTime);というメソッドがあるので、↑推奨です。
![Page 73: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/73.jpg)
ここまでで、 MongoDB の話は終わりです。
73
![Page 74: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/74.jpg)
まとめ
74
![Page 75: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/75.jpg)
75
固有の地雷に気をつけてください
今回の発表の内容のようなことが避けられればよいかと。
![Page 76: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/76.jpg)
76
静的チェック系のモジュールの導入
現状は、 ESLint が有力。
現場では、 jshint と jscs と gjslint など使ってます。移り変わりが激しいですね (‘A`)
![Page 77: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/77.jpg)
77
自由度が高くスタンダードな実装が無い
設計や実装方針の決めが重要
逆に、うまく設計や実装が出来るとすごく追加・修正がしやすいシステムが出来ると思います。
現場では、 MVC で実装してますが、 M が重くなりすぎて、色々と検討中です。(ただ、分かりやすいです。)
![Page 78: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/78.jpg)
78
完璧なロールバックはできない
トランザクションが無いので、完璧なロールバックはできないです。現場では、エラーが起きた際に、更新前に戻すクエリを発行したりしています。
お金系処理は、別システムの API を叩いています。RDBMS のような完璧さは無いので、作るシステムによって考えてほしいです。マイクロサービスの 1 つとして使うのはありかと。
![Page 79: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/79.jpg)
79
Node.js含め、各モジュールの更新頻度が高い
アップデート頻度や、モジュール自体のデファクトの移り変わりが激しいです。
「 power-assert」を使うなど、仕様が変わらなそうなものを使うのも良いと思いますが、基本はモジュールの変更に追従する方針になると思います。なので、モジュールを変更しても大丈夫なように、テストを充実させておく必要があるとおもいます。
![Page 80: Node.js×mongo dbで3年間サービス運用してみた話](https://reader036.vdocuments.site/reader036/viewer/2022062412/58794db51a28abb1418b5461/html5/thumbnails/80.jpg)
80
最後に
Node.js の実装は、 Java より楽になっていると思います。環境構築も、 npm i で、一発で出来たりしますし。
MongoDB も複雑な設定をしなくても動いてくれます。
楽ちんではありますが、銀行業務などには向かないので、ケースバイケースで使用していくと、幸せになれるのでは?と、思います。以上です。