Go开发 之 单端口转发到多个端口

2023-10-26

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、效果

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go开发 之 单端口转发到多个端口 的相关文章

  • Golang Appengine 项目无法构建

    我有一个使用 golang 的应用程序引擎项目 我已经大约一年没有碰过了 我现在无法让它在之前构建的机器上构建 我收到以下错误 go app builder 解析输入失败 解析器 src golang org x net internal
  • Go SQL查询不一致

    我在执行查询时遇到一些非常奇怪的不一致 并且想知道是否有人知道原因 想象一下我有一个定义如下的结构 type Result struct Afield string db A Bfield interface db B Cfield str
  • 使用 crypto/ssh 的 golang scp 文件

    我正在尝试通过 ssh 下载远程文件 以下方法在 shell 上运行良好 ssh hostname tar cz opt local folder gt folder tar gz 然而 golang 上的相同方法在输出工件大小方面存在一些
  • Go 中的 WebP 编码器/解码器

    是否有一个完整的 WebP 编码器和解码器与当前每周 或可分叉 兼容 它的速度与标准 png 相当吗 这个人在 GitHub 上有一个包 其中包含 WebP 的编码器和解码器 https github com chai2010 webp h
  • 我们如何在 Golang 中组合多个错误字符串?

    我是 golang 新手 我的应用程序需要在循环中返回多个错误 稍后需要组合并作为单个错误字符串返回 我无法使用字符串函数来组合错误消息 在返回之前可以使用什么方法将这些错误合并为一个错误 package main import fmt s
  • 如何将未知字段类型的数据解组为 JSON

    我有这些 结构 type Results struct Gender string json gender Name struct First string json first Last string json last json nam
  • Golang 基础知识 struct 和 new() 关键字

    我正在学习 golang 当我阅读描述结构的章节时 我遇到了初始化结构的不同方法 p1 passport var p2 passport p3 passport Photo make byte 0 0 Name Scott Surname
  • 在 IntelliJ IDEA 中运行。多个文件和错误未定义:数据

    我想使用 IntelliJ IDE 社区版编写代码GO Go语言 我安装了正确的插件 并安装了构建应用程序所需的所有工具 我的应用程序包含以下两个文件 每个都在目录中 事件服务器 Main go Data go 如果我想使用 Run Ctl
  • 在 Go 中使用电子邮件地址创建证书签名请求 (CSR)

    我尝试使用 crypto x509 包生成 CSR 但没有找到将 emailAddress 字段添加到其主题中的方法 根据文档证书申请 http golang org pkg crypto x509 CertificateRequest结构
  • Gorm 总是返回带有 nil 值的结构

    我正在使用 Gorm 构建 Go Web API 作为 Amazon RDS 中 Postgresql 数据库的 ORM 问题是 Gorm 总是返回一片结构 其值全部为零 尽管数据库已经填充了数据 切片中的结构体数量是否合适取决于LIMIT
  • 如何在 Ubuntu 中将 Go 程序作为守护进程启动?

    在 Ubuntu 中将 Go 程序作为守护进程启动的正确方法是什么 然后我将使用 Monit 对其进行监控 我应该做这样的事情 go run myapp go 我应该考虑 Go 特有的事情吗 您应该为您的程序构建一个可执行文件 go bui
  • 如何在Go中将字节数组转换为字符串[重复]

    这个问题在这里已经有答案了 byte字符串会引发错误 string byte n 也会引发错误 顺便说一下 例如 文件名的 sha1 值是字符串 它是否明确需要 utf 8 或任何其他编码集 谢谢 我用来转换的最简单方法byte to st
  • bazel go_embed_data“无法嵌入”

    我将以下 bazel BUILD 配置为 gazelle name gazelle go embed data name static files srcs glob static package main var staticFS go
  • Golang HTTP Post 错误:连接被拒绝

    我正在尝试向正在运行 PHP 应用程序的端口 8080 上的本地主机发送 post 请求 卷曲效果很好 curl data key asdf http localhost 8080 但在 Go 中我收到以下错误 Post http loca
  • 使用ticker定期从经常变化的路径加载内存中的所有文件?

    我有一个应用程序需要从两个不同的路径读取文件 读取所有这些文件后 我需要将它们加载到内存中products map Path Full 这是内存中服务器启动期间需要加载的所有文件的路径 该路径将包含大约 50 个文件 每个文件大小约为 60
  • 如何通过map[string]interface{}递归迭代

    我遇到了一个问题 如何在附加条件下递归地迭代 map string interface 1 如果一个值是一个映射 递归调用该方法 2 如果一个值是一个数组 调用数组的方法 3 如果一个值不是一个映射 处理它 现在当方法尝试执行时doc th
  • Golang SSL TCP套接字证书配置

    我正在创建一个 Go TCP 服务器 不是 http s 并且尝试将其配置为使用 SSL 我有一个 StartCom 免费 SSL 证书 我正在尝试使用它来完成此任务 我的服务器代码如下所示 cert err tls LoadX509Key
  • 非本地包中的本地导入

    我知道应该避免本地进口 但在这种情况下有特殊情况需要 这是一个私人仓库 heroku buildpack 在go get 由于服务器上缺少私钥 与绝对 URL 一起使用时会出现此阶段 现在我得到这个错误local import in non
  • http:多余的response.WriteHeader调用

    我有一个HandleFunc 如果成功的话 我希望 显然 能够 sent a 200回复 在回复中写一条信息性消息 但是以下代码片段 在快乐路径中执行 if fullRun w Write byte successMsg w WriteHe
  • Golang 使用 gomail.v2 实现多个收件人

    我通过 gomail v2 发送电子邮件的唯一方法是在 for 循环中对每封电子邮件使用 Send 函数 但我需要向其他电子邮件地址显示已发送相同的电子邮件 for recipient range os Args 3 mail SetAdd

