ウェブサーバについて質問です。

1台のサーバ上で、Apacheとnginxの両方をポート80番で動かすことは可能でしょうか?

a.example.com でアクセスするとapacheのバーチャルホストが閲覧でき、
b.example.com でアクセスするとnginxのバーチャルホストが閲覧できる、

みたいなことをしたい思っています。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2011/08/14 22:34:24
  • 終了:2011/08/15 00:05:08

ベストアンサー

id:a-kuma3 No.1

a-kuma3回答回数4596ベストアンサー獲得回数19352011/08/14 22:46:10

ポイント80pt

1台のサーバ上で、Apacheとnginxの両方をポート80番で動かすことは可能でしょうか?

残念だけど、これは無理だよ。

socket の口を開けて待ち構えるようなプログラムでは、ポートを取りあうので、

既に別のプロセスが掴んでるポートを開けられない。


もし、やるとしたら、apache のモジュールを作って、別のポートで口を開けて待ってる nginx に

中継するようにすればできる。

Apache をフロントにした、Tomcat への中継をする mod_jk のようなイメージ。


mod_proxy を使えば、似たようなことはできるね。

http://a.example.com/aaa/ だけを http://a.example.com:8080/ へ転送して、

nginx は 8080 で、待ち構えておく、とか。

http://httpd.apache.org/docs/2.2/ja/mod/mod_proxy.html


--

(追記)

ごめん、typo を直した。

×ポートを取りある

○ポートを取りあう


ひとつのポートを、複数のプロセスが待ち受けるのは無理なんだけど、

サーバの外の人から見て、80 のポートに出したリクエストを、複数のプロセスが

応答を返すのはできると思うんだ。

先の回答で書いた Apache が 80 を開けてて、別のプロセスに振る、とか、

全く別のプロセスが 80 を開けてて、Apache と nginx に振り分けるとか。

id:DQNEO

>残念だけど、これは無理だよ。

>socket の口を開けて待ち構えるようなプログラムでは、ポートを取りあうので、

>既に別のプロセスが掴んでるポートを開けられない。


なるほど。プログラムがポートを占有してしまうイメージですかね?

できないということで、了解しました。

ありがとうございます。

>先の回答で書いた Apache が 80 を開けてて、別のプロセスに振る、とか、

>全く別のプロセスが 80 を開けてて、Apache と nginx に振り分けるとか。

なるほど。

ロードバランサとかリバースプロキシというやつですかね。

nginx自体にそういう機能があるようなので、勉強してみます。

2011/08/14 23:41:29

その他の回答(2件)

id:a-kuma3 No.1

a-kuma3回答回数4596ベストアンサー獲得回数19352011/08/14 22:46:10ここでベストアンサー

ポイント80pt

1台のサーバ上で、Apacheとnginxの両方をポート80番で動かすことは可能でしょうか?

残念だけど、これは無理だよ。

socket の口を開けて待ち構えるようなプログラムでは、ポートを取りあうので、

既に別のプロセスが掴んでるポートを開けられない。


もし、やるとしたら、apache のモジュールを作って、別のポートで口を開けて待ってる nginx に

中継するようにすればできる。

Apache をフロントにした、Tomcat への中継をする mod_jk のようなイメージ。


mod_proxy を使えば、似たようなことはできるね。

http://a.example.com/aaa/ だけを http://a.example.com:8080/ へ転送して、

nginx は 8080 で、待ち構えておく、とか。

http://httpd.apache.org/docs/2.2/ja/mod/mod_proxy.html


--

(追記)

ごめん、typo を直した。

×ポートを取りある

○ポートを取りあう


ひとつのポートを、複数のプロセスが待ち受けるのは無理なんだけど、

サーバの外の人から見て、80 のポートに出したリクエストを、複数のプロセスが

応答を返すのはできると思うんだ。

先の回答で書いた Apache が 80 を開けてて、別のプロセスに振る、とか、

全く別のプロセスが 80 を開けてて、Apache と nginx に振り分けるとか。

id:DQNEO

>残念だけど、これは無理だよ。

>socket の口を開けて待ち構えるようなプログラムでは、ポートを取りあうので、

>既に別のプロセスが掴んでるポートを開けられない。


なるほど。プログラムがポートを占有してしまうイメージですかね?

できないということで、了解しました。

ありがとうございます。

>先の回答で書いた Apache が 80 を開けてて、別のプロセスに振る、とか、

>全く別のプロセスが 80 を開けてて、Apache と nginx に振り分けるとか。

なるほど。

ロードバランサとかリバースプロキシというやつですかね。

nginx自体にそういう機能があるようなので、勉強してみます。

2011/08/14 23:41:29
id:Jupiter2100 No.2

じゅぴたー回答回数444ベストアンサー獲得回数742011/08/14 23:11:50

ポイント10pt

できません。

1ポートにつき1アプリケーション(1プロセス)というのがTCP/IP通信の取り決めなので、どうすることもできません。

id:DQNEO

ありがとうございます。

>1ポートにつき1アプリケーション(1プロセス)というのがTCP/IP通信の取り決め

なるほど、TCP/IPを勉強すればこの辺のことがわかるようになるんですね。

2011/08/14 23:38:11
id:saijyoh_739 No.3

saijyoh_739回答回数113ベストアンサー獲得回数102011/08/14 23:43:24

ポイント10pt

> 1台のサーバ上で、Apacheとnginxの両方をポート80番で動かすことは可能でしょうか?

できます。

IPアドレスはネットワークインターフェースに一つずつ割り当てる事もできます。

つまり、複数のNICを持ったコンピュータには複数の事なるIPアドレスを設定できます。

また、一つのNICでもIP Alias(別名アドレス)を設定すれば一つのNICに複数のIPアドレスを割り当て使う事も可能です。

サーバで設定している複数のIPアドレスを『Apache』用と『nginx』用で用意すれば両方のアドレスで80番ポートのウェブサーバをサービスする事ができます。

id:DQNEO

IPアドレスが複数あれば、それぞれを80番ポートに割り当てることができるんですね!

何となく原理がわかってきました。

ありがとうございました。

