首页 > 其他分享 >golang 反向代理 Gin框架反向代理详解

golang 反向代理 Gin框架反向代理详解

时间:2022-11-24 19:13:42浏览次数:57  
标签:http name 代理 golang 反向 proxy shuiche router

前言

想用gin框架做一个反向代理服务,搜索了一圈,全是只讲解些皮毛的帖子,今天我就总结一下gin做反向代理的详细操作和原理

正文

开始之前我们先了解一些前置知识

gin的通配符

gin的动态路由可以自行查阅,我这里指列出两个通配符:冒号( :)、星号( * )

  • 冒号通配符

只能匹配到一层路由

// 路由请求
router.GET("shuiche/:name",  handle)

// 请求结果匹配
/shuiche/query     匹配
/shuiche/invoke    匹配
/shuiche/v1/find    不匹配
/shuiche/            不匹配
  • 星号通配符

能匹配到多层路由

// 路由请求
router.GET("shuiche/:name",  handle)

// 请求结果匹配
/shuiche/query     匹配
/shuiche/invoke    匹配
/shuiche/v1/find   匹配
/shuiche/          匹配

反向代理

概念:

反向代理是什么?有个很棒的说法是流量转发。服务端获取到客户端来的请求,将它发往另一个服务器,从另外一个服务器那里获取到响应再回给原先的客户端。反向的意义简单来说在于这个代理自身决定了何时将流量发往何处。

最小案例

我们先看一下最简单的代理案例

// router路由
router.Any("/proxy/*name", proxyHandler)

// api函数
func proxyHandler(c *gin.Context) {
	var target = "http://127.0.0.1:8081"
	proxyUrl, _ := url.Parse(target)
	proxy := httputil.NewSingleHostReverseProxy(proxyUrl)

	proxy.ServeHTTP(c.Writer, c.Request)
}

案例解释:
我们假设请求链接为: http://127.0.0.1:8080/proxy/test
我们假设:当前gin服务使用的端口是 8080, 被代理的服务器端口是8081,也就是说:客户端访问8080,8080 将请求转发给 8081

代理函数这里只做了一个事情:就是把 http://127.0.0.1:8080/proxy/test 原样发送给了 8081。

对与客户端来说,相当于发送了这样样的请求:http://127.0.0.1:8081/proxy/test

截取路由转发

有时候,我们的项目接口比较多,有些本地api,也有代理api,这时候就会给代理专门加一个前缀,例如:/proxy, 服务端拿到 /proxy 的路由请求全部做转发,这时候上面的案例就不能满足需求了,因为「最小案例」在做转发时会将 /proxy 原样转发到被代理的服务器上,这样就会报 404 错误。这时我们就需要将 /proxy 前缀去掉,看案例

// router路由
router.Any("/proxy/*name", proxyHandler)

// api函数
func proxyHandler(c *gin.Context) {
	var target = "http://127.0.0.1:8081"
	proxyUrl, _ := url.Parse(target)

	c.Request.URL.Path = c.Param("name")  //  重点是这行代码

        proxy := httputil.NewSingleHostReverseProxy(proxyUrl)

	proxy.ServeHTTP(c.Writer, c.Request)
}

案例解释:
我们在「最小案例」的代码基础上增加了一行代码,c.Request.URL.Path = c.Param("name") ,我们将请求的url地址重新修改为了 *name 匹配到的值,这样我们的服务在转发时就会转发新的请求地址

修改请求信息

有时候,我们在做代理时,需要增加一些新的请求头,比如增加鉴权 token 等字段到http的header里面

// router路由
router.Any("/proxy/*name", proxyHandler)

// api函数
func proxyHandler(c *gin.Context) {
	var target = "http://127.0.0.1:8081"
	proxyUrl, _ := url.Parse(target)

	c.Request.URL.Path = c.Param("name") 
	c.Request.Header.Set("token", "token_123") //  重点是这行代码

        proxy := httputil.NewSingleHostReverseProxy(proxyUrl)

	proxy.ServeHTTP(c.Writer, c.Request)
}

依然是只直接修改本来的请求内容,修改后再用 NewSingleHostReverseProxy 做代理,即可

服务器获取被代理服务的返回内容

参考这篇:https://www.coder.work/article/194458

另外一种写法

我们查看 httputil.NewSingleHostReverseProxy 源码时会发现,底层调用的其实还是 httputil.ReverseProxy 这个方法,我们也可以直接调用,

// router路由
router.Any("/proxy/*name", proxyHandler)


// api函数
func proxyHandler(c *gin.Context) {
        var target = "http://127.0.0.1:8081"
	director := func(req *http.Request) {
		req.URL.Scheme = "http"
		req.URL.Host = target
		req.Host = target
		req.URL.Path = c.Param("proxyPath")
	}
	proxy := &httputil.ReverseProxy{Director: director}
	proxy.ServeHTTP(c.Writer, c.Request)
}

案例解释:
如果有对http请求做处理的需求,都可以在 director 函数中修改,最终,代理转发的是 director 函数请求

后记

转发代理其实很简单,就好比:我让你帮我把一个物品给他 这么简单,你就是代理服务器,物品在过你手时,你可以对物品做二次处理,当然,他在把物品还回来的时候,你也可以拦截做二次处理。

如果你还有什么疑问,可以留言一起讨论

标签:http,name,代理,golang,反向,proxy,shuiche,router
From: https://www.cnblogs.com/shuiche/p/16922587.html

相关文章

  • python,requests高级用法,爬虫代理池,BautifulSoup4介绍
    requests高级用法ssl认证使用代理超时设置异常处理上传文件代理池搭建django后端获取客户端的ip爬取某视频网站爬取新闻BautifulSoup......
  • hive和mysql的笔记-反向overwrite,避免重复插入数据,量表关联更新
    hive和mysql的笔记-反向overwrite,避免重复插入数据,量表关联更新1反向overwrite操作->解决错误的插入数据的问题。描述:​ 例如​ 学生表:student<id,name,createtime......
  • Java 设计模式:代理模式
    目录代理模式(ProxyPattern)概述实现静态代理示例动态代理JDK动态代理示例源码分析CGLib动态代理示例源码分析业界实践代理模式(ProxyPattern)概述所属:结构性模式,提供了......
  • 节点反向追加得到根
    image.pngINodecurrentNode=this.keybutton.keyEntry;TreeNoderootTreeNode=null;while(currentNode!=null){......
  • 【go】golang 熔断器的实现过程
    熔断器像是一个保险丝。当我们依赖的服务出现问题时,可以及时容错。一方面可以减少依赖服务对自身访问的依赖,防止出现雪崩效应;另一方面降低请求频率以方便上游尽快恢复服务......
  • JDK动态代理
    知识点【publicclassJDKProxyimplementsInvocationHandler{privateObjecttargetObject;//代理的目标对象publicObjectcreateProxyInst......
  • 使用CGLIB生成代理
    知识点【使用前提条件:【/**如果这个代理的类没有实现接口就不能使用JDK中的动态代理*这时需要使用第三方的.jarCGLIB实现代理**/......
  • 为什么要使用IP代理服务器?代理服务器的基本功能有哪些?
    每一个网站背后都有一个固定的Ip地址,这个地址可以显示网站的身份地址,提高网站的安全系数。那么为什么要使用ip代理服务器?的基本功能有哪些?Maxproxy小编简单的告诉大家! ......
  • Maxproxy代理IP软件正式上线,完美替代911IP代理软件。
    7月28日911s5宣布永久性关闭服务,那么还有类似的软件替代吗?!答案是有的!  Maxproxy全球顶级IP代理服务商采用国际运营商纯住宅IP高性能、高匿名性、稳定的服务器、没......
  • JDK动态代理深入剖析
    1基于接口的代理模式什么是代理?简单来说,代理是指一个对象代替另一个对象去做某些事情。例如,对于每个程序员来说,他都有编程的能力:interfaceProgrammable{voidd......