Go 言語の標準ライブラリ net/http/httputil
には、リバースプロキシを作るための NewSingleHostReverseProxy
関数が用意されています。この関数を使うことで、Nginx で行うようなリバースプロキシを Go 言語のプログラム上で行うことができます。
下記コードを実行して http://localhost:10000/ にアクセスすると、hello, world
が返ってきます。ポート番号 10000〜10003 が使われていると正常に動作しないので注意が必要です。
package main
import (
"net/http"
"net/http/httputil"
"net/url"
"time"
"github.com/gin-gonic/gin"
)
func main() {
// サーバーを作成する
s10000 := gin.Default()
s10001 := gin.Default()
s10002 := gin.Default()
s10003 := gin.Default()
// s10000 へのルートパスのリクエストは s10001 と s10002 を経由して s10003 に渡る
s10000.GET("/", makeReverseProxy("10001"))
s10001.GET("/", makeReverseProxy("10002"))
s10002.GET("/", makeReverseProxy("10003"))
s10003.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "hello, world")
})
// 非同期にサーバーを立ち上げる
go s10000.Run(":10000")
go s10001.Run(":10001")
go s10002.Run(":10002")
go s10003.Run(":10003")
// プログラムが終わらないようにする
time.Sleep(time.Hour)
}
func makeReverseProxy(port string) func(*gin.Context) {
return func(c *gin.Context) {
remote, _ := url.Parse("http://localhost:" + port)
proxy := httputil.NewSingleHostReverseProxy(remote)
proxy.ServeHTTP(c.Writer, c.Request)
}
}
この仕組を使うことで、モノリシックな Web サーバーを複数の Web サーバーに分割できます。将来は複数のサーバーで運用したいけれど、とりあえずはひとつのサーバーで動かしたいといったときに使えるのではと思っています。