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网络通信超时设置方式

    golang网络通信超时设置方式

    这篇文章主要介绍了golang网络通信超时设置方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Golang标准库time包日常用法小结

    Golang标准库time包日常用法小结

    本文主要介绍了Golang标准库time包日常用法小结,可以通过它们来获取当前时间、创建指定时间、解析时间字符串、控制时间间隔等操作,感兴趣的可以了解一下
    2023-11-11
  • Go读取配置文件的方法总结

    Go读取配置文件的方法总结

    我们常见的配置文件的格式一般有:XML、JSON、INI、YAML、env和.properties,本文小编为大家整理了Go语言读取这些格式的配置文件的方法,希望对大家有所帮助
    2023-10-10
  • Golang算法问题之整数拆分实现方法分析

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

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

    Golang简介与基本语法的学习

    这篇文章主要介绍了Golang简介与基本语法的学习,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • go语言定义零值可用的类型学习教程

    go语言定义零值可用的类型学习教程

    这篇文章主要为大家介绍了go语言定义零值可用的类型教程学习,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • Golang库插件注册加载机制的问题

    Golang库插件注册加载机制的问题

    这篇文章主要介绍了Golang库插件注册加载机制,这里说的插件并不是指的golang原生的可以在buildmode中加载指定so文件的那种加载机制,需要的朋友可以参考下
    2022-03-03
  • go语言中GoMock安装使用详解

    go语言中GoMock安装使用详解

    这篇文章主要为大家介绍了go语言中GoMock安装使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • 详解Go使用Viper和YAML管理配置文件

    详解Go使用Viper和YAML管理配置文件

    在软件开发中,配置管理是一项基本但至关重要的任务,它涉及到如何有效地管理应用程序的配置变量,本文将探讨如何使用Viper库配合YAML配置文件来实现高效的配置管理,感兴趣的可以了解下
    2024-04-04
  • Go语言基于HTTP的内存缓存服务的实现

    Go语言基于HTTP的内存缓存服务的实现

    这篇文章主要介绍了Go语言基于HTTP的内存缓存服务,本程序采用REST接口,支持设置(Set)、获取(Get)和删除(Del)这3个基本操作,同时还支持对缓存服务状态进行查询,需要的朋友可以参考下
    2022-08-08

最新评论