这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天
青训营大项目使用Hertz作为http框架,其中由于对minio的访问带有对host的签名,所以需要通过Hertz server作为中转站来进行访问,即通过Hertz进行反向代理。
基础知识
路由
- 参数路由,例如:
/src/:path
| 路径 | 是否匹配 |
|---|---|
/src/ | 不匹配 |
/src/you | 匹配 |
/sec/you/test | 不匹配 |
- 通配路由,例如:
/src/*path
| 路径 | 是否匹配 |
|---|---|
/src/ | 匹配 |
/src/somefile.go | 匹配 |
/sec/subdir/somefile.go | 匹配 |
反向代理时使用到的是通配路由
反向代理
服务器根据客户端的请求,从其关系的一组或多组后端服务器(如 Web 服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知反向代理的 IP 地址,而不知道在代理服务器后面的服务器集群的存在。在日常使用中常用nginx来作代理,这里由于基础框架使用hertz,则只用起配套的反向代理功能。
proxy, err := reverseproxy.NewSingleHostReverseProxy("http://127.0.0.1:9090/")
需求
在访问代理server时通过特定的路由指向反向代理。
例如,将http://192.168.0.2:8080/src/*的均转发到http://127.0.0.1:9090/*,这样可以实现其他主机通过192.168.0.2暴露的8080端口访问到未对外开放的9090端口,且其他url信息保持不变。
实现
如下操作即可将反向代理注册到该路径下
h.GET("/src/*path", proxy.ServeHTTP)
但是会出现一个问题,转发时/src/也会一起转发最后访问到的是http://127.0.0.1:9090/src/*
所以在匿名函数中对path进行处理。
h.GET("/src/*path", func (c context.Context, ctx *app.RequestContext) {
proxy, _ := reverseproxy.NewSingleHostReverseProxy("http://127.0.0.1:9090")
ctx.Request.SetRequestURI(ctx.Param("path"))
hlog.CtxInfof(c, string(ctx.Request.URI().Path()))
proxy.ServeHTTP(c, ctx))
最后实现了hertz的反向代理。