用go实现了一个数据库访问的代理,即客户端发数据到proxy proxy转发至后端数据库并将数据返回给客户端,项目使用的go net包; pprof分析cpu耗时,发现syscall (28%)和epollwait(50%)占比相当高,syscall主要是net的read和write耗时,已经优化合并了部分读写操作,epollwait高的吓人,请大神帮助分析下,感激不尽
有疑问加站长微信联系(非本文作者)

用go实现了一个数据库访问的代理,即客户端发数据到proxy proxy转发至后端数据库并将数据返回给客户端,项目使用的go net包; pprof分析cpu耗时,发现syscall (28%)和epollwait(50%)占比相当高,syscall主要是net的read和write耗时,已经优化合并了部分读写操作,epollwait高的吓人,请大神帮助分析下,感激不尽
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
`单行代码`
mark
程序是实现了一个数据库代理服务:
客户端 <---> 代理服务 <--> 数据库
代码逻辑大概如下: // 建立监听 s.listener, err = net.Listen(netProto, s.addr)
//循环accept for s.running { conn, err := s.listener.Accept() if err != nil { ... continue }
// func (s *Server) onConn(c net.Conn, dbType string) { ... // 循环监听读connection消息 for { // 使用 io.ReadFull读消息;RB是 bufio.Reader; 若没消息程序会停在这里,我理解这就是epoll的挂起 并不消耗cpu header := make([]byte, 5) if _, err := io.ReadFull(cc.pkg.Rb, header); err != nil { return nil, nil, err }
... }
程序是实现了一个数据库代理服务:
客户端 <---> 代理服务 <--> 数据库
代码逻辑大概如下:
被你写成了对讲机式的半双工通信😂
请明示啊
又做了测试, 数据链路 client --> proxy,然后proxy mock数据返回client,QPS能达到近110W; 然后增加一个 proxy到数据库的写(读还没增加),其他不变,QPS下降近一半 只有50多W;
nginx转发效率就很高,按道理数据链路应该差不多,怎么做到损耗这么小的?
//for循环监听数据库端返回消息 for { header := make([]byte, 5) data, err = io.ReadFull(cc.backendConn.Conn.pkg.Rb, header ) // 处理消息 ..... //写消息到客户端 c.pkg.Wb.Write(data) } // 回收数据库连接到资源池 c.closeConn(c.backendConn, false) }
这个代码需要起一个协程。。。