在一个 IP 上托管多个 Golang 站点并根据域请求提供服务?

Host Multiple Golang Sites on One IP and Serve Depending on Domain Request?

我是 运行 VPS,安装了 Ubuntu。如何在url中不指定端口(xxx.xxx.xxx.xxx:8084)的情况下使用相同的VPS(相同的IP)为多个Golang网站提供服务?

例如,Golang 应用程序 1 正在侦听端口 8084Golang 应用程序 2 正在侦听端口 8060。我希望当有人从域 example1.com 请求时提供 Golang 应用程序 1,当有人从域 example2.com.

请求时提供 Golang 应用程序 2

我相信你可以用 Nginx 做到这一点,但我还没弄明白怎么做。

请尝试以下代码,

server {
   ...
   server_name www.example1.com example1.com;
   ...
   location / {
      proxy_pass app_ip:8084;
   }
   ...
}

...

server {
   ...
   server_name www.example2.com example2.com;
   ...
   location / {
      proxy_pass app_ip:8060;
   }
   ...
}

app_ip 是主机所在的机器的 ip,如果在同一台机器上,请输入 http://127.0.0.1http://localhost

Nginx 免费解决方案。

首先你可以重定向connections on port 80 as a normal user

sudo apt-get install iptables-persistent
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8000
sudo netfilter-persistent save
sudo netfilter-persistent reload

然后使用gorilla/mux或类似的方法为每个主机创建一个路由,甚至从中得到一个"subrouter"

r := mux.NewRouter()
s := r.Host("www.example.com").Subrouter()

所以完整的解决方案是

package main

import (
    "net/http"
    "github.com/gorilla/mux"
    "fmt"
)

func Example1IndexHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello www.example1.com!") // send data to client side
}

func Example2IndexHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello www.example2.com!") // send data to client side
}

func main() {
    r := mux.NewRouter()
    s1 := r.Host("www.example1.com").Subrouter()
    s2 := r.Host("www.example2.com").Subrouter()

    s1.HandleFunc("/", Example1IndexHandler)
    s2.HandleFunc("/", Example2IndexHandler)

    http.ListenAndServe(":8000", nil)
}

您不需要任何第三方路由器。只需创建一个实现 http.Handler 接口的主机交换机。

import (
    "fmt"
    "log"
    "net/http"
)

type HostSwitch map[string]http.Handler

// Implement the ServerHTTP method
func (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if handler, ok := hs[r.Host]; ok && handler != nil {
        handler.ServeHTTP(w, r)
    } else {
        http.Error(w, "Forbidden", http.StatusForbidden)
    }
}

我希望这能给您带来灵感。如果您需要完整的代码示例 https://play.golang.org/p/bMbKPGE7LhT

您还可以在 my blog

上阅读更多相关信息