Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SendToQueue这个方式的发送是否没有起到缓冲作用? #357

Open
EquentR opened this issue Dec 22, 2024 · 5 comments · May be fixed by #358
Open

SendToQueue这个方式的发送是否没有起到缓冲作用? #357

EquentR opened this issue Dec 22, 2024 · 5 comments · May be fixed by #358

Comments

@EquentR
Copy link

EquentR commented Dec 22, 2024

大佬们好,请教一个问题
在connection对象中,用来缓冲队列发送的Writer最终调用的还是阻塞的Send方法,这个方法直接调用底层的TCP连接,如果发送的数据包不大,而且发送较为频繁的话(例如一秒几万个数据包,且每个数据包大小可能远达不到1kib),那么频繁地进行系统调用,在内核态和用户态切换会造成大量的时间消耗,且无法充分利用带宽。通过pprof/profile分析结果也确实如此,大量时间消耗在tcp.Write中,这里是否可以给TcpConn连接加入bufio+锁+定时器flush的方式来增加带宽利用率?

// StartWriter is the goroutine that writes messages to the client
// (写消息Goroutine, 用户将数据发送给客户端)
func (c *Connection) StartWriter() {
	zlog.Ins().InfoF("Writer Goroutine is running")
	defer zlog.Ins().InfoF("%s [conn Writer exit!]", c.RemoteAddr().String())

	for {
		select {
		case data, ok := <-c.msgBuffChan:
			if ok {
                                // !!!!此处
				if err := c.Send(data); err != nil {
					zlog.Ins().ErrorF("Send Buff Data error:, %s Conn Writer exit", err)
					break
				}

			} else {
				zlog.Ins().ErrorF("msgBuffChan is Closed")
				break
			}
		case <-c.ctx.Done():
			return
		}
	}
}

附:pprof
5c4fa81c6ed7e840cbe9e9cd6f7d700
3c670d8101211afd983bf04caf31f55
79c2e3da11cb8524945a2269e26e52d
a5820f9ccb5dd111bcd4e7ddb5d0f0e

@YanHeDoki
Copy link
Collaborator

理论上这里确实可以先收集一批次的 buf 里面的 msg 然后一次性写入的但是我记得是因为什么问题改成了现在这样

@YanHeDoki
Copy link
Collaborator

好像是直接用 Tcpconn 写入的话会出现连接已经关闭但是 sendbuf 中还存在消息的情况

@EquentR
Copy link
Author

EquentR commented Dec 22, 2024

但是不管哪种方式好像都会导致连接关闭了,send buf chan还有消息啊,缓冲发送似乎无法避免这个问题,毕竟连接确实被关掉了,然后就只能重连,那么产生新的连接对象后,原本的chan也需要额外的手段继承过来😂。感觉还是直接使用bufio累计到一定数量自动发送或定时器超时后将bufio flush一下比较合理

@YanHeDoki
Copy link
Collaborator

但是不管哪种方式好像都会导致连接关闭了,send buf chan还有消息啊,缓冲发送似乎无法避免这个问题,毕竟连接确实被关掉了,然后就只能重连,那么产生新的连接对象后,原本的chan也需要额外的手段继承过来😂。感觉还是直接使用bufio累计到一定数量自动发送或定时器超时后将bufio flush一下比较合理

可以提个 pr 看一下,理论上这里是确实可以优化的

@EquentR
Copy link
Author

EquentR commented Dec 22, 2024

好,我试着改一下

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants