DRYな備忘録

Don't Repeat Yourself.

nginxでプロキシが502 Bad Gatewayを吐く【ロードバランサ】【nginx】

問題

nginxでロードバランサとしても動くリバースプロキシを設定してみた。んだけど、502 Bad Gateway。なんじゃそりゃ?

要件

  • xxx.xxx.xxx.xxxというグローバルIP
  • tainaka.comという名前が与えられているリバースプロキシがいる
  • tainaka.comという名前でリクエストが来た場合は
  • 物理的には同サーバで動いているアプリケーションのポートにリクエストを振る
  • アプリケーションは複数プロセス立っていて、それぞれ違うポートで動いている
  • プロキシサーバはポート80番でnginxしか開かない

ロードバランサつくるお

以下のように/etc/nginx/nginx.confを設定

# 基本デフォルトなので抜粋
http {
    upstream ritsu {
        server localhost:19001;
        server localhost:19002;
        server localhost:19003;
        server localhost:19004;
        server localhost:19005;
    }
    server {
        listen 80;
        server_name tainaka.com;
        location / {
            proxy_pass http://ritsu;
        }
    }
}

上記のように、

upstream {{クラスタ名}} {
    server {{アプリケーションアドレス:ポート}};
    # ...
    ## もちろんリモートも可
}

を設定しておけば

server {
    listen {{公開プロキシポート}}
    server_name {{公開ホスト名}}
    location {{アクセスパス}} {
        proxy_pass http://{{クラスタ名}}
    }
}

で、田井中.comでアクセスが来たら律アプリケーション(複数)に振り分けることができる。ぺろぺろ。 超簡単。

f:id:otiai10:20131010095124j:plain

(とはいえ、わたくしapacheでロードバランサつくったことないので何をもって"超簡単"と言えるのか比較対象無いんですけどね)

502だお

sudo /etc/init.d/nginx restart

そしてブラウザからtainaka.comにアクセスすると

f:id:otiai10:20131010092715p:plain

( ゚∀゚)・∵. グハッ!!

502だしググった

色々ためす

  • upstreamを使わず、ロードバランサしないただのリバースプロキシ立ててやってみたけど、まあちゃんと動く
  • localhost? 127.0.0.1? アドレス指定を色々工夫してみても、まあ502

解決した

これであった diff -C3 nginx.conf.wrong nginx.conf.correct

*** nginx.conf.wrong 2013-10-10 09:39:13.209641000 +0900
--- nginx.conf.correct    2013-10-10 09:39:32.209641001 +0900
***************
*** 1,10 ****
  http {
      upstream ritsu {
!         server localhost:19001;
!         server localhost:19002;
!         server localhost:19003;
!         server localhost:19004;
!         server localhost:19005;
      }
      server {
          listen 80;
--- 1,10 ----
  http {
      upstream ritsu {
!         server localhost:18001;
!         server localhost:18002;
!         server localhost:18003;
!         server localhost:18004;
!         server localhost:18005;
      }
      server {
          listen 80;

つまりアプリケーションのポートを間違えて書いていた。

結局502とは

  • 名前解決できて
  • プロキシサーバ発見できてコネクションも成立して
  • だけどプロキシサーバより先のサーバ(上位サーバっていうの?)が
  • 「正しいレスポンスを」「何かしらの理由で返してくれない」場合
  • 502 Bad Gateway

ということになるのか?StackOverflowでは、通信バッファとかcgi設定をミスってたりとかの理由で「返してくれない」みたい。今回では「上位サーバが見つからない」という理由。でも名前解決できてコネクション成立してるから404ではないわけか。

プロキシ挟んでいるぶんだけ、HTTPのステータスもよく分からん情報量足らんな感じなのかな。

雑感

  • 辛いもの食べた翌日に必ずお腹痛いので辛い
  • できること増えてきた一方で「知っておかねばならない知識」を知らない気がする
  • やや危険

DRY

nginx実践入門 (WEB+DB PRESS plus)

nginx実践入門 (WEB+DB PRESS plus)

Nginx ポケットリファレンス

Nginx ポケットリファレンス