golang-server-epoll-client-使用连接池-15万-qps

12次阅读

共计 1552 个字符,预计需要花费 4 分钟才能阅读完成。

epoll 加连接池

前几天看了 epoll 使用,今天写了一个测试脚本,测试一下 epoll 加连接池,性能

50 万个请求,连接池使用 2000 连接,发送 “test” 服务端接受后 转成大写返回,处理完所有的请求耗时 3.731506996s,性能很强大
github 上有详细代码,epollServer.go 是服务端代码,testPool.go 是 client 端代码
地址:https://github.com/shanlongpa…

  • client 仿照 redis 的连接池,写了一个连接池

       pool := &pools.Pool{
           MaxIdle:     100,
           MaxActive:   2000,
           IdleTimeout: 20 * time.Second,
           MaxConnLifetime: 100 * time.Second,
           Dial: func() (net.Conn, error) {//c, err := redis.Dial("tcp", "127.0.0.1:6379")
               c, err := net.Dial("tcp", "127.0.0.1:8972")
               if err != nil {return nil, err}
               return c, err
           },
       }
       defer pool.Close()
    
       t := time.Now()
    
       worklist := make(chan int)
       var wg sync.WaitGroup
       for i := 0; i < 2000; i++ {go func() {
               for range worklist {wg.Done()
                   cli,err:=pool.Get()
                   if err!=nil{log.Println(err)
                       return
                   }
    
                   str:="test"
    
                   err=pools.Write(cli.C,[]byte(str))
    
                   if err!=nil{log.Println(err)
                       pool.Put(cli,true)
                       return
                   }
                   _,err=pools.Read(cli.C)
                   if err!=nil{log.Println(err)
                   }else{
                       //if i%500==0{//    fmt.Println(string(receByte))
                       //}
                   }
                   pool.Put(cli,false)
               }
           }()}
    
       for i := 0; i < 500000; i++ {wg.Add(1)
           worklist <- i
       }
    
       fmt.Println("pool 建立,连接数:",pool.Active)
    
       close(worklist)
       wg.Wait()
       // 调用服务
       fmt.Println(time.Since(t))
  • server 使用 epoll

       ln, err := net.Listen("tcp", "127.0.0.1:8972")
       if err != nil {panic(err)
       }
       epoller, err = MkEpoll()
       if err != nil {panic(err)
       }
    
       go start()
    
       for {conn, e := ln.Accept()
           if e != nil {if ne, ok := e.(net.Error); ok && ne.Temporary() {log.Printf("accept temp err: %v", ne)
                   continue
               }
    
               log.Printf("accept err: %v", e)
               return
           }
    
           if err := epoller.Add(conn); err != nil {log.Printf("failed to add connection %v", err)
               conn.Close()}
       }
       
       
       // 返回接受的信息,小写转成大写字母
    func replyConn(c net.Conn) error {data,err:= pools.Read(c)
       if err!=nil{return err}
       err= pools.Write(c,[]byte(strings.ToUpper(string(data))))
       return err
    }

正文完
 0