Golang中如何实现单服务器/单端口托管多服务
Golang中如何实现单服务器/单端口托管多服务 大家好。虽然我觉得自己问了个有点傻的问题,但我真的很好奇。显然,运行两个不同服务的最佳选择是让它们在不同的地址上运行,但假设我是一个手头拮据的大学生/农民,只想在业余时间构建一些玩具工具,而且以我的收入,确实只能负担得起一台VPS和一瓶可乐。那么,我的想法是,或许可以在不同的端口上运行服务。不过,除此之外,我还在考虑一个更程序化的解决方案。如果我拥有两个不同的“.tk”域名,并将它们指向同一个IP地址,我是否可以通过引荐来源(referrer)来判断我实际使用的是哪个地址?也就是说,“example1.tk”和“example2.tk”可以导向两种完全不同的体验,即使它们运行在同一台服务器的同一个端口上,对吗?有没有一种更合适的方法来实现这一点,而不需要解析请求并消耗大量的CPU周期?
更多关于Golang中如何实现单服务器/单端口托管多服务的实战教程也可以访问 https://www.itying.com/category-94-b0.html
您可以在不同的非特权端口上运行它们,并在80/443端口上设置第三个服务,这个第三个服务就是所谓的反向代理。它将根据配置的规则,将请求转发给配置好的“后端”服务。
在那之后,我的假设是只需在不同的端口上运行服务。不过,除此之外,我正在考虑一个更程序化的解决方案。
你可以使用 Nginx 并将它们代理到不同的端口。我推荐使用 Cloudflare 来管理 DNS。https://hosting.go4webdev.org/howto
你好 @ashinnv,
你有几个选择。
选项1: 通过URL路径区分两个服务。例如,
https://yourdomain.tk/api/service1/...
https://yourdomain.tk/api/service2/...
选项2: 使用子域名。如果你拥有一个域名,可以创建子域名,例如,
https://service1.yourdomain.tk/api/...
https://service2.yourdomain.tk/api/...
通常,每个子域名会解析到一个独立的IP地址,但你也可以让它们解析到同一个IP地址,并通过你的代码根据子域名来路由请求。
选项3: 使用反向代理将请求路由到两个不同的进程——这是 @NobbZ 和 @luk4z7 的建议。(Traefik 就是这样一个反向代理。)
这个选项需要最多的工作量(设置反向代理、管理三个不同的进程……),但作为回报,你获得了更大的灵活性。你可以重启一个服务而不影响另一个,可以相当容易地添加第三个服务,可以实现服务无停机更新:首先在一个不同的端口启动服务的新版本,然后让代理将所有新请求导向这个新版本,当所有现有请求完成后,就可以关闭旧版本的服务。
关于CPU周期:特别是选项1和2,应该不会给你的CPU增加任何显著的负载。换句话说,处理一个请求所需的CPU周期应该远多于路由本身。
如有疑问,请测试和衡量。
在Go中实现单端口托管多服务,最合适的方式是通过HTTP主机头(Host header)进行路由,而不是解析referrer。这种方法效率高且符合HTTP标准。以下是一个简单示例:
package main
import (
"fmt"
"net/http"
)
func main() {
mux := http.NewServeMux()
// 为example1.tk定义处理函数
mux.HandleFunc("example1.tk/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "欢迎访问服务1")
})
// 为example2.tk定义处理函数
mux.HandleFunc("example2.tk/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "欢迎访问服务2")
})
// 默认处理
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "未知域名")
})
http.ListenAndServe(":80", mux)
}
对于更复杂的场景,可以使用第三方路由库如gorilla/mux:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func service1Handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "服务1的内容")
}
func service2Handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "服务2的内容")
}
func main() {
r := mux.NewRouter()
// 基于主机头路由
r.Host("example1.tk").HandlerFunc(service1Handler)
r.Host("example2.tk").HandlerFunc(service2Handler)
http.ListenAndServe(":80", r)
}
这种方法消耗的CPU资源极少,因为HTTP主机头是每个请求的标准部分,解析成本可以忽略不计。你只需要将两个域名都指向同一个VPS的IP地址,然后在服务器上配置相应的路由逻辑即可。

