Golang 建立TCP时使用连接池
2019-06-09 本文已影响0人
FredricZhu
package main
import (
"fmt"
"io/ioutil"
"log"
"net"
"sync"
"testing"
"time"
)
func connectToService() interface{} {
time.Sleep(1 * time.Second)
return struct{}{}
}
func warmServiceConnCache() *sync.Pool {
p := &sync.Pool{
New: connectToService,
}
for i := 0; i < 10; i++ {
p.Put(p.New())
}
return p
}
func startNetworkDaemon() *sync.WaitGroup {
var wg sync.WaitGroup
wg.Add(1)
go func() {
connPool := warmServiceConnCache()
server, err := net.Listen("tcp", "localhost:8080")
if err != nil {
log.Fatalf("cannot listen: %v", err)
}
defer server.Close()
wg.Done()
for {
conn, err := server.Accept()
if err != nil {
log.Printf("cannot accept connection: %v", err)
continue
}
svcConn := connPool.Get()
fmt.Fprintln(conn, "")
connPool.Put(svcConn)
conn.Close()
}
}()
return &wg
}
func init() {
daemonStarted := startNetworkDaemon()
daemonStarted.Wait()
}
func BenchmarkNetworkRequest(b *testing.B) {
for i := 0; i < b.N; i++ {
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
b.Fatalf("cannot dial host: %v", err)
}
if _, err := ioutil.ReadAll(conn); err != nil {
b.Fatalf("cannot read :%v", err)
}
conn.Close()
}
}
程序输出如下,相比不用连接池,单次操作时间少了一个数量级。
image.png