2011/08/14 23:49:41
  • id:DQNEO
    もしかして、グローバルIPを振られたNICが2つついてあればできるんですかね?

    (もちろんレンタルサーバとかVPSだとそれができないですが)
  • id:a-kuma3
    >もしかして、グローバルIPを振られたNICが2つついてあればできるんですかね?
    残念、それも無理。
    ホスト側では、自分がどのIPアドレスでアクセスされたか、というのと関係なく、
    ポートを開けて待つようになってるので、ポートが別のプロセスで使われてると、
    ポートを開くことができない。

    ただ、仮想化されていれば、話は別。
    仮想化されているホストごとに、80 のポートで待ち受けることはできます。
  • id:DQNEO
    なんとなく解決方法が見えてきました。

    nginx:ポート80
    apache:ポート8080

    のようにしておいて、
    nginx側で、
    a.example.com のリクエストを受け取ったら a.example.com:8080に転送する、
    b.example.com のリクエストを受け取ったら、そのままバーチャルホストを表示させる

    これで行けそうな気がしました。
    そして今気づいたのですが、これってa-kuma3さんが提案してくださったのがこの案(apacheとnginxが逆のパターン)だったのですね。
  • id:a-kuma3
    >そして今気づいたのですが、これってa-kuma3さんが提案してくださったのがこの案(apacheとnginxが逆のパターン)だったのですね。

    そうそう。
    申し訳ないが、nginx のことをあまり知らないので、Apache 寄りの回答を書きました。
    nginx で、URL のドメイン部分を見て、転送する機能があるのなら、それでいけると思います。
  • id:DQNEO
    みなさまご親切にありがとうございました。
    今思えば質問自体が間違っていたような気がします。

    やりたかったことが解決できそうなので、質問は終了とさせていただきます。
  • id:TransFreeBSD
    >自分がどのIPアドレスでアクセスされたか、というのと関係なく、ポートを開けて待つようになってるので、
    apacheもnginxも設定上はIPアドレスを指定できるようですが、実際には無理な何かがあるのでしょうか?
    http://httpd.apache.org/docs/2.2/bind.html
    http://nginx.org/ja/docs/http/request_processing.html
  • id:saijyoh_739
    # a-kuma3
    # ホスト側では、自分がどのIPアドレスでアクセスされたか、というのと関係なく、
    # ポートを開けて待つようになってるので、ポートが別のプロセスで使われてると、
    # ポートを開くことができない。

    できめす。
    ポートを開くというのはIPアドレス:ポートの組み合わせで開くという事で80番ポートを単独で開けるわけではありません。

    それと、一つのIPアドレスで複数の80番ポートで提供するサービスは行えます。
    ※難しかったり面倒だったりはしますが。

    Aoacgeで名前ベースのバーチャルホストとかWebサービスとWebDAVとか。
    ※ httpのホストヘッダで振り分け転送する事で可能です。

    a-kuma3さんはTCP/IPの基礎的な知識を持ってないか、今回に限って勘違いで思い込んでいる事で間違った答えをしているか。

    問題は解決されているという事なので


    # TransFreeBSD
    # >自分がどのIPアドレスでアクセスされたか、というのと関係なく、ポートを開けて待つようになってるので、
    # apacheもnginxも設定上はIPアドレスを指定できるようですが、実際には無理な何かがあるのでしょうか?

    a-kuma3さんの単なる誤解です。
    サーバはポートを待っている訳ではなく、このアドレスのこのポートという組み合わせで待ってます。

    例えばnetstat コマンドで


    tcp4 0 0 localhost.http *.* LISTEN
    tcp4 0 0 192.168.64.1.http *.* LISTEN
    tcp4 0 0 192.168.65.1.http *.* LISTEN
    tcp4 0 0 *.http *.* LISTEN

    こんな感じになります。

    ※ IP ALIASで複数アドレス作ってhttpd.conf幾つか作って(IPアドレス別)
    httpd -f address1.conf
    httpd -f address2.conf
    httpd -f address3.conf
    上記の様な感じで沢山動かしてみてください。
    簡単に確認できると思います。
  • id:DQNEO
    > ポートを開くというのはIPアドレス:ポートの組み合わせで開くという事で80番ポートを単独で開けるわけではありません。

    そうなんですね。
    確認してみます。

    ありがとうございます!
  • id:a-kuma3
    id:saijyoh_739 さんへ。
    >a-kuma3さんの単なる誤解です。
    >サーバはポートを待っている訳ではなく、このアドレスのこのポートという組み合わせで待ってます。

    いや、まぢで分からん。
    bind() にも、listen() にも、accept() にも、自分のIPアドレスを制限する、ということに該当する指定が無いと思うんだけど。
    どの API の、どの引数に設定するの?
  • id:TransFreeBSD
    FreeBSD http://www.freebsd.org/cgi/man.cgi?query=bind&apropos=0&sektion=2&manpath=FreeBSD+8.2-RELEASE&format=html
    int bind(int s, const struct sockaddr *addr, socklen_t addrlen);

    linux http://www.kernel.org/doc/man-pages/online/pages/man2/bind.2.html
    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

    いずれもsockaddr構造体でポート番号と共にIPアドレスを指定できます。
    ただ、通常はアドレスをINADDR_ANYとして、全てのアドレスで受け付ける事が多いだけです。
    Windowsも同様だったと思いますし、おおよそのOSで可能だと思います。
    ソフトウェア上、運用上はまた別ですのでそれぞれでしょうけど。
  • id:a-kuma3
    あー、sockaddr_in.sin_addr !
    とんだ、赤っ恥だぜー。

    これ、接続先という認識があって、接続しに来るクライアントだと思ってました。
    当然、INADDR_ANY しか設定したことがありません (`・ω・´)キリッ

    勉強になりました >id:TransFreeBSD さん、id:saijyoh_739 さん

    ぼくにベストアンサーが付いてるのが、気になるんですが、
    お二方の回答、コメントが正しいです >id:DQNEO さん
    ポイントの再配分は、やっておきますんで m(_ _)m
  • id:DQNEO
    私も大変勉強になりました。TCP/IPの勉強をしてみます。

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません