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

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

新規登録して質問してみよう
ただいま回答率
85.50%
CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

Node.js

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

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

2回答

2977閲覧

同一サーバ内で稼働する複数プロセスへのリクエスト分散方法

777

総合スコア34

CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

Node.js

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

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

1クリップ

投稿2015/09/05 16:00

お世話になります。

node.jsでシステム(※)を作っています。
最初にユーザからのアクセスを80ポートで受けて
それを子プロセスに分散させる方法がわからずに悩んでおります。

そこで、掲題の方法がお分かりになられる方、
お知恵お貸し頂けませんでしょうか。。。

(※)作成中のシステム
親プロセス1 … 子プロセス間のデータ連携
子プロセス1 … 共通サービス 個別サービスA
子プロセス2 … 共通サービス 個別サービスB
子プロセス3 … 共通サービス 個別サービスC

LVSを使って出来るのかなと思っていたのですが、
そもそも同一物理サーバ内の複数プロセスに
アクセスを分散させる用途では使えない(?)ようで
どうしたものかと。。。

以上、よろしくお願い致します。

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

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

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

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

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

pi-chan

2015/09/06 00:56

「最初にユーザからのアクセスを80ポートで受けて、それを子プロセスに分散させる」という機能を親プロセスに担わせようとしておられるのですか? それとも親プロセスは「子プロセス起動」+「子プロセス間連携」が主な機能で、各子プロセスは個別にhttpリクエストを待ち受ける仕組みですか?
777

2015/09/06 01:08

pi-chanさん、ご指摘ありがとうございます。 親プロセスは、子プロセスの起動と子プロセス間での プロセス間通信が主な機能として実装をすすめてきました。 さらに、出来たら親プロセスで、子プロセスの死活監視を行わせ、 子プロセスが死んだら再立ち上げという部分まで実装したいなと思っています。 親の死活監視は、foreverを使って行おうと考えております。 親プロセスに子プロセスへのアクセス振り分け機能をつけない理由ですが、 親プロセスには子プロセス間のプロセス間通信のハブという役割があるので、 その時点で負荷が大きいのかなと考えているためです。 その上アクセス割り振りまで担わせてしまうのは まずい気がしているためです。 LVSで子プロセスへアクセスを分散させられればうれしいのですが、 なんとかなりませんでしょうか。。。 (LVSでなくとも良いのですが、それしか今のところ存じないので) そもそも、上記のような設計は良くないのでしょうか。 親プロセスに振り分けまで担わせた方がいいのでしょうか。。。 マルチプロセスを使ったプログラミングが初めてなので 設計もこれでいいのか、不安です。。
pi-chan

2015/09/06 02:25

ちょっと気になっているのですが…子プロセス1〜3は提供するサービスは内容が(一部)異なるのに、いわゆる通常のロードバランサーのように、単純にリクエストを振り分けたのではまずいのではないでしょうか?一般に、リクエストの内容(パラメータの違いとか)に応じて異なるサービスを提供するという目的であれば、そもそもリクエストが異なる訳ですから、(親プロセスとは別でも構わないですが)コントローラー(代表してリクエストを待ち受け処理を振り分ける)を一つ作成するか、あるいはapacheか何かでプロキシを立て、rewrite機能でURL自体を書き換えてやるという方法もあるとおもいますが。単にパフォーマンス向上のために処理を振り分けたいということであれば、「処理内容の同じ」プロセスを多重起動させ、リクエスト内容に応じたレスポンスを返す仕組みにすれば良いと思います。 要するに、「負荷分散」と「処理の振り分け」を混同しているために複雑なことをしようとされているだけのように思いますので、要件をもう少し整理してみてはいかがですか?
777

2015/09/06 03:41

pi-chanさん、ありがとうございます。 補足させて頂きます。 共通サービスというのはサービスメニュー表示のようなものをイメージ頂けますでしょうか。 ロードバランサーで振り分けたいのはこちらへのアクセス部分のみです。 サービスメニューに多くの情報を盛り込んでいて、 重いので各プロセスで3等分したいのです。 共通サービスに使う情報はプロセス間通信で子プロセスにミラーリングしてあります。 (redisを使いたくなかったのでこういう形になりました。。。) 個別サービスに使う情報は各子プロセスだけで保持しています。 子プロセスの一つでも落ちたらその子プロセスが担っていたサービスは提供できなくなります。 子プロセスが落ちた場合は、親プロセスを通じて他の子プロセスへ通知し 共通メニューからは、落ちた子プロセスのサービスを除外します。 子プロセスを復活出来たらサービスを追加します。 サービスメニューには各サービスへのリンク(※)を載せていますので、 共通メニュー以降のアクセスでは振り分けの必要は無いと考えております。 (※)リンクの例 <a href="http://123.123.123.123:45670/service.html?serviceID=891>サービスA(891)</a> <a href="http://123.123.123.123:45671/service.html?serviceID=910>サービスB(910)</a> <a href="http://123.123.123.123:45672/service.html?serviceID=101>サービスC(101)</a> 上記のような形で、URLにポート番号を直接埋め込んでいるので、 ユーザは該当サービスのポートにたどり着けると思っています。 (ポート番号を見せてしまうのはスマートなやり方ではないと思っていますが他に方法が思いつかず。。。) 以上ふまえまして、何か方法ございませんでしょうか。。
guest

回答2

0

nginxを表に立てておいて、裏で動かしてるpm2で管理させたnode.jsアプリにロードバランスしながら流すという方法をよく使ってます

この辺が参考になるのではないでしょうか
pm2のforkモードで動的にCPUと同じ数のhttpサーバを起動する

投稿2015/09/07 03:19

khirose

総合スコア251

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

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

777

2015/09/08 03:55

khiroseさん ご回答ありがとうございます。 子プロセスに別ポートを割り振って、 各プロセスにnginxからアクセスを分散させるという感じでしょうか?
guest

0

forkのような事はできそうですが、forkされているわけではなさそうです。
公式サイト:child_process.fork()
child_process.fork()

nginxをフロントに立てて、workerのプロセス数を増やせば分散処理できますが、forkとは違い親プロセスが子プロセスを管理するという事が出来なくなるので、redisやmemcacheといったKVSや、RDBMS等を活用して情報共有を図る必要が出てくると思います。

node.jsを使った事がないので、詳しい動作まで調べておりません。。。

投稿2015/09/06 07:52

Ken.sakanakana

総合スコア1768

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

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

777

2015/09/06 08:07

Ken.sakanakanaさん ご回答ありがとうございます。 仰るように、child_process.fork()を使っております。 これで親1と子3を形成しております。 この、子3に対して外部からのアクセスを振り分けたいのです。 手段は問わないのですが、 80番ポートで待ち受けするトップページを仮想的に建てておいて、 そこに来たアクセスをnode子プロセスに振り分ける のような感じの事がしたいのです。。。 ※1手段としてLVSを考えていたのですが、ダメでした。 親も子プロセス間のデータ連携処理で高負荷になると思うので、 親プロセスに割り振りの機能を持たせたくは無いです ※というか正直親でどうやって振り分けたらいいのかわからないです。 振り分けの機能以外は作成完了しているので、 あまり変更をせずに、nodeの外で解決出来ればなと思っています。
Ken.sakanakana

2015/09/06 13:23

apacheとnginxの比較でよく用いられるのですが、forkする方が高負荷に陥りやすいと思うのですが、スレッド処理では何か不都合があったのでしょうか。 バックエンド処理で待ちが長くなるなら、キューイング処理させ、結果をポーリングさせることで、1コネクション毎の空き時間を作り別スレッドの処理を回せるようになると思うのですが。。。旨く説明できなくてすみません。 ↓この資料を見てもらうとなんとなくわかるかもしれません! http://www.slideshare.net/kazeburo/isucon-summerclass2014action2final
777

2015/09/07 02:26

Ken.sakanakanaさん ご回答ありがとうございます。 nodeはシングルスレッドでしか動かないので クラスタ化等しないとサーバの複数プロセスを活かせないので マルチタスク化を狙いました。 その結果、今の構成になりました。 はたして性能向上しているのかわからないですが。。。 頂いたURL参考にさせて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問