2012-05-16 5 views
2

저는 유료 타사 API의 실시간 데이터를 가져 오는 Python 백엔드 웹 서버에서 작업하고 있습니다. 이 API를 매우 빠르게 쿼리해야합니다 (약 10 초당 약 150 개의 쿼리). 따라서 나는 200 개의 스레드를 생성하고 대기열에 URL을 쓰는 개념 증명을 만들었습니다. 그런 다음 스레드는 큐에서 URL을 읽고 HTTP 요청을 전송합니다. 타사 API는 지연이라는 값을 반환합니다.이 값은 서버가 요청을 처리하는 데 걸린 시간입니다. 다음은 모든 URL을 다운로드하는 POC 코드입니다 (반복하지는 않음). 파이썬 멀티 스레딩 및 HTTP 요청

_http_pool = urllib3.PoolManager() 

def getPooledResponse(url): 
    return _http_pool.request("GET", url, timeout=30) 

class POC: 
    _worker_threads = [] 
    WORKER_THREAD_COUNT = 200 
    q = Queue.Queue() 

    @staticmethod 
    def worker(): 
     while True: 
      url = POC.q.get() 
      t0 = datetime.datetime.now() 
      r = getPooledResponse(item) 
      print "thread %s took %d seconds to process the url (service delay %d)" % (threading.currentThread().ident, (datetime.datetime.now() - t0).seconds, getDelayFromResponse(r)) 
      POC.q.task_done() 

    @staticmethod 
    def run(): 
      # start the threads if we have less than the desired amount 
      if len(POC._worker_threads) < POC.WORKER_THREAD_COUNT: 
       for i in range(POC.WORKER_THREAD_COUNT - len(POC._worker_threads)): 
        t = threading.Thread(target=POC.worker) 
        t.daemon = True 
        t.start() 
        POC._worker_threads.append(t) 

      # put the urls in the queue 
      for url in urls: 
       POC.q.put(url) 
       # sleep for just a bit so that the requests don't get sent out together (this is a limitation of the API I am using) 
       time.sleep(0.3) 
POC.run() 

나는이 실행

는 처음 몇 결과는 합리적인 지연 반환됩니다

thread 140544300453053 took 2 seconds to process the url (service delay 1.782) 

그러나, 10 ~ 20 초 후에 내가 할 일 이러한 종류의 :

thread 140548049958656 took 23 seconds to process the url (service delay 1.754) 

즉, 서버가 약간의 지연으로 돌아 오더라도 내 스레드가 완료하는 데 더 오래 걸립니다 ...

다른 21 초를 소비 한 곳을 테스트하려면 어떻게해야합니까?

감사합니다.

+2

[여러 스레드와 관련된 Python GIL 문제를 확인 했습니까?] (http://wiki.python.org/moin/GlobalInterpreterLock) –

+0

감사합니다. 내가 여기서 정확히해야 할 일은 무엇일까요? 이 문제를 피할 수있는 방법이 있습니까? – user1094786

+0

글쎄, 내가 알리가 추천 한 코드를위한 프로파일 러를 얻는 것이 분명 할 것이다. 이 경우 GIL 문제에 빠져들 수도 있지만,이 경우 GIL은 모든 스레드가 본질적으로 연속적으로 실행되도록하므로 GIL이 속도 저하의 원인이 될 수 있습니다. GIL 문제를 해결하려면 스레드가 아닌 별도의 프로세스를 사용해야합니다. 또는 코드를 threadsafe하게 만드는 방법을 찾으십시오. 그러나 나는 올바른 방향으로 여러분을 안내하기 위해 멀티 스레드/파이썬 코딩을 코딩 할만큼 유창하지 않습니다. –

답변

0

코드에 profiler을 사용해야합니다.