クラウド時代のWebアプリケーション・スマートフォンアプリを開発・運用する会社です。 03-4577-8680 03-6673-4950

アプリケーションサーバにポートを指定せずに起動すると?

2019-05-04

最近、

Goで書かれたアプリケーションサーバが起動しない! ->原因: .env ファイルが欠けていた

というドタバタがありました。

結局Goと関係ないですが、この時、

「あまりGoに慣れてないのでGoの問題かと…」「DockerまだよくわかってなくてDockerの問題かと…」

というような声があったのて、あえてGoで検証してみようと思ったわけです。

さて、Goでサーバサイドのシステムを作る場合、

直接的・間接的(echoなどのフレームワーク経由で)に、netパッケージの機能を使うことになると思います。

そして多くの場合、設定ファイルや.env・環境変数などでGo外部からListenするポート番号を指定することになります。

ではうっかり、ポート番号が空になってしまった場合、どのような挙動になるのでしょうか。

ポートの指定は string なので “:” となっている場合、ということですね。

ということでさっそく、次のようなコードで実験してみましょう。

main.go

package main

import (
“fmt”
“net”
“net/http”
)

func main() {
http.HandleFunc(“/”, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, “Hello, world.”)
})
listener, err := net.Listen(“tcp”, “:”)
if err != nil {
panic(err)
}
fmt.Println(“Port:”, listener.Addr().(*net.TCPAddr).Port)
panic(http.Serve(listener, nil))
}

go run main.go

おそらく、怪しげなポート番号が表示されるはずです。
Ctl+C で停止して、何度か実行してみると、ポート番号は起動するたびに変化していることがわかります。

しかもポート番号の数字が大きめです。

これはいわゆる「Port 0」の挙動ですね。Go 関係ありません。

0番は使用できないことになっているので、動的ポート番号領域(つまり 49152 以上)が割り振られるというやつです。

たとえば echo の場合、起動時にこういうメッセージバナーが表示されます。

/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.1.5
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:8080

ここで起動中のポート番号が表示されるので、

「あれ?起動してるのに接続できない!なんで!?」

ということがあった場合には、

まず想定通りのポートで立ち上がっているかを確認してみた方がいいですね。

プロキシが間にある場合や、Dockerで立ち上げている場合はとくに。