Skip to content

Instantly share code, notes, and snippets.

@tevino
Created November 30, 2015 02:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tevino/e8457ce41c0c7416183f to your computer and use it in GitHub Desktop.
Save tevino/e8457ce41c0c7416183f to your computer and use it in GitHub Desktop.
test of io.Copy
package main
import (
"fmt"
"io"
"net"
)
var addrSrv, _ = net.ResolveTCPAddr("tcp", "localhost:2000")
var addrClt, _ = net.ResolveTCPAddr("tcp", "localhost:2001")
func forward(conn *net.TCPConn) {
c, err := net.DialTCP("tcp", nil, addrClt)
if err != nil {
conn.Close()
fmt.Printf("dial: %v\n", err)
return
}
defer c.Close()
defer conn.Close()
go io.Copy(c, conn)
io.Copy(conn, c)
}
func main() {
l, err := net.ListenTCP("tcp", addrSrv)
if err != nil {
fmt.Println(err)
return
}
println("now")
for {
conn, err := l.AcceptTCP()
if err != nil {
fmt.Printf("accept: %v\n", err)
return
}
go forward(conn)
}
}
@astaxie
Copy link

astaxie commented Dec 2, 2015

我改成下面代码了,相比这个的性能稍微提升,但是pprof看,CPU还是占用在同一个地方:

这个是第一个代码:

astaxie@ubuntu:~/go/src/test$ wrk -c10k -d2m http://localhost:2000
Running 2m test @ http://localhost:2000
  2 threads and 10000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   151.11ms  209.35ms   2.00s    93.30%
    Req/Sec    14.53k     4.31k   26.87k    69.06%
  3466524 requests in 2.00m, 2.77GB read
  Socket errors: connect 0, read 263259, write 0, timeout 30350
Requests/sec:  28863.13
Transfer/sec:     23.62MB

这个是下面的代码的结果:

astaxie@ubuntu:~/go/src/test$ wrk -c10k -d2m http://localhost:2000
Running 2m test @ http://localhost:2000
  2 threads and 10000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   149.80ms  214.56ms   2.00s    93.11%
    Req/Sec    15.08k     4.70k   37.20k    72.56%
  3596694 requests in 2.00m, 2.87GB read
  Socket errors: connect 0, read 263205, write 0, timeout 27821
Requests/sec:  29956.95
Transfer/sec:     24.51MB
package main

import (
    "fmt"
    "io"
    "net"
    "sync"
       "github.com/davecheney/profile"
)

var addrSrv, _ = net.ResolveTCPAddr("tcp", "localhost:2000")
var addrClt, _ = net.ResolveTCPAddr("tcp", "localhost:2002")

func forward(conn *net.TCPConn) {
    c, err := net.DialTCP("tcp", nil, addrClt)
    if err != nil {
        conn.Close()
        fmt.Printf("dial: %v\n", err)
        return
    }
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        io.Copy(c, conn)
                c.Close()
        wg.Done()
    }()
    wg.Add(1)
    go func() {
        io.Copy(conn, c)
        conn.Close()
        wg.Done()
    }()
    wg.Wait()
}

func main() {
        defer profile.Start(profile.CPUProfile).Stop()
    l, err := net.ListenTCP("tcp", addrSrv)
    if err != nil {
        fmt.Println(err)
        return
    }
    println("now")
    for {
        conn, err := l.AcceptTCP()
        if err != nil {
            fmt.Printf("accept: %v\n", err)
            return
        }
        go forward(conn)
    }
}

@tevino
Copy link
Author

tevino commented Dec 3, 2015

😄 线上代码也差不多,大概是这样:

serverClosed := make(chan, bool)
go forward(cltConn, srvConn, nil)
go forward(srvConn, cltConn, serverClosed)  // 最后会 close(serverClosed)
go func(){
    <-serverClosed
    srvConnCounter--
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment