开源的反向代理项目推荐

ttps://bitbucket.org/tebeka/seamless是一个开源的反向代理项目,可将用户访问通过代理分流给多个后端服务器。可通过http接口动态增加删除后端服务。
项目主要文件有两个:seamless.go和backends.go,简单,易于阅读学习。
其中最主要的一个函数forward用于转发请求:

1
2
3
4
5
6
7
8
9
10
func forward (local net. Conn , remoteAddr string ) {
    remote , err := net. Dial ( "tcp" , remoteAddr )
    if err != nil {
        log. Printf ( "remote dial failed: %v\n" , err )
        local. Close ( )
        return
    }
    go io. Copy (local , remote )
    go io. Copy (remote , local )
}

io.Copy一句是精隨。
local和remote均是一个网络连接,类型为net.Conn,关于Conn接口的定,在Go官方源码中有:

1
2
3
4
5
6
7
8
9
10
type Conn interface {
        Read (b [ ]byte ) (n int , err error )
        Write (b [ ]byte ) (n int , err error )
        Close ( ) error
        LocalAddr ( ) Addr
        RemoteAddr ( ) Addr
        SetDeadline (t time. Time ) error
        SetReadDeadline (t time. Time ) error
        SetWriteDeadline (t time. Time ) error
    }

io.Copy(dst Writer, src Reader),则实现从src复制到dst。
io.Copy的实现代码有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
buf := make ( [ ]byte , 32 * 1024 )
    for {
        nr , er := src. Read (buf )
        if nr > 0 {
            nw , ew := dst. Write (buf [ 0 :nr ] )
            if nw > 0 {
                written += int64 (nw )
            }
            if ew != nil {
                err = ew
                break
            }
            if nr != nw {
                err = ErrShortWrite
                break
            }
        }
        if er == EOF {
            break
        }
        if er != nil {
            err = er
            break
        }
    }
    return written , err

可以看到调用了Read和Write方法,而这个方法刚好net.Conn中定义了。这就实现了将一个连接的数据复制到另一个连接。

你可能感兴趣的:(开源的反向代理项目推荐)