2012-02-03 6 views
2

나는 python 및 eventlet 메일 링리스트에 이미 게시 했으므로 참을성이 없어서 사과드립니다.Python은 eventlet을 실행하는 CPU의 99 %를 사용합니다.

작은 (마이크로가 아닌) 예약 된 우분투 11.10 aws 인스턴스에서 eventlet 0.9.16을 실행 중입니다.

eventlet 문서의 예제에서 echo 서버와 비슷한 소켓 서버가 있습니다. 코드를 처음 실행하면 모든 것이 잘된 것처럼 보이지만 10 시간이나 15 시간 후에 CPU 사용량이 약 1 %에서 99 %로 증가한다는 것을 알게되었습니다. 그 시점에서 소켓 서버에 더 이상 연결할 수 없습니다.

def socket_listener(self, port, socket_type): 
     L.LOGG(self._CONN, 0, H.func(), 'Action:Starting|SocketType:%s' % socket_type) 
     listener = eventlet.listen((self._host, port)) 
     listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     pool = eventlet.GreenPool(20000) 
     while True: 
      connection, address = listener.accept() 
      connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
      L.LOGG(self._CONN, 0, H.func(), 'IPAddress:%s|GreenthreadsFree:%s|GreenthreadsRunning:%s' % (str(address[0]), str(pool.free()),str(pool.running()))) 
      pool.spawn_n(self.spawn_socketobject, connection, address, socket_type) 
     listener.shutdown(socket.SHUT_RDWR) 
     listener.close() 

L.LOGG 방법은 단순히 MySQL의 테이블에 제공된 매개 변수를 기록

내가 실행하고 코드입니다. 내 초기 구글 검색에서

def listen_phones(self): 
    self.socket_listener(self._port_phone, 'phone') 

t_phones = Thread(target = self.listen_phones) 
t_phones.start() 

나는 문제가 https://lists.secondlife.com/pipermail/eventletdev/2008-October/000140.html에서보고 된 버그와 유사 할 거라고 생각하지만 난 그렇게 eventlet의 새 버전을 사용하고 있습니다 :

그래서 같은 스레드에 socket_listener를 실행하고 틀림없이 그럴 수는 없을까요?

+0

좋아, 물어볼 게. 'while True' 내에서 차단 작업이 실제로 차단되고 있습니까? 아마도 그것은 오류 상태 또는 일부 자원의 고갈로 인해 즉시 반환됩니다. – phs

+0

글쎄, 나는 오류 조건을 배제하지 않는다고 생각한다. 그러나 그것은 내가 연결할 수 없게되기 전에 클라이언트가 여러 번 성공적으로 연결될 것이라는 점을 감안할 때 거의 불가능합니다. 갑자기 100 %를 치기 전에이 시간 동안 CPU는 1 ~ 3 % 정도 유지됩니다. 이 서버에서 실행되는 다른 응용 프로그램의 방식이 거의 없으므로 리소스가 고갈 될 수 있는지 확실하지 않습니다. 아파치와 MySQL 인스턴스가 있지만 사실상 아무 일도하지 않습니다. 또한 소켓 관련 블로킹 문제 일 수도 있습니다. 그것은 혼란 스럽다. – tedtoy

+0

tedtoy, 마침내 문제를 발견 했습니까? 나는 eventlet과 비슷한 문제가있다 - http : // stackoverflow.com/questions/9124120/python-consumes-99-of-cpu-running-eventlet – Andrew

답변

2

listener.accept()이 비 블로킹 인 경우 스레드를 잠시 동안 잠자기 상태로 두어야 스케쥴러에서 작업을 다른 프로세스로 보낼 수 있습니다. 당신의 while True 루프의 끝에서

time.sleep(0.03) 

를 넣어이 작업을 수행합니다.

+0

신속하게 실행하고 싶기 때문에 루프를 지연시키는 아이디어가 마음에 들지 않지만, 나중에 도움이되고 업데이트됩니다. – tedtoy

+0

몇 밀리 초만 기다려주십시오. 이것은 CPU 부하가 높은 원인이기 때문에 endlees 루프를 실행할 때마다해야 할 일입니다. – Chris

1

답장을 보내 드려 죄송합니다.

listener.setblocking(0)과 같은 코드가 없으므로 차단으로 작동해야하며 절전 모드가 필요하지 않습니다.

또한 적어도 모든 CPU를 먹는 파이썬 프로세스인지 확인하려면 ps 또는 top과 같은 도구를 사용하십시오.

에 : 문제가 지속되면

, 당신이 좋아하는 중,이 채널 중 하나에 신고하시기 바랍니다