Когда уровень параллелизма повышается до 10000, я получаю тайм-аут массового диалога tcp.
$ go version
go версия go1.12.1 linux / amd64
$ go env
GOARCH="amd64"
GOBIN="/home/zhoudazhuang/gobin/"
GOCACHE="/home/zhoudazhuang/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/zhoudazhuang/db11/jm/pro"
GOPROXY=""
GORACE=""
GOROOT="/home/zhoudazhuang/usr/local/go1.12.1/go"
GOTMPDIR=""
GOTOOLDIR="/home/zhoudazhuang/usr/local/go1.12.1/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build631445118=/tmp/go-build -gno-record-gcc-switches"
Что я сделал?
Мой проверенный код:
Сервер:
func main() {
l, err := net.Listen("tcp", ":8888")
if err != nil {
log.Println("listen error:", err)
return
}
for {
c, err := l.Accept()
if err != nil {
log.Println("accept error:", err)
break
}
go c.Close()
// start a new goroutine to handle
// the new connection.
//log.Println("accept a new connection")
//go handleConn(c)
}
}
Клиент:
package main
import (
"fmt"
"github.com/jessevdk/go-flags"
"net"
"os"
"sync"
"time"
)
var args struct {
Addr string `short:"a" required:"yes" description:"服务端地址"`
Concurrence int `short:"c" required:"yes" description:"并发请求数"`
Count int `short:"t" required:"yes" description:"测试次数"`
}
func main() {
argParser := flags.NewNamedParser("tcp_test", flags.PassDoubleDash)
argParser.AddGroup("Mock parameters", "", &args)
_, err := argParser.Parse()
if err != nil {
fmt.Println(err)
argParser.WriteHelp(os.Stdout)
os.Exit(1)
}
fmt.Printf("测试参数: %+v\n",args)
wg := sync.WaitGroup{}
for j:=0; j<args.Count;j++ {
for i:=0; i<args.Concurrence;i++{
wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(time.Second*5)
conn, err := net.DialTimeout("tcp", args.Addr, time.Second*3)
if err != nil {
fmt.Printf("dialog err: %+v i为%d:\n",err,j)
return
}
time.Sleep(time.Millisecond*10)
conn.Close()
}()
}
}
fmt.Println("start wait")
wg.Wait()
fmt.Println("ok")
}
cmd: ./Test -a 127.0.0.1:8888 -c 10000 -t 3
╰─> # cat / proc / sys / net / ipv4 / ip_local_port_range
4096 65535
╰─> # ulimit -a
размер файла ядра (блоки, -c) 0
размер сегмента данных (в килобайтах, -d) неограничен
приоритет планирования (-e) 0
размер файла (блоков, -f) неограничен
ожидающие сигналы (-i) 386849
Максимальная заблокированная память (кбайт, -l) 64
максимальный объем памяти (в килобайтах, -m) неограничен
открыть файлы (-n) 10000000
размер трубы (512 байт, -p) 8
Очереди сообщений POSIX (байты, -q) 819200
приоритет в реальном времени (-r) 0
размер стека (кбайт, -s) 10240
время процессора (секунды, -t) не ограничено
максимальное количество пользовательских процессов (-u) 1000000
виртуальная память (кбайт, -v) неограниченно
блокировки файлов (-x) неограниченно
Что вы ожидали увидеть?
нет времени ожидания набора tcp.
Что вы видели вместо этого?
диалоговое окно err: dial tcp 127.0.0.1:8888: тайм-аут ввода-вывода i 为 3:
ошибка диалога: наберите tcp 127.0.0.1:8888: время ожидания ввода-вывода i i 3:
ошибка диалога: наберите tcp 127.0.0.1:8888: время ожидания ввода-вывода i 为 3:
ошибка диалога: наберите tcp 127.0.0.1:8888: время ожидания ввода-вывода i i 3:
Ref Issue:
вопрос