随机推荐

  • 2019浙江ACM省赛

    目录 E Sequence in the Pocket J Welcome Party K Strings in the Pocket E Sequence in the Pocket 题意 给定一组数 每次操作 可以把一个数抽出 放在数组
  • postgres的时间转换

    天下苦postgres时间转换久已 最近在操作数据库时 遇到频繁的时间操作 每次弄完了就忘了 今天痛定思痛 下定决心 终于自己也受不了自己的lazy了 对postgres的时间操作进行一下总结 本文竟可能详尽的记录postgres中涉及到d
  • 对称二叉树(Leetcode &101)

    题目 101 对称二叉树 思路 使用层序遍历 遍历当前层的节点时 如该节点的左 右 孩子为空 在list中添加null 否则加入左 右 孩子的值 每遍历完一层则对当前list进行判断 这里判断我用了一个很笨的方法 前面记录下一层节点值时就设
  • tomcat内存(jvm)、并发、缓存优化

    内存调优 rem次调整为高并发内存调优 rem 以下配置为JVM参数调优 set JAVA OPTS server rem 以服务器模式启动 启动速度慢 但更稳定 性能更好 Xms8192M rem 由于本机内存为16G 这里就设置成8G
  • 最全ES6详解及用法

    最全ES6详解及用法 前言 babel babel使用方法 变量的定义 let const this 和作用域 do 顶层对象 global对象 import class JS中的原型 原型语言 prototype proto constr
  • 降低 CPU 占用率的方法

    CPU 占用率和什么有关 答 1 单位时间内执行的指令数目多少 用户时间 2 I O操作时间 等待时间 3 线程调度花费的时间 软 硬中断 优先级调整时间 举个例子 好比一个大人 每次来回可以扛一袋大米 每天的任务要求扛 60 袋 假定来回
  • 软件架构设计

    软件架构设计 一 引言 软件架构的概念 软件架构设计及其生命周期 1 需求分析阶段 需求分析与SA研究二者的联系 2 设计阶段 3 实现阶段 4 构件组装阶段 5 部署阶段 6 后开发阶段 软件架构的重要性 引言 从第一个程序被划分成模块开
  • Unity3D 场景切换

    在Unity3D中 一个场景在运行中切换到另一个场景的方法 1 在Unity中 File gt Build Settings gt 把要切换的场景添加到Scenes In Build下面 也可以Add Open Scenes 添加完关闭这个
  • 详解Java中的BIO、NIO、AIO

    1 详解Java中的BIO NIO AIO 1 1 引言 IO流是Java中比较难理解的一个知识点 但是IO流在实际的开发场景中经常会使用到 比如Dubbo底层就是NIO进行通讯 本文将介绍Java发展过程中出现的三种IO BIO NIO以
  • 渗透测试笔记(五)——XSS跨站脚本攻击

    XSS简介 XSS Cross Site Scripting 跨站脚本 为了避免与CSS混淆 所以简称XSS XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点 进而添加一些代码 嵌入到Web页面中去 使别的用户访
  • 会话追踪技术:cookie、 URL重写

    servlet day4 会话追踪技术 cookie http协议的访问是无状态的访问 当前访问是不会知道之前访问的状态的 http协议的访问是不会帮我们保存访问的记录 痕迹的 有些时候需要记录之前的访问状态 比如在购物网站的时候 第一次访
  • 多线程与高并发编程进阶(二)

    前言 前文多线程与高并发入门中 已经介绍了多线程编程的目的以及实际应用中可能会遇到的问题 本文接着叙述关于多线程并发机制的底层原理 volatile以及synchronized 一般来说 Java代码从编写到最后的执行会经历以下的过程 Ja
  • 二叉树的基本操作(1)

    结点类型 struct TreeNode char val struct TreeNode l r TreeNode int x val x l nullptr r nullptr 新建一个类 名为solution 相关函数都放在这里面调用
  • 分类预测

    分类预测 MATLAB实现LSSVM 最小二乘支持向量机 分类 目录 分类预测 MATLAB实现LSSVM 最小二乘支持向量机 分类 最小二乘法 最小二乘支持向量机 程序设计 主程序 子程序 拓展知识 参考资料 致谢 最小二乘法 最小二乘法
  • 利用python实现163邮箱邮件的自动删除

    问题 163邮箱收信箱大量邮件无法批量删除 解决思路 利用python控制鼠标实现邮件自动删除 利用python的pyautogui实现鼠标的控制 import pyautogui as pg screenWidth screenHeigh
  • 海洋浮标数据显示系统

    R语言是现今世界上数据处理和可视化领域非常流行的数据处理语言 其类似于matlab 是开源的 功能强大的数据处理工具 Oracle是企业级的数据库 能够存储大量数据并且方便管理和使用 本文主要是基于R与oracle对美国国家海洋与大气管理局
  • 老师给我的指点——深刻剖析了我

    今天上午找导师有事 导师坐下来和我聊了聊 他说 就他的观察 我有以下几个方面的问题 一 感觉我在做事上总是欠缺那么一点东西 就是说 给我的事情 我是能做完也让别人没法批评我 但是总感觉欠缺一点东西 相比师妹 每次给任务1分可以做完1 2分
  • 函数式编程实例WordCount(林子雨老师慕课代码) 由于文件引入的问题之前报过Exception in thread “main“ java.lang.NullPointerExcept(已解决)

    函数式编程实例WordCount 数据文件目录 文件内容 刚开始在写文件的时候以为val dirfile new File data 这一行写的是具体文件 于是我写成了这样 运行之后始终给我报空指针异常 后面仔细研究文件 原来val dir
  • Linux 系统启动过程

    简介 Linux 系统启动过程大致分为5个阶段 1 内核的引导 2 运行 init 3 系统初始化 4 建立终端 5 用户登录系统 内核引导 计算机通电后 首先会进行 BIOS 开机自检 然后根据BIOS中设置的启动设备 一般是硬盘 来启动
  • Go开发 之 单端口转发到多个端口

    文章目录 1 背景 2 正题 3 源码 4 配置 5 效果 1 背景 运维和我提到这个需求的时候 我先是一愣 第一时间想到的是nginx 然后运维说nginx没有这个功能 之所以选择用go语言 主要两点 静态语言性能够用 不用部署其它包 可