FD泄漏,我应该如何重构代码?

时间:2017-08-23 13:36:43

标签: http go

我已阅读post

我的服务代码如下:

type httpResponse struct {
    StatusCode int
    Header     http.Header
    Body       []byte
}

var client *http.Client

func init() {
    client = &http.Client{
        Transport: &http.Transport{
            Proxy: http.ProxyFromEnvironment,
            DialContext: (&net.Dialer{
                Timeout:   30 * time.Second,
                KeepAlive: 30 * time.Second,
            }).DialContext,
            MaxIdleConns:          100,
            MaxIdleConnsPerHost:   100,
            IdleConnTimeout:       90 * time.Second,
            TLSHandshakeTimeout:   10 * time.Second,
            ExpectContinueTimeout: 3 * time.Second,
        },
    }
}

func sendRequest(url string) (httpResponse, error) {
    var res httpResponse
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return res, err
    }
    resp, err := client.Do(req)
    if resp != nil {
        res.StatusCode = resp.StatusCode
        res.Header = resp.Header
    }
    if err != nil {
        return res, err
    }
    defer resp.Body.Close()
    res.Body, err = ioutil.ReadAll(resp.Body)
    if err != nil {
        return res, err
    }
    return res, nil
}

func InteractByKey(key string) (Info, error) {
    host := "http://test.baidu.com"
    url := fmt.Sprintf("%s/test/2.0/info?method=select&key=%s", host, key)

    for intRetry := 0; intRetry < 3; intRetry++ {
        resp, err := sendRequest(url)
        if err != nil {
            continue
        }
        if resp.StatusCode >= 500 {
            continue
        }
        if resp.StatusCode >= 400 && resp.StatusCode < 500 {
            continue
        }
        arrRes, err := unpackInfo(resp.Body)
        return arrRes[0], err
    }
    return Info{}, &ErrGetInfoFailed
}

我的客户端代码如下所示使用Python,客户端访问InteractByKey服务,一次访问一个请求:

#!/usr/bin python
#coding=utf-8

import requests

# address is the ip of machine A
url = "http://10.95.35.14:8099/test/2.0/check?method=InteractByKey&key="


def _send_request(url):
    session = requests.Session()
    session.keep_alive = False

    resp = None
    try:
        resp = session.get(url)
    except:
        if resp is not None:
            resp.connection.close()
            return (False, url)
    if resp is None or resp.status_code != 200:
        if resp is not None:
            resp.connection.close()
        return (False, url)
    try:
        data = resp.json()
    except:
        if resp is not None:
            resp.connection.close()
            return (False, url)
    if resp is not None:
        resp.connection.close()
    try:
        if data['result'][0]['mark_result']['success'] is False:
            return (False, data)
    except:
        return (False, url)
    return (True, data)

with open('test.txt') as f:
    for line in f:
        key = line.strip()
        urls = url + key
        res = _send_request(urls)
        if res[0] is True:
            print "OK " + key + " " + str(res[1])
        else:
            print "Error " + key + " " + str(res[1])

机器A运行我的服务程序(Go语言),机器B运行我的客户端程序(Python语言)。

当我通过客户端程序向服务发送请求时,我的fd服务(Go)机器将始终添加,如下所示:

$ lsof -p 18464 | wc -l
182
$ lsof -p 18464 | wc -l
199
$ lsof -p 18464 | wc -l
876
$ lsof -p 18464 | wc -l
1580
$ lsof -p 18464 | wc -l
2107
$ lsof -p 18464 | wc -l
2709
$ lsof -p 18464 | wc -l
2910

当数量达到约8000时,sendRequest将超时,无法运行或重新启动我的服务程序。

那么,我应该如何重写我的代码?

0 个答案:

没有答案