Skip to content

write package goroutine pool #62

Description

@AlexStocks

经过半年的改进,目前关闭 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 的处理。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions