API网关在微服务系统中是必要的组件,承担了负载均衡,反向代理,统计,鉴权,监控等等职责。此处只就反向代理的功能做一个实现。
主要用到
httputil.ReverseProxy
对象。它的
Director
表示要重定向到的操作,
ModifyResponse
是你可以操作返回的结果。
proxy := httputil.NewSingleHostReverseProxy(target)
查看源码会发现 NewSingleHostReverseProxy()
的实现中,对req.URL.Path
的包装不太符合实际需求,于是需要自己来实现 Director
。另外此方法返回的ReverseProxy
对象并没有实现ModifyResponse
。
一个简单的反向代理服务器:
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"net/url"
"strings"
type handle struct {
host string
port string
type Service struct {
auth *handle
user *handle
func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var target *url.URL
if strings.Contains(r.RequestURI, "/api/stats") {
target, _ = url.Parse("http://" + s.auth.host + ":" + s.auth.port + "/show/stats")
} else if strings.Contains(r.RequestURI, "/api/autoCommentList") {
target, _ = url.Parse("http://" + s.user.host + ":" + s.user.port + "/show/autoCommentList")
} else {
fmt.Fprintf(w, "404 Not Found")
return
targetQuery := target.RawQuery
director := func(req *http.Request) {
req.URL.Scheme = target.Scheme
req.URL.Host = target.Host
req.URL.Path = target.Path
if targetQuery == "" || req.URL.RawQuery == "" {
req.URL.RawQuery = targetQuery + req.URL.RawQuery
} else {
req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
proxy := &httputil.ReverseProxy{Director: director}
proxy.ModifyResponse = func(response *http.Response) error {
cont, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(cont))
response.Body = ioutil.NopCloser(bytes.NewReader(cont))
return nil
proxy.ServeHTTP(w, r)
func startServer() {
service := &Service{
auth: &handle{host: "127.0.0.1", port: "8007"},
user: &handle{host: "127.0.0.1", port: "8007"},
err := http.ListenAndServe(":8888", service)
if err != nil {
log.Fatalln("ListenAndServe: ", err)
func main() {
startServer()
GoProxy是可配置的单目标反向代理HTTP处理程序,与net / http http.Handler接口兼容
func NewGoProxy
func NewGoProxy ( config * config. Config ) * GoProxy
NewGoProxy使用指定的路径前缀为每个提供的配置注册一个新的反向代理处理程序
func(* GoProxy)ServeHTTP
func ( g * GoProxy ) ServeHTTP ( w http. ResponseWriter , r * http. Request )
reproxy Reproxy是支持各种提供程序(docker,static,file)的简单边缘HTTP服务器/反向代理。
一个或多个提供者提供信息代理reproxy是支持各种提供者(docker,static,file)的简单边缘HTTP服务器/反向代理。
一个或多个提供程序提供有关请求的服务器,请求的URL,目标URL和运行状况检查URL的信息。
分发为单个二进制文件或docker容器。
可以将服务器设置为FQDN,iesexample.com或*(全部捕获)。
请求的URL可以是正则表达式,例如^ / api /(.*),而目标URL可能在其中有正则表达式匹配的组,即http://d.example.com:8080/$1。
1、 设置WriteHeader的顺序问题之前遇到个问题,在一段代码中这样设置WriteHeader,最后在header中取Name时怎么也取不到。?用 golang 写 http server 时,可以很方便可通过 w.Header.Set(k, v) 来设置 http response 中 header 的内容。但是需要特别注意的是:某些时候不仅要修改 response的header ,还要修...
本文介绍golang中如何进行反向代理。
下面例子中,
proxy server接收client 的 http request,转发给true server,并把 true server的返回结果再发送给client。
1.proxy server
proxyServer.go代码如下所示。
// proxyServer.go
package main
import (
"log"
"n...
1、客户两个部门,A部门在平台上训练模型,发布预测服务;B部门为新成立业务部门,需要去调用A的预测服务。B部门对发出的请求、返回都有明确的接口规范。A的预测服务,不同模型请求、返回参数不同,没有确定的格式,不会根据B要求做修改。
考虑在用户请求入口加一个proxy服务,功能:
①作为B的访问入口
②解析B发出的请求,筛选平台需要的字段
③将B的请求代理到后方预测服务上
④接收预测服务response,加上B需要字段
三、实现
使用ReverseProxy做代理,用ModifyRespon
正向代理的血案前几天打算使用golang做一个代理程序,golang标准库net/http/httputil已经提供了这样的能力。一把梭之后发现必然返回403 Forbidden, 我直接在target里面填上游服务实例ip就可以正确返回。给一个向代理百度官网的简化示例,大家可以体会一下:packagemain
import(
"fmt"
"log"
"net/htt...
// NewProxy takes target host and creates a reverse proxy
func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
url, err := url.Parse(targetHost)
目前已经有许多可用的代理服务了,比如ngrok和localtunnel,但ngrok有个缺点就是提供的域名只能用几个小时,然后需要新生成新的域名,如果想要固定域名就要花钱,但我们自已实现的代理可以用一个固定的域名,如果给前端同学来调试的话,不用改来改去,很方便。当我们在开发的时候,有时想要把自已开发的接口暴露给其他开发者或者第三方的服务,方便我们调试和排查问题,那就需要某种机制把我们本地的服务接口暴露到互联网上,本文将要介绍如何通过Golang和WebSocket来实现这一功能。## ggrok简介。
很久没水博客了,今天就来水一篇,说说go标准库的httputil.ReverseProxy
httputil.ReverseProxy顾名思义,http的反向代理,可以类比nginx的反向代理功能
httputil.ReverseProxy 定义了一组方法让使用者去实现,主要有这几个Director
最核心的方法, 我们可以在这里对请求进行相应的修改,比如设置请求目标的地址,对原有请求头进行增删改,以及对请求体进行处理等等操作。ModifyResponse
可以让我们对响应的结果进行处理,比如修改、读取响应