在运行于Bottle的pythonanywhere应用中,我希望对象在请求之间得以保留。
如果我写这样的东西:
X = {'count': 0}
@route('/count')
def count():
X['count'] += 1
tpl = SimpleTemplate('Hello {{count}}!')
return tpl.render(count=X['count'])
计数增加,这意味着X在请求之间保持不变。
我目前正在pythonanywhere上运行它,这是一项托管服务,在这里我无法控制Web服务器(我假设是nginx?)线程,负载平衡(如果有)等...
我的问题是,这是巧合吗,因为它仅使用一个线程,而我的测试负载却很小?
更一般而言,这将在什么时候停止?例如。我有多个线程/套接字/实例/负载均衡服务器等?
除此之外,即使必须移动到准系统服务器,做这样的工作(坚持到瓶子)也是我最好的选择。
这是Bottle docs关于其请求对象的内容:
LocalRequest的线程安全实例。如果从请求回调中进行访问,则此实例将始终引用当前请求(即使在多线程服务器上)。
但是我不完全了解这意味着什么,或者像我所使用的那样,全局变量在多线程方面的地位。
答案 0 :(得分:1)
TL; DR:您可能希望使用外部数据库来存储状态。
如果您的应用程序很小,并且您计划始终只运行一个服务器进程,那么您当前的方法可以工作;您需要做的“所有”操作是锁定对共享状态的每次访问(!)(示例代码中的字典X
)。 (我把“全部”放在吓人的引号中,因为它可能变得比起初听起来更复杂。)
但是,由于您询问的是多线程,因此我认为您的应用程序不只是玩具,这意味着您计划接收大量流量和/或希望同时处理多个请求。在这种情况下,您将需要多个进程,这意味着您的方法(将状态存储在内存中)无法工作。内存不跨进程共享。跨进程共享状态的(一般)方式是在外部存储状态,例如在数据库中。
您熟悉Redis吗?那将在我的候选人短名单上。
答案 1 :(得分:1)
我可以通过与PythonAnywhere支持人员联系来获得答案,后者的说法是:
当您使用免费 PythonAnywhere帐户运行网站时, 一个进程处理您的所有请求-所以像 您在那里使用的那一个很好。但是只要您想扩展 并获得(例如)一个黑客帐户,那么您将有多个流程 (不是线程)-当然每个人都有自己的全局变量 变量,所以事情会出错。
因此,该部分讨论了PythonAnywhere的工作原理以及何时停止在其中工作。
第二部分的答案,关于如何在多个Bottle进程之间共享变量,一旦他们了解数据库在这种情况下将无法正常运行,我也得到了他们的支持(最有帮助!)。
不同的进程当然不能共享变量,最可行的解决方案是:
编写自己的缓存服务器以处理将内容保存在内存中的过程。您将有一个始终运行的进程,并且Web API请求将以某种方式对其进行访问(内部REST API?)。它可以将内容保留在内存中[...]
Ps:我没想到会有其他答复告诉我将状态存储在数据库中,我发现我要问的事实意味着我有充分的理由不使用数据库,这很浪费时间!” / p>