我刚刚发现了Pyramid应用程序的一个非常大的问题。 mongo scaffold暗示事件处理程序也应该用于处理数据库连接。这个想法是,当新请求进入时,连接到数据库,当页面呈现断开连接时。
所以这就是我在__init.py__
def connectDatabase(event):
mongo = MongoDB()
con = mongo.connectDatabase()
db = con[Cfg_MongoDB_Database]
event.request.con = con
event.request.db = db
redis = Redis()
con = redis.connectDatabase()
event.request.redis = con
log.debug('newrequest')
def closeConnection(event):
mongo = MongoDB()
mongo.closeConnection(event.request.con)
log.debug('newresponse')
def main(global_config, **settings):
config = Configurator(settings=settings, root_factory=Dashboard)
authentication = AuthTktAuthenticationPolicy(Cfg_Auth_Key, hashalg='sha512',\
include_ip=False, timeout=3600*24*7, max_age=3600*24*7, reissue_time=3600)
authorization = ACLAuthorizationPolicy()
config.set_authentication_policy(authentication)
config.set_authorization_policy(authorization)
config.add_static_view('includes', 'includes', cache_max_age=3600)
config.add_renderer(".html", "pyramid.mako_templating.renderer_factory")
config.add_route('dash', '/')
config.add_subscriber(connectDatabase, NewRequest)
config.add_subscriber(closeConnection, NewResponse)
log.debug('main')
config.scan()
return config.make_wsgi_app()
但是我已经将一些记录器放入连接到数据库的方法中,并且发现该方法被调用10次以上,并且如果我在add_static_view
中禁用缓存超过100次。这意味着对于每个css,image,js,都会建立新的连接。这是巨大的开销!该站点需要300ms才能连接数据库100次!
/Users/jan/Documents/Test2/test2/data.py changed; reloading...
-------------------- Restarting --------------------
2013-02-01 18:32:48,351 DEBUG [test2.tools][MainThread] main
Starting server in PID 12374.
serving on http://127.0.0.1:6543
2013-02-01 18:34:14,451 DEBUG [test2.tools][Dummy-2] newrequest
2013-02-01 18:34:14,582 DEBUG [test2.tools][Dummy-2] newresponse
2013-02-01 18:34:14,952 DEBUG [test2.tools][Dummy-3] newrequest
2013-02-01 18:34:14,953 DEBUG [test2.tools][Dummy-3] newresponse
2013-02-01 18:34:17,459 DEBUG [test2.tools][Dummy-4] newrequest
2013-02-01 18:34:17,474 DEBUG [test2.tools][Dummy-4] newresponse
2013-02-01 18:34:17,482 DEBUG [test2.tools][Dummy-5] newrequest
2013-02-01 18:34:17,497 DEBUG [test2.tools][Dummy-5] newresponse
2013-02-01 18:34:19,158 DEBUG [test2.tools][Dummy-2] newrequest
2013-02-01 18:34:19,159 DEBUG [test2.tools][Dummy-2] newresponse
所以到目前为止的解决方案是将连接转移到Model。但是我怎么知道我什么时候可以关闭连接?对于我的问题,任何人都有更好,更优雅的解决方案吗?
答案 0 :(得分:3)
pymongo内置了连接池http://api.mongodb.org/python/current/api/pymongo/mongo_client.html#pymongo.mongo_client.MongoClient
使用连接池不应该在每个请求上创建新连接
此外,我认为你的金字塔应用程序不应该在生产中提供静态媒体,正是出于这个原因,apache,nginx已经过优化以提供文件,而你的请求也不必通过你的应用程序
答案 1 :(得分:3)
在Pyramid中执行此操作的建议方法是使用请求属性,而不是NewRequest
事件。正如您所注意到的,该事件是针对每个请求触发的,包括静态请求。请求属性是惰性的,只在您需要时进行评估,并且您可以指定它们在请求的生命周期内被缓存(实现)。我已经链接了下面的示例,该示例演示了如何添加request.db
。
https://raw.github.com/Pylons/pyramid_cookbook/master/database/mongodb.rst
以下是一些适合您的更新代码。
def main(global_config, **settings):
# ...
db_url = urlparse(settings['mongo_uri'])
config.registry.db = pymongo.Connection(
host=db_url.hostname,
port=db_url.port,
)
def add_db(request):
db = config.registry.db[db_url.path[1:]]
if db_url.username and db_url.password:
db.authenticate(db_url.username, db_url.password)
return db
config.add_request_method(add_db, 'db', reify=True)