目录:

  • 一、创建资源服务器(RealServer)
  • 二、创建代理服务器(Proxy)
  • 三、测试

** 一、创建资源服务器(RealServer)**

type RealServer struct {
	Addr string
}

func (r *RealServer) Run() {
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
		req.Header.Set("X-Forwarded-For", req.RemoteAddr)
		backend := fmt.Sprintf("Backend=http://%s%s?%s\n", r.Addr, req.URL.Path, req.URL.RawQuery)
		realIP := fmt.Sprintf("RemoteAddr=%s,X-Forwarded-For=%v,X-Real-Ip=%v\n", req.RemoteAddr, req.Header.Get("X-Forwarded-For"), req.Header.Get("X-Real-Ip"))
		header := fmt.Sprintf("Headers =%v\n", req.Header)
		io.WriteString(rw, backend)
		io.WriteString(rw, realIP)
		io.WriteString(rw, header)
	})
	mux.HandleFunc("/error", func(rw http.ResponseWriter, req *http.Request) {
		rw.WriteHeader(500)
		io.WriteString(rw, "error handler")
	})
	server := &http.Server{Addr: r.Addr, Handler: mux, WriteTimeout: time.Second * 3}
	go func() {
		log.Fatal(server.ListenAndServe())
	}()
	log.Println("Starting httpserver at " + r.Addr)
}

func main() {
	server1 := &RealServer{Addr: "172.*.*.249:8081"}
	server2 := &RealServer{Addr: "172.*.*.249:6061"}
	server1.Run()
	server2.Run()
	//监听关闭信号
	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
}

二、创建代理服务器(Proxy)

var realAddr, proxyAddr = "http://172.*.*.248:8081", "172.*.*.249:3000"

func ProxyHandler(rw http.ResponseWriter, req *http.Request) {
	// 0.浅拷贝请求对象组装新请求体
	var newReq = new(http.Request)
	*newReq = *req
	proxy, _ := url.Parse(realAddr)
	newReq.URL.Scheme = proxy.Scheme
	newReq.URL.Host = proxy.Host
	newReq.Header.Set("X-Real-Ip", proxy.Host)

	// 1.请求后端资源
	transport := http.DefaultTransport
	resp, err := transport.RoundTrip(newReq)

	// 2.回写客户端
	if err != nil {
		rw.WriteHeader(http.StatusBadGateway)
		log.Println(err)
		return
	}
	defer resp.Body.Close()
	for k, v := range resp.Header {
		for _, vv := range v {
			rw.Header().Add(k, vv)
		}
	}
	io.Copy(rw, resp.Body) // 或者bufio.NewReader(resp.Body).WriteTo(rw)
}

func main() {
	http.HandleFunc("/", ProxyHandler)
	log.Print("start proxy server on: ", proxyAddr)
	log.Fatal(http.ListenAndServe(proxyAddr, nil))
}

三、测试
在这里插入图片描述