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


最近、 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で立ち上げている場合はとくに。

最新記事

すべて表示

SQLite(sqlite3)で “no such table”

小ネタです。 SQLiteを使っていて "no such table" とエラーが出た場合、 DBファイル名の指定が空になっている、という凡ミスを起こしていないかを確認してみましょう。 ・・・ そういう凡ミスをしてしばし悩んだので… ファイル名の指定が空になっている場合、一時的なインメモリDBとして保存されます(※1)。 つまりDB接続を切断すると中身は消えます。 なので接続

GitLab 9.1.2 (MySQL) を 11.4.0 (PostgreSQL) にアップグレード

弊社ではかなり前からGitLab(CE)を自社環境で運用しているのですが、ふと気付くと、バージョンがだいぶ先に行ってしまっていました。 とくに最近のバージョンでは Auto DevOps なども使えるようになっていたりするので、さすがにそろそろキャッチアップしたいと考えたわけです。 現行の環境は次の通りです: GitLab 9.1.2 sameersbn/gitlab 使用 MySQL 5.6

Go のフレームワーク echo でCSRFミドルウェアを使う(3)CSRFトークンの送出にFormを指定する

「Go のフレームワーク echo でCSRFミドルウェアを使う」シリーズ第3弾です。 今回はソースを追いません。オマケ的な回です。 リファレンスのサンプルではHTTPヘッダで送出するパターンを想定していますが、リファレンス下部に header / form / query が使える旨の解説があります。 https://echo.labstack.com/middleware/csrf#conf