2011-02-03 91 views
4

我有一個python腳本,設置了幾個gearman worker。他們調用SQLAlchemy模型中的一些方法,我也使用了Pylons應用程序。Gearman + SQLAlchemy - 不斷丟失MySQL線程

一切正常工作一兩個小時,然後MySQL線程會丟失,所有查詢失敗。當我爲pool_recycle定義這樣一個低值時,我無法弄清楚爲什麼線程正在丟失(我在3臺不同的服務器上得到相同的結果)。另外,爲什麼不創建新的連接?

要調查的事情的任何想法?

import gearman 
import json 
import ConfigParser 
import sys 
from sqlalchemy import create_engine 

class JSONDataEncoder(gearman.DataEncoder): 
    @classmethod 
    def encode(cls, encodable_object): 
     return json.dumps(encodable_object) 
    @classmethod 
    def decode(cls, decodable_string): 
     return json.loads(decodable_string) 

# get the ini path and load the gearman server ips:ports 
try: 
    ini_file = sys.argv[1] 
    lib_path = sys.argv[2] 
except Exception: 
    raise Exception("ini file path or anypy lib path not set") 

# get the config 
config = ConfigParser.ConfigParser() 
config.read(ini_file) 
sqlachemy_url = config.get('app:main', 'sqlalchemy.url') 
gearman_servers = config.get('app:main', 'gearman.mysql_servers').split(",") 

# add anypy include path 
sys.path.append(lib_path) 
from mypylonsapp.model.user import User, init_model 
from mypylonsapp.model.gearman import task_rates 

# sqlalchemy setup, recycle connection every hour 
engine = create_engine(sqlachemy_url, pool_recycle=3600) 
init_model(engine) 

# Gearman Worker Setup 
gm_worker = gearman.GearmanWorker(gearman_servers) 
gm_worker.data_encoder = JSONDataEncoder() 

# register the workers 
gm_worker.register_task('login', User.login_gearman_worker) 
gm_worker.register_task('rates', task_rates) 

# work 
gm_worker.work() 
+1

另一種思考的authoritivie文檔,你釋放任務之間的sqlalchemy會話還是重新使用它們? – David 2011-02-03 21:03:07

+0

@大衛 - 不,我沒有解放他們,重複使用他們。做了更多挖掘,發現日誌中的「無法重新連接,直到無效事務回滾」。所以我在每個作業之後都嘗試過一個session.rollback(),但是這與我的一個作業的功能發生衝突,這會緩存sqlalchemy響應對象,並在後續作業中將其重用於大型加速。所以現在我正在嘗試使用NullPool - engine = create_engine(sqlachemy_url,poolclass = NullPool),並在每個作業之後調用session.close()。 24小時後將知道這是否是勝利組合。 – Tony 2011-02-04 16:45:19

回答

3

無論使用哪個數據庫庫,我都已經看到了Ruby,PHP和Python的全面性。我無法找到如何解決這個「正確」的方式,這是使用mysql_ping,但有一個SQLAlchemy解決方案,這裏解釋得更好http://groups.google.com/group/sqlalchemy/browse_thread/thread/9412808e695168ea/c31f5c967c135be0

正如該線程中的某人指出的那樣,將recycle選項設置爲等於True相當於將其設置爲1.更好的解決方案可能是查找MySQL連接超時值並將回收閾值設置爲80%。

您可以通過查找這個變量http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_connect_timeout

編輯得到現場組值: 我花了一下,找到上期運用pool_recycle http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/connections.html?highlight=pool_recycle