在一个 IP 上托管多个 Golang 站点并根据域请求提供服务?
Posted
技术标签:
【中文标题】在一个 IP 上托管多个 Golang 站点并根据域请求提供服务?【英文标题】:Host Multiple Golang Sites on One IP and Serve Depending on Domain Request? 【发布时间】:2017-02-15 02:11:20 【问题描述】:我正在运行安装了 Ubuntu 的 VPS。如何在url中不指定端口(xxx.xxx.xxx.xxx:8084)的情况下,使用同一个VPS(同一个IP)服务多个Golang网站?
例如,Golang 应用 1 正在侦听端口 8084,Golang 应用 2 正在侦听端口 8060。我希望在有人从域 example1.com
请求时服务 Golang 应用程序 1,当有人从域 example2.com
请求时服务 Golang 应用程序 2。
我确信你可以使用 nginx 做到这一点,但我无法弄清楚如何。
【问题讨论】:
nginx.com/resources/admin-guide/reverse-proxy 【参考方案1】: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 或类似方法为每个主机创建一个路由,甚至从中获取一个“子路由器”
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)
【讨论】:
我知道这是如何工作的,但是要托管多个网站,这种方法可能有点混乱。 这完全取决于架构设计。以microservices 为例。我并不是说反向代理是一个坏主意,只是需要考虑更多选项。【参考方案2】:请尝试以下代码,
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.1
或 http://localhost
【讨论】:
这是给 Nginx 的? 是的,先生,它是用于 nginx, 抱歉耽搁了,我只是在设置,我现在就试试! 罗杰先生, 对于每个站点,我应该声明一个新的server
还是只让 1 个 server
管理我的所有 go-sites?【参考方案3】:
您不需要任何第三方路由器。只需创建一个实现 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上阅读更多相关信息
【讨论】:
感谢这个解决方案,一直在寻找使用 go 而不是 nginx 或 apache 的东西。以上是关于在一个 IP 上托管多个 Golang 站点并根据域请求提供服务?的主要内容,如果未能解决你的问题,请参考以下文章
在多个绑定上托管 IIS 站点时如何获取正确的本地地址 URI?