网络代理于网络转发区别

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)

 

 

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)

 

 

网络代理:

用户不直接连接服务器,网络代理去连接,获取数据后返回给用户

网络转发:

是路由器对报文的转发操作,中间可能对数据包修改

 

网络代理类型:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)

 

 网络代理之HTTP代理(golang反向代理、负载均衡算法实现)

 

 

 

正向代理:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)

 

 实现一个web浏览器代理:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)

 

 代码实现一个web浏览器代理:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)

 

 代码实现:

package main

import (
    "fmt"
    "io"
    "net"
    "net/http"
    "strings"
)

type Pxy struct{}

func (p *Pxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
    fmt.Printf("Received request %s %s %s\n", req.Method, req.Host, req.RemoteAddr)
    transport := http.DefaultTransport
    // step 1,浅拷贝对象,然后就再新增属性数据
    outReq := new(http.Request)
    *outReq = *req
    if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
        if prior, ok := outReq.Header["X-Forwarded-For"]; ok {
            clientIP = strings.Join(prior, ", ") + ", " + clientIP
        }
        outReq.Header.Set("X-Forwarded-For", clientIP)
    }
    
    // step 2, 请求下游
    res, err := transport.RoundTrip(outReq)
    if err != nil {
        rw.WriteHeader(http.StatusBadGateway)
        return
    }

    // step 3, 把下游请求内容返回给上游
    for key, value := range res.Header {
        for _, v := range value {
            rw.Header().Add(key, v)
        }
    }
    rw.WriteHeader(res.StatusCode)
    io.Copy(rw, res.Body)
    res.Body.Close()
}

func main() {
    fmt.Println("Serve on :8080")
    http.Handle("/", &Pxy{})
    http.ListenAndServe("0.0.0.0:8080", nil)
}

 

 

反向代理:

网络代理之HTTP代理(golang反向代理、负载均衡算法实现)

 

 

如何实现一个反向代理:

  • 这个功能比较复杂,我们先实现一个简版的http反向代理。
  • 代理接收客户端请求,更改请求结构体信息
  • 通过一定的负载均衡算法获取下游服务地址
  • 把请求发送到下游服务器,并获取返回的内容
  • 对返回的内容做一些处理,然后返回给客户端

 

启动两个http服务(真是服务地址)

127.0.0.1:2003
127.0.0.1:2004
package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    rs1 := &RealServer{Addr: "127.0.0.1:2003"}
    rs1.Run()
    rs2 := &RealServer{Addr: "127.0.0.1:2004"}
    rs2.Run()

    //监听关闭信号
    quit := make(chan os.Signal)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <-quit
}

type RealServer struct {
    Addr string
}

func (r *RealServer) Run() {
    log.Println("Starting httpserver at " + r.Addr)
    mux := http.NewServeMux()
    mux.HandleFunc("/", r.HelloHandler)
    mux.HandleFunc("/base/error", r.ErrorHandler)
    server := &http.Server{
        Addr:         r.Addr,
        WriteTimeout: time.Second * 3,
        Handler:      mux,
    }
    go func() {
        log.Fatal(server.ListenAndServe())
    }()
}

func (r *RealServer) HelloHandler(w http.ResponseWriter, req *http.Request) {
    //127.0.0.1:8008/abc?sdsdsa=11
    //r.Addr=127.0.0.1:8008
    //req.URL.Path=/abc
    fmt.Println(req.Host)
    upath := fmt.Sprintf("http://%s%s\n", r.Addr, req.URL.Path)
    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"))

    io.WriteString(w, upath)
    io.WriteString(w, realIP)
}

func (r *RealServer) ErrorHandler(w http.ResponseWriter, req *http.Request) {
    upath := "error handler"
    w.WriteHeader(500)
    io.WriteString(w, upath)
}
real_server

相关文章: