Go开发 之 单端口转发到多个端口
原创
©著作权归作者所有:来自51CTO博客作者wx635f8a025188b的原创作品,请联系作者获取转载授权,否则将追究法律责任
文章目录
- 1、背景
- 2、正题
- 3、源码
- 4、配置
- 5、效果
1、背景
运维和我提到这个需求的时候,我先是一愣,第一时间想到的是nginx,然后运维说nginx没有这个功能……之所以选择用go语言,主要两点:
- 静态语言性能够用
- 不用部署其它包,可以直接丢一个可执行程序和一个配置上去就能运行。
2、正题
这种东西,一看就肯定有前辈做过,于是自行github上找了一圈,果然有答案:
https://github.com/vulcand/oxy
于是用了,上述这个包,写程序调用一下即可。
该包引用了其它开源的包哈(也可以用go mod哈,就不用自己去下载包啦~):
https://github.com/gorilla/websockethttps://github.com/mailgun/timetoolshttps://github.com/sirupsen/logrus
https://github.com/golang/syshttps://github.com/go-mgo/mgo/tree/v2
3、源码
/**
* 2020 5 21 - sha zhen yu
*/
package main
import(
"log"
"strings"
"net/http"
"io/ioutil"
"encoding/json"
"github.com/vulcand/oxy/forward"
"github.com/vulcand/oxy/testutils"
)
type Rule struct{
Domain string `json:Domain`
Address string `json:Address`
}
type Setting struct{
MainPort string `json:MainPort`
Rules []Rule `json:Rules`
}
var setting Setting
var fwd *forward.Forwarder
func redirectHandle(w http.ResponseWriter, r *http.Request){
address := getAddress(r.Host)
if address != "" {
r.URL = testutils.ParseURI("http://"+address)
log.Println("Info: "+r.Host+" => "+address)
fwd.ServeHTTP(w, r)
} else {
w.WriteHeader(500)
}
}
func getAddress(host string) string {
for _,v := range setting.Rules {
if strings.Compare(host,v.Domain) == 0 {
return v.Address
}
}
return ""
}
func Init(){
log.Println("Init: start")
var Data,err = ioutil.ReadFile("setting.json")
if err != nil{
log.Fatal("Read Config File Error!")
return
}
err = json.Unmarshal(Data,&setting)
if err != nil{
log.Fatal("Read Config JSON Error!Please Check!")
return
}
log.Println("Main Port: "+setting.MainPort)
for i:=0;i<len(setting.Rules);i++{
log.Println("Import Rule: "+setting.Rules[i].Domain+" <----> "+setting.Rules[i].Address)
}
log.Println("Init: end")
}
func main(){
Init()
fwd, _ = forward.New()
redirect := http.HandlerFunc(redirectHandle)
s := &http.Server{
Addr: ":"+setting.MainPort,
Handler: redirect,
}
log.Println("Info: Listening port "+s.Addr)
s.ListenAndServe()
}
4、配置
{
"name": "HttpProxyForwarding",
"version": "1.0.0",
"MainPort": "80",
"Rules": [
{
"Domain":"test1.shazhenyu.com",
"Address":"193.207.242.129:81"
},
{
"Domain":"test2.shazhenyu.com",
"Address":"193.207.242.129:82"
}
]
}
5、效果