2016-08-17 3 views
1

API 끝점에 100K-300K POST 요청을 보내려합니다. 이러한 요청은 반복되는 JSON 개체 목록에서 비롯됩니다. 불행히도 내가 사용할 수있는 최대 청크 크기는 한 번에 10 개의 이벤트로, 원하는 모든 이벤트를 보내는 속도가 크게 줄어들고 있습니다. JSON 객체 목록을 정의한 후 :HTTP 요청 동시 전송

chunkSize= 10 
for i in xrange(0, len(list_of_JSON), chunkSize): 
    chunk = list_of_JSON[i:i+chunkSize] #10 
    endpoint = "" 
    d_profile = "[" + ",".join(json.dumps(x) for x in chunk) + "]" 
    str_event = d_profile 
    try: 
     url = base_api + endpoint + "?api_key=" + api_key + "&event=" + str_event 
     r = requests.post(url) 
     print r.content 
     print i 
    except: 
     print 'failed' 

이 프로세스는 매우 느리게 동작하여 이벤트를 전송합니다. 필자는 완전히 새로운 주제이지만 멀티 스레딩/동시성/병렬 처리의 가능성을 찾았습니다. 몇 가지 조사 후, 나는이 추한 SNIPPIT을 마련했습니다

import logging 
import threading 
import time 

logging.basicConfig(level=logging.DEBUG, 
       format='[%(levelname)s] (%(threadName)-10s) %(message)s', 
       ) 

def worker(): 
    logging.debug('Starting') 
    import time 
    chunkSize= 10 
    for i in xrange(0, (len(list_of_JSON)/2), chunkSize): 
     chunk = list_of_JSON[i:i+chunkSize] #10 
     endpoint = "" 
     d = "[" + ",".join(json.dumps(x) for x in chunk) + "]" 
     str_event = d 
     try: 
      url = base_api + endpoint + "?api_key=" + api_key + "&event=" + str_event 
      r = requests.post(url) 
      print r.content 
      print i 
     except: 
      print 'failed' 
    time.sleep(2) 
    logging.debug('Exiting') 

def my_service(): 
    logging.debug('Starting') 
    import time 
    chunkSize= 10 
    for i in xrange(((len(list_of_JSON)/2)+1), len(list_of_JSON), chunkSize): 
     chunk = list_of_JSON[i:i+chunkSize] #10 
     endpoint = "" 
     d = "[" + ",".join(json.dumps(x) for x in chunk) + "]" 
     str_event = d 
     try: 
      url = base_api + endpoint + "?api_key=" + api_key + "&event=" + str_event 
      r = requests.post(url) 
      print r.content 
      print i 
     except: 
      print 'failed' 
    time.sleep(3) 
    logging.debug('Exiting') 

t = threading.Thread(target=my_service) 
w = threading.Thread(target=worker) 


w.start() 
t.start() 

이 어떤 제안이나 리팩토링을 감사하겠습니다.

편집 : 내 구현이 내가 원하는 것을 성취한다고 생각합니다. 나는 What is the fastest way to send 100,000 HTTP requests in Python?을 살펴 봤지만이 솔루션이 얼마나 pythonic 또는 efficient인지는 여전히 확신 할 수 없습니다.

+0

의 사용 가능한 복제 [? 무엇 파이썬에서 10 만 개 HTTP 요청을 보낼 수있는 가장 빠른 방법입니다 (http://stackoverflow.com/questions/2632520/what-is- -est-send-100-000-http-requests-in-python) – Wajahat

+1

이것은 꽤 오래되었지만 [이벤트 릿] (https://github.com/eventlet/eventlet)을 살펴볼 것을 제안합니다.). 설명서에는 사용자가 요구하는 것과 정확히 일치하는 기본 예제가 있습니다. – Thtu

+0

eventlet 체크 아웃, – astateofsanj

답변

-1

꼬인 (의견에 제안 된대로) 것을 사용하는 치료법을 사용할 수 있습니다. Scrapy는 웹 페이지 스크랩을위한 프레임 워크이지만, 이것을 사용하여 post 요청을 보낼 수도 있습니다. 코드는 다음과 같이 다소 보일 것 같은를 달성 거미 : 거미가 제자리에 일단

class EventUploader(scrapy.Spider): 
    BASE_URL = 'http://stackoverflow.com/' # Example url 

    def start_requests(self): 
     for chunk in list_of_JSON: 
      get_parameters = { 
       'api_key': api_key, 
       'event': json.dumps(chunk), # json.dumps can encode lists too 
      } 

      url = "{}/endpoint?{}".format(
       self.BASE_URL, urlencode(get_parameters)) 
      yield scrapy.FormRequest(url, formdata={}, callback=self.next) 

    def next(self, response): 
     # here you can assert everything went ok 
     pass 

, 당신이 당신의 요청을 제한하는 scrapy 미들웨어를 사용할 수 있습니다. 이처럼 업 로더를 실행하는 것 :

scrapy runspider my_spider.py