golang too many open files

钱tao · · 932 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

背景:

需要做一个小文件下载工具,需要做到并发,使用了beego的httplib作为http资源的下载工具,
在服务器上没什么问题(有问题没暴露),但是在本地机器上出现too many open files

查因

这是一个unix上一个比较常见的错误,问题是怎么出现的呢,明明已经限制的协程的数量。怎么会出现过多的socket连接导致文件数超限。

  1. 通过获取进程打开文件数 明显看到socket的数量明显多于预期。什么原因导致没有关闭连接
  2. 检查代码发现自己也是简单的用了httplib.Get函数然后使用ToFile写入文件,response也已经关闭,理论上不应该出现问题。

继续查因

  1. 打印协程数发现协程数明显增加,已知http读写会开启协程,那么明显是tcp链接问题。
  2. 检查httplib代码
func Get(url string) *BeegoHTTPRequest {
    return NewBeegoRequest(url, "GET")
}

发现每次每次都新建一个Request,然后因为没有设置Transport,每一次都设置了一个Transport导致每次都新建一个链接。
为了解决这个问题修改代码如下:

func downOneFile(ctx context.Context, dstDir string, jobChannel chan Entry, index int) {
    tp := &http.Transport{
        DialContext: (&net.Dialer{
            Timeout:   30 * time.Second,
            KeepAlive: 30 * time.Second,
            DualStack: true,
        }).DialContext,
        MaxIdleConns:          100,
        IdleConnTimeout:       90 * time.Second,
        ExpectContinueTimeout: 1 * time.Second,
    }
    
    for {
        select {
        case v, ok := <-jobChannel:
            if ok {
                atomic.AddInt64(&jobCount, 1)
                logs.Debug("NumGoroutine:", index, runtime.NumGoroutine(), jobCount)
                rawUrl := BaseUrl + v.FullPath
                req := httplib.NewBeegoRequest(rawUrl, "GET")
                req.SetTransport(tp) // 复用同一个transport
                err := req.ToFile(filepath.Join(dstDir, v.SavePath))
                if err != nil {
                    logs.Error(`save %v fail:%v`, v.FullPath, err)
                } else {
                    logs.Debug(v.FullPath, `save to`, filepath.Join(dstDir, v.SavePath))
                }
                atomic.AddInt64(&downloadCount, 1)
                atomic.AddInt64(&jobCount, -1)
                wg.Done() //下载结束
            } else {
                return
            }
        case <-ctx.Done():
            return
        }
    }
}

修改完成,再次测试发现一切正常,终于解决问题了。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:钱tao

查看原文:golang too many open files

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

932 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传