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

write package goroutine pool #62

Open
AlexStocks opened this issue Jun 27, 2021 · 1 comment
Open

write package goroutine pool #62

AlexStocks opened this issue Jun 27, 2021 · 1 comment

Comments

@AlexStocks
Copy link

经过半年的改进,目前关闭 handleLoop 的改进已经接近尾声,目前针对一个网络连接已经能够做到:
1 只有一个 read goroutine 专门处理读请求;
2 在业务处理逻辑的 goroutine 中同步处理写请求。

这个处理方法能否大幅度减少网络连接相关的 goroutine 的数量,在处理小包[<100k] 的情况下,基本上每次写请求发送都能成功,但是在处理网络打包[>= 8MiB] 的情况下,还是有很大概率会失败,其本质是 tcp/udp 的发送缓冲区有限,对待大包需要循环多次尝试发送。所以下一步的工作,个人觉得是不是可以专门启动一个处理写请求的 goroutine pool,其大小有限如 16,每个 goroutine 有一个请求队列【每个队列称为 wQ,16 个 wQ 就是一个 wQArray】,则写请求处理步骤就变成了:

1 业务方调用 session.WritePkg(pkg, timeout) 发送;
2 session.WritePkg(pkg, timeout) 先调用 pkg.Write() 接口把 pkg 序列化成字节流后,把 session.fd 和 字节流包装成一个 struct【暂称为 type sessionPkg struct { s []byte, fd int, timeout time.Duration, ackQ struct{} }】,然后放入一个 wQ【wQ = wQArray[session.fd % 16],取模运算可以保证每个 fd 网络请求都交给同一个 goroutine,保证发送顺序性】,然后以 select{ case <- time.After(@timeout); case a := <- sessionPkg.ackQ} 方式同步等待;
3 每个发送 goroutine 不断从 wQ 内取出 sessionPkg,然后循环发送;
发送方式可能为最多发送 10 次,每次时间间隔是 sessionPkg.timeout / 10。中间任何一次发送成功就返回,10 次发送失败就返回发送失败,不要影响 wQ 中后续 sessionPkg 的处理。

@AlexStocks AlexStocks changed the title 启用一个专门处理写请求的 goroutine pool write package goroutine pool Jun 27, 2021
@AlexStocks
Copy link
Author

如果启用这个 feature,则 write package goroutine pool 可以考虑使用 https://github.com/dubbogo/gost/blob/fd9b88f342a2fe712a4daca02a1db1afba6e3c2a/sync/task_pool.go#L60

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

No branches or pull requests

1 participant