質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Q&A

解決済

1回答

846閲覧

【node.js】プロセス間通信/片方が頻繁に落ちている状態となりうる条件で

shiro05270

総合スコア7

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

0グッド

0クリップ

投稿2019/01/07 01:59

前提・実現したいこと

node.jsにて、2つのプログラムを作成しています。

① send.js:センサからひたすら値を取得して②へその値を投げる
② receive.js:①から受け取った値をひたすらクラウドへ送信する

②のプロセスは頻繁にエラーで落ちてしまうため、プロセス監視により落ちたら自動的に再起動するようにしています。
①に関しては、基本的に長期稼働させても落ちることはありません。また、落としてはいけません。

ここで質問です。
socket.ioなどで、ソケット通信を用いてプロセス間通信を試みようと思いますが、②が落ちていることで、通信が確立されず、①もエラーで落ちてしまうことなどを危惧しております。

理想としては、
①は通信がうまくいっているかを気にせずひたすら②へデータを送り続ける(②が落ちている最中であろうとなかろうときにせず送り続ける)
②はエラーで落ちていない間は①からデータを受け取る

となることです。
プロセス間通信について疎いので、node.jsで上記を実現できるモジュールおよび使用方法などご教授いただけますと幸いです。
何卒宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

②のプロセスは頻繁にエラーで落ちてしまうため、プロセス監視により落ちたら自動的に再起動するようにしています。

いやいや、なんで頻繁にエラーで落ちちゃうの…?
Node.jsでも早々落ちない高耐久のサーバー組めるはずだよ。
まずはつまらないエラーで落ちないように自動テストを埋めていこう。

socket.ioなどで、ソケット通信を用いてプロセス間通信を試みようと思いますが、②が落ちていることで、通信が確立されず、①もエラーで落ちてしまうことなどを危惧しております。

いやいや、2が落ちてれば検知出来るよね?
Promiseなら.catchで拾えるし、
非同期処理ならコールバック引数の第一引数がerrだからそれ見て対応変えられるはずだよ


プロセス間通信について疎い

速度だけならいろいろと手はあるね。
UNIXドメインソケットとかね。

でもそこまでシビアなパフォーマンスを要求しないなら、
普通にTCPのサーバを立ち上げて、localhost:xxxxとして繋いだ方がいいね。

①は通信がうまくいっているかを気にせずひたすら②へデータを送り続ける

そもそも頻繁に死ぬ2を何とかしようという話なんだけど、
2が頻繁に死ぬならSocket.ioじゃダメ、直接つなげるのはやめたほうがいい。

例えば両方は直接接続せずにMySQLなどのデータベースを経由して通信する。
1はメッセージをとにかくMySQLへ保存して、
2は3秒に一度みたいなペースでMySQLを巡回してメッセージを取り出して、仕事が終わったら消すというのはどうだろう?
MySQLみたいなデータベースは高耐久なアプリだから、落ちないメッセージ置き場として中々適切だと思うよ。

私だったらPubSub導入する路線で考えるかな。
Kafkaとか、Pulsarとか触ってみたいね。
AWSが使えるならSQSが理想。

PubSubというのはメッセージキューのサービス(サーバ)で、
1のような仕事を発注したい人がとりあえずメッセージを投げまくったのを保存しておき、
2のようなプロセスが蓋を開けると仕事がバサバサ落ちてくるという仕組みを提供している。

これはSQSの機能の話で他のPubSubで使えるかは調査の必要があるけど、
チケットを受信したら受信しましたよフラグが一旦建ち、
その後仕事終了と称してチケットを削除しないと10〜30分程度でチケットが復活する仕組みになっている。
なので2がチケットを10件受け取って、7件目の仕事中で死んだら4件の未処理チケットが宙ぶらりんで残ってしまうのだけど
時間が経てばこの4件のメッセージが未受信状態に戻ってまた別のタスクが受け取れるようになるわけ。

これでまさに1はメッセージを投げて、2は勝手に受け取るという仕組みが実現出来るね。

投稿2019/01/07 05:42

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiro05270

2019/01/12 10:45 編集

返信おくれてしまい申し訳ありません。 詳しい回答をいただきとても感謝しております。大変勉強になります。 状況の詳細を載せておらず申し訳ありません。 ②で頻繁にエラーが起きるというのは実は意図的にエラーを発生させてプロセスを落としています。というのも、②は①から取得するデータを継続的にAWSIoTへとデータをpublishしているのですが、数日稼働させているとAWSIoTまで届かなくなってしまう現象が発生しました。原因を探ってみるとどうも、AWSIot.device.onで受け取る事が出来るAWSとの通信状態遷移がうまくいかないときがあるようでした。 通常であれば、クラウドとの通信状態がconnectで、不安定になるとcloseと遷移し、暫くするとreconnect状態へ遷移して再接続を試みたのちconnectへ戻るというように自動的に通信を復旧する仕組みが働いてくれていることを確認しました。 しかし、AWSIoTまでデータが届かなくなる障害が起きた際は、closeへ遷移したのち一向にreconnect状態へ遷移しませんでした。(これ自体がどうして起きてしまうのかの根本的な原因や解決策は見いだせてません。。) また、調査した知見が正しければsdkを用いたAWSIoTとのやり取りはトピックに載せたデータをpublishとsubscribeでやり取りしている認識でおりご紹介頂いているpubsubで通信していると考えており、確かにclose中にpublishしていた内容はreconnectののち再びconnectへ遷移した時に一気にAWSIoTまで届くことは確認しております。しかし、closeから状態が戻らないならどうしようもないのかなと悩んでおりました。 そのため、対症療法として、一定時間以上closeになってからconnectに戻らなければエラーで落として、プロセス監視により再びプロセスを再起動させる手段を取ることにしたという経緯でございます。 また、私はsocket.ioの.emit .onで2プロセス間のやり取りをするつもりでおりましたが、やめた方がいいと仰る理由としては、ご紹介頂いたpubsubのようにキューの使用になっていないからプロセスが落ちている間のデータが欠測してしまうからという理解でよろしいでしょうか? その他、上記の状況説明の上でなにか助言をいただくことが叶いますと大変助かります。よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問