![](/img/trans.png)
[英]Class instance in Python Bottle application, is it shared between threads/processes?
[英]Share state between threads in bottle
在运行在pythonanywhere上的Bottle应用程序中,我希望对象在请求之间保持不变 。
如果我写这样的话:
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文档必须针对其请求对象说的话:
LocalRequest的线程安全实例。 如果从请求回调中访问,则此实例将始终引用当前请求(即使在多线程服务器上)。
但是我不完全理解这意味着什么,或者像我所使用的那样,全局变量在多线程方面的地位如何。
TL; DR:您可能需要使用外部数据库来存储状态。
如果您的应用程序很小,并且您计划始终只运行一个服务器进程,那么您当前的方法可以工作; 您需要做的“所有”操作是锁定对共享状态的每次访问(!)(示例代码中的dict X
)。 (我在这里用“ all”括起来,因为它可能变得比起初听起来更复杂。)
但是,由于您正在询问多线程,因此我假设您的应用程序不只是玩具,这意味着您计划接收大量流量和/或希望同时处理多个请求。 在这种情况下,您将需要多个进程,这意味着您的方法(将状态存储在内存中)无法工作。 内存不跨进程共享。 跨进程共享状态的(一般)方法是在外部(例如,在数据库中)存储状态。
您熟悉Redis吗? 那将在我的候选人短名单上。
我通过与PythonAnywhere支持人员联系来寻求答案,他说:
当您使用免费的 PythonAnywhere帐户运行网站时,只有一个进程可以处理您的所有请求-因此,像您使用的那样使用全局变量就可以了。 但是,只要您想扩大规模并获得(例如)一个黑客帐户,您就会拥有多个进程(而不是线程)-当然,每个进程都有其自己的全局变量,因此一切都会进行错误。
因此,该部分讨论了PythonAnywhere的细节,说明了它为什么起作用以及何时停止在那里工作。
第二部分的答案,关于如何在多个Bottle进程之间共享变量,一旦他们了解到数据库在这种情况下将无法正常运行,我也会得到他们的支持(最有帮助!)。
当然,不同的流程不能共享变量,最可行的解决方案是:
编写自己的缓存服务器来处理将内容保存在内存中的过程。您将有一个始终运行的进程,并且Web API请求将以某种方式对其进行访问(内部REST API?)。 它可以将内容保留在内存中[...]
附言:我没想到会有其他回复告诉我将状态存储在数据库中,我发现我要问的事实意味着我有充分的理由不使用数据库,这很浪费时间!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.