11

使用 Nginx/Django 创建虚拟主机就像编写适当的配置一样容易。

对于 Go,我找到了这个https://codereview.appspot.com/4070043并且我知道我必须使用ServeMux但如何实现它?

我的意思是我的所有项目都必须有 1 个二进制文件,或者我必须创建一些“路由器”服务器来根据主机名路由请求?如何做到“走”?

4

2 回答 2

23

您是正确的,您将使用 ServeMux。ServeMux的godoc有一些关于如何使用它的详细信息。

在标准的 http 包中,有可以使用顶级 Handle 函数操作的 DefaultServeMux。例如,一个简单的虚拟主机应用程序可能如下所示:

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, world!")
    })
    http.HandleFunc("qa.example.com/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, improved world!")
    })
    http.ListenAndServe(":8080", nil)
}

在这个例子中,对 qa.example.com 的所有请求都将命中第二个处理程序,而对其他主机的所有请求都将命中第一个处理程序。

于 2013-01-05T13:18:34.210 回答
2

这是另一个如何使用 golang 提供“虚拟主机”功能的示例:

package main

import(
    "net/url"
    "net/http"
    "net/http/httputil"
)

func main() {
    vhost1, err := url.Parse("http://127.0.0.1:1980")
    if err != nil {
            panic(err)
    }
    proxy1 := httputil.NewSingleHostReverseProxy(vhost1)
    http.HandleFunc("publicdomain1.com/", handler(proxy1))

    vhost2, err := url.Parse("http://127.0.0.1:1981")
    if err != nil {
            panic(err)
    }
    proxy2 := httputil.NewSingleHostReverseProxy(vhost2)
    http.HandleFunc("publicdomain2.com/", handler(proxy2))

    err = http.ListenAndServe(":80", nil)
    if err != nil {
          panic(err)
    }
}

func handler(p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
            p.ServeHTTP(w, r)
    }
}

在这种情况下,每个“虚拟主机”可以是任何 http 服务器,如其他 golang net.http 网络服务器,甚至其他常规网络服务器,如 nginx。它们中的每一个都可以在同一个 ip 和另一个端口中,或者在另一个 ip 和任何端口中。如果您愿意,是否转发到不同的物理服务器并不重要。

于 2014-10-06T21:13:45.243 回答