0

I have read the post

My service code like the following:

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
}

And my client code like the following using Python, the InteractByKey of service is visited by client and one request at a time:

#!/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])

Machine A run my service program(Go language), and machine B run my client program(Python language).

When I send request by client program to service, my fd of service(Go) machine will always add, like this:

$ 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

When the number reach about 8000, sendRequest will timeout, it can not run or restart my service program.

So, how should I rewrite my code?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
thinkerou
  • 1,781
  • 5
  • 17
  • 28

0 Answers0