私はrabbitmqからメッセージを受け取り、geventを使用してグリーンレットを生成して作業したいと思います。私のコードは:
import pika
import gevent.monkey
gevent.monkey.patch_all()
import gevent
from gevent.pool import Pool
from gevent import Timeout
from meliae import scanner
import MySQLdb
import urllib2
from MySQLdb.cursors import SSCursor
db=MySQLdb.connect(host='125.221.225.12',user='root',passwd='young001',charset='utf8',db='delicious',use_unicode=True)
cur = db.cursor()
p = Pool(300)
success_count = 0
fail_count = 0
connection = pika.BlockingConnection(pika.ConnectionParameters(host='125.221.225.12'))
channel = connection.channel()
channel.queue_declare(queue='url_queue')
#logfile = file("log.txt",'aw',buffering=0)
def insert_into_avail(url):
cur.execute("insert into avail_urls(url) values (%s)",url)
db.commit()
def insert_into_fail(url):
cur.execute("insert into fail_urls(url) values (%s)",url)
db.commit()
class TooLong(Exception):
pass
def down(url):
global success_count
global fail_count
print 'the free pool is', p.free_count()
try:
with Timeout(30,TooLong):
url_data = urllib2.urlopen(url)
if url_data and url_data.getcode() ==200:
#print 'url is ok'
insert_into_avail(url)
success_count = success_count+1
else:
print 'the code is ',url_data.getcode()
#logfile.write(url)
#print 'the pool is ', len(p)
print 'success count is', success_count
except:
insert_into_fail(url)
fail_count = fail_count+1
#print 'the url is down',url
#print 'the pool is ', len(p)
print 'the fail_count is', fail_count
for method,properties,body in channel.consume('url_queue'):
#print 'body is ',body
channel.basic_ack(method.delivery_tag)
scanner.dump_all_objects("dump.txt")
p.spawn(down,body)
#scanner.dump_all_objects("dump.txt")
#print 'the pool is ', len(p)
#logfile.write
p.join()
それは非常に遅く動作します、いくつかの出力は次のとおりです:
the fail_count is 30
the free pool is 295
the fail_count is 31
the free pool is 295
the fail_count is 32
the free pool is 295
the fail_count is 33
the free pool is 295
the fail_count is 34
the free pool is 295
the fail_count is 35
the free pool is 295
プールには約5個のグリーンレットしかありません。プールに300個のグリーンレットを入れたいので、プログラムは高速に実行されます。どうしたの?それをデバッグする方法は?rabbitmq、gevent、または私のコードのためですか?どうも
*更新: *「scanner.dump_all_objects( "dump.txt")」とコメントすると、フルプールで実行されます。オブジェクトをファイルに書き込むと時間がかかるため、rabbitmqからのメッセージの取得に非常に時間がかかります。
しかし、私のコードでは、メモリリークの問題があるようです。プログラムは数百Mのメモリを使用するので、すべてのオブジェクトを印刷してメモリリークの問題を見つけたいですか?それを修正する方法は?もっと良い方法はありますか?