Golang Go语言中使用反向代理,怎么处理代理失效的问题

发布于 1周前 作者 itying888 来自 Go语言

Golang Go语言中使用反向代理,怎么处理代理失效的问题

如下代码, 使用了 echo 框架, 将主程序 /xy/* 的请求代理到 http://xy.abc.com/xy/*

proxy := httputil.NewSingleHostReverseProxy("http://xy.abc.com")

e.Any("/xy/*", echo.WrapHandler(proxy))

实际使用过程中发现很多不稳定, 用着用着 404 了, 如果 http://xy.abc.com 后启动, 主程序的代理也不生效, 这个用法感觉很原始,需要自己去处理状态检测。

有什么好的处理办法吗


更多关于Golang Go语言中使用反向代理,怎么处理代理失效的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

你的描述比较模糊.

> 实际使用过程中发现很多不稳定, 用着用着 404 了
如果是 echo 返回了 404, bug 得去 echo 开发者那去问下.

> 如果 http://xy.abc.com 后启动, 主程序的代理也不生效
不生效是指 404 还是 502 ? 也得去看 echo 开发者去问下.

> 这个用法感觉很原始,需要自己去处理状态检测。
通常反向代理通常只负责转发请求, 并不负责返回 404. 报错或超时了会返回 502.
高级点确实需要健康检查, 比如定期给后端发送 HEAD /healthy . 收到 200 则认为 ok 否则认为挂球.

更多关于Golang Go语言中使用反向代理,怎么处理代理失效的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这种用法有些罕见啊,一般都是 nginx 、envoy 、traefik 等专门来反向代理、负载均衡。




实际项目中,有几个不同的子系统模块,使用了其他语言 node,php 开发,和主系统一样都是提供 json api 的 webserver

所以在主程序这里对所有前端请求做 分发, 由于在前端直接调用子系统的 API 会有一些问题, 比如跨域的兼容性, 统一权限拦截处理,子系统是没有权限判断的,统一在主系统 webserver 处理。


这应该算是比较简单的微服务调用吧


现在处理有了一点进展, 主系统处理了一个大 bug, 由于 grpc 连接处理不当导致的内存泄露(大量连接没有关闭)。解决这个 bug 后截止为止, 这个反向代理一直正常。但不能确定是不是 bug 引起的问题,应该是很有相关性, 继续观察。


http://xy.abc.com 后启动, 主程序的代理也不生效, 这个 status 是 404,去 echo 的 issues 列表看了下,没有很直接相关的主题,还是先定位下是不是我自己程序的 bug 吧。


对于服务分发调用,确实需要考虑更好地可靠性, 但暂时还不想引用过多的第三方工具(还达不到多大的量级),只能手工去加强这块的管理了, 至少可以先通过运维脚本监控重启解决。

http.ResponseWriter 封装一下,如果写入状态码 404 了,不 Writer 数据了,在反向代理完后,检查下状态码是不是 404,404 就自己执行额外操作。

随手的伪代码,没调试。

golang<br>type response struct{<br> http.ResponseWrite<br> Status int<br>}<br><br>func (w *response )Write(data []byte) (int, error) {<br> if w.Status==404 {<br> return 0,nil<br> }<br> return w.ResponseWrite.Write(data)<br>}<br><br>func (w *response )WriteHeader(code int) {<br> w.Status = code<br> w.ResponseWrite.WriteHeader(code)<br>}<br><br>func(addr string) echo.Handler {<br> proxy := httputil.NewSingleHostReverseProxy(addr)<br> return func(ctx echo.Context)<br> w := &amp;response{<br> ResponseWrite: ctx.Response(),<br> }<br> proxy.ServeHTTP(w, ctx.Reuest())<br> if w.Status==404 {<br> ctx.WriteString("proxy 404 啦")<br> }<br>}<br>

啊抱歉, 时隔一年多才上来看到回复.
> 实际使用过程中发现很多不稳定, 用着用着 404 了.
所以是哪些请求收到 404 了? 最好留下对应请求记录的,比如 http method 和 path 部分. 浏览器端 javascript 环境比较恶劣, 没准会出现 post get 傻傻分不清.

回到主题上, 你的反向代理, 如果后端给了响应就照实返回, 哪怕出错也会有个 5xx 之类的状态码返回.
其他情况比如后端启动慢, 一时半会访问不了, 这是后端的问题. 作为网关你只需返回 502. 这是 http 标准做法. 所有主流的反向代理都是这么干的.

p.s. 你实现的其实就是 api 网关, 挺合适, 甚至可以定制一些算法. 但我看你的例子里 http://xy.abc.com 是个外网地址? 虽然不影响逻辑. 但是通信质量会比内网差很多, 容易超时导致把账算在你网关的头上…

在Golang中使用反向代理时,遇到代理失效的问题,可以从以下几个方面进行排查和处理:

  1. 检查目标URL:确保反向代理配置的目标URL是正确的,包括协议(http/https)、主机名和端口。错误的URL会导致代理请求无法正确转发。
  2. 自定义Director函数:使用httputil.NewSingleHostReverseProxy创建反向代理时,可以自定义Director函数来修改请求。确保在Director函数中正确设置了req.URLreq.Host等字段。特别是req.Host,如果不设置,可能会导致代理请求无法正确路由到目标服务器。
  3. 检查网络连接:确认代理服务器能够访问目标服务器。网络问题、防火墙设置或目标服务器的可达性都可能影响代理效果。
  4. 查看错误日志:分析代理服务器和目标服务器的错误日志,可能包含有关代理失效的详细信息。
  5. SSL/TLS配置:如果目标服务器使用HTTPS,确保代理服务器正确配置了SSL/TLS证书和验证设置。

综上所述,处理Golang中反向代理失效的问题需要从多个方面进行排查,包括目标URL、自定义Director函数、网络连接、错误日志以及SSL/TLS配置等。根据具体情况采取相应的措施,通常可以解决代理失效的问题。

回到顶部