// Accept accepts connections on the listener and serves requests // for each incoming connection. func (server *Server) Accept(lis net.Listener) { for { conn, err := lis.Accept() if err != nil { log.Println("rpc server: accept error:", err) return } // 这里有问题:这里会不会不停创建 goroutine? go server.ServeConn(conn) } }
1 sunny352787 2024-02-21 10:56:08 +08:00 lis.Accept()是阻塞的 |
![]() | 2 dhb233 2024-02-21 11:00:03 +08:00 会创建啊,如果请求处理完了,goroutine 也会销毁 |
![]() | 3 lsk569937453 2024-02-21 11:02:50 +08:00 这个位置就是要不停的创建的 goroutine ,以保证后面的请求不会被未处理完的请求阻塞。 |
![]() | 4 Vegetable 2024-02-21 11:03:44 +08:00 当然是会不停创建的。 每个连接一个 goroutine ,数量取决于同时存在的连接数量。 |
![]() | 5 yifeia 2024-02-21 11:04:58 +08:00 ![]() accept 一个创建一个,只要 ServeConn 不阻塞,那 goroutine 执行完了就释放了,问题不大. |
6 Cola98 2024-02-21 11:14:15 +08:00 会不停创建,或者做一个简单的实验,你把这一段 for{ go xxx } 抽出来看下 |
7 hingle 2024-02-21 11:35:33 +08:00 在 go 上一行打印一下,就知道会不会了。 |
![]() | 8 guonaihong 2024-02-22 11:20:02 +08:00 因为 list.Accpet 只有新的连接过来,才会停止阻塞,所以这种写法的 go 程的个数等于连接 net.Conn 的个数。 另外聊个题外话,创建大量的 go 程,新版本 go 的 runtime 里面已经做了复用和优化。性能开销没有想象中那么大。 做过一个实验,使用 https://github.com/antlabs/quickws 这个 websocket 库,创建 100w 个 go 程,内存占用大约是 7.67GB 左右,8w tps 并发,50%的时延是 511.62ms -------------------------------------------------------------- BenchType : BenchEcho Framework : quickws TPS : 86326 EER : 413.65 Min : -1ns Avg : 573.50ms Max : 1.44s TP50 : 511.62ms TP75 : 705.19ms TP90 : 715.05ms TP95 : 718.11ms TP99 : 721.15ms Used : 49.70s Total : 5000000 Success : 4290729 Failed : 709271 Conns : 1000000 Concurrency: 50000 Payload : 1024 CPU Min : 120.52% CPU Avg : 208.70% CPU Max : 231.77% MEM Min : 7.67G MEM Avg : 7.67G MEM Max : 7.67G |
9 yc8332 2024-02-22 13:55:48 +08:00 本来就是不停创建啊。但是要上面执行了才会到下面啊,没连接创个啥 |