Go语言实现单端口转发到多个端口

 更新时间:2024年02月20日 10:16:29   作者:沙振宇  
这篇文章主要为大家详细介绍了Go语言实现单端口转发到多个端口,文中的示例代码讲解详细,具有一定的参考价值,对大家的学习或工作有一定的帮助,需要的小伙伴可以了解下

1、背景

运维和我提到这个需求的时候,我先是一愣,第一时间想到的是nginx,然后运维说nginx没有这个功能……之所以选择用go语言,主要两点:

  • 静态语言性能够用
  • 不用部署其它包,可以直接丢一个可执行程序和一个配置上去就能运行。

2、正题

这种东西,一看就肯定有前辈做过,于是自行github上找了一圈,果然有答案:
https://github.com/vulcand/oxy

于是用了,上述这个包,写程序调用一下即可。

该包引用了其它开源的包哈(也可以用go mod哈,就不用自己去下载包啦~):
https://github.com/gorilla/websocket
https://github.com/mailgun/timetools
https://github.com/sirupsen/logrus

https://github.com/golang/sys
https://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、效果

以上就是Go语言实现单端口转发到多个端口的详细内容,更多关于Go单端口转多端口的资料请关注脚本之家其它相关文章!

相关文章

  • 深入了解Golang网络编程Net包的使用

    深入了解Golang网络编程Net包的使用

    net包主要是增加 context 控制,封装了一些不同的连接类型以及DNS 查找等等,同时在有需要的地方引入 goroutine 提高处理效率。本文主要和大家分享下在Go中网络编程的实现,需要的可以参考一下
    2022-07-07
  • 一文带大家了解Go语言中的内联优化

    一文带大家了解Go语言中的内联优化

    内联优化是一种常见的编译器优化策略,通俗来讲,就是把函数在它被调用的地方展开,这样可以减少函数调用所带来的开销,本文主要为大家介绍了Go中内联优化的具体使用,需要的可以参考下
    2023-05-05
  • Golang算法问题之整数拆分实现方法分析

    Golang算法问题之整数拆分实现方法分析

    这篇文章主要介绍了Golang算法问题之整数拆分实现方法,结合实例形式分析了Go语言数值运算与数组遍历相关操作技巧,需要的朋友可以参考下
    2017-02-02
  • Go get命令使用socket代理的方法

    Go get命令使用socket代理的方法

    由于某些不可描述的原因,国内使用 go get 命令安装某些包的时候会超时导致失败,比如 net 包、 sys 包、 tools 包等。这篇文章给大家介绍go get 命令使用socket 代理的方法,感兴趣的朋友一起看看吧
    2018-10-10
  • go语言的sql包原理与用法分析

    go语言的sql包原理与用法分析

    这篇文章主要介绍了go语言的sql包原理与用法,较为详细的分析了Go语言里sql包的结构、相关函数与使用方法,需要的朋友可以参考下
    2016-07-07
  • Go time包AddDate使用解惑实例详解

    Go time包AddDate使用解惑实例详解

    这篇文章主要为大家介绍了Go time包AddDate使用解惑实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 在Go中使用JSON(附demo)

    在Go中使用JSON(附demo)

    Go开发人员经常需要处理JSON内容,本文主要介绍了在Go中使用JSON,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • golang开发go包依赖管理godep使用教程

    golang开发go包依赖管理godep使用教程

    这篇文章主要为大家介绍了golang开发go包依赖管理godep使用教程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • Golang中Append()使用实例详解

    Golang中Append()使用实例详解

    今天在刷leetcode的时候,第113题让我遇到了一个Go语言中append函数的一个坑,所以复习下,这篇文章主要给大家介绍了关于Golang中Append()使用的相关资料,需要的朋友可以参考下
    2023-01-01
  • go语言制作一个gif动态图

    go语言制作一个gif动态图

    这篇文章主要介绍了go制作一个gif动态图的相关资料,需要的朋友可以参考下
    2015-03-03

最新评论