Django中请求之间的共享对象
Posted
技术标签:
【中文标题】Django中请求之间的共享对象【英文标题】:Shared object between requests in Django 【发布时间】:2011-08-03 13:54:51 【问题描述】:我正在使用 Python 模块 (PyCLIPS) 和 Django 1.3。
我想开发一个线程安全类,它实现了对象池和单例模式,并且必须在 Django 中的请求之间共享。
例如,我想做以下事情:
请求从池中获取具有某个 ID 的对象,执行 用它把它推回池中,然后发送响应 与对象的 ID。 具有对象 ID 的另一个请求获取 池中具有给定 ID 的对象,并重复上述请求中的步骤。 但是当服务器运行时,对象的状态必须保持在池中。应该像Singleton Session Bean in Java EE
我应该怎么做?有什么我应该读的吗?
更新: 我无法将池中的对象存储在数据库中,因为这些对象是用 C 语言编写的库下的包装器,该库是 Expert System Engine CLIPS 的 API。
谢谢!
【问题讨论】:
你试过使用Djangohttps://docs.djangoproject.com/en/dev/topics/cache/的缓存框架吗?您可以在请求之间将对象缓存/持久保存在内存中。 【参考方案1】:嗯,我认为这里需要一个不同的角度。 Django 不像 Java,解决方案应该针对多进程环境而不是多线程环境量身定制。
Django 没有直接等效的单例会话 bean。
也就是说,我认为您的描述没有理由不适合经典数据库模型。您想保存每个对象的数据,这些数据应该始终放在 DB 层中。
否则,您始终可以将内容保存在 Django 为登录用户和匿名用户提供的会话中 - see the docs on Django sessions。
考虑到运行 Java Web 容器和 Python/Django 多进程环境之间的巨大差异,在 Java 环境中使用您可能熟悉的任何其他模式最终都会失败。
编辑:好吧,考虑到这些对象不是您的应用程序原生的,而是通过第三方库访问的,这确实使事情变得复杂。我的直觉是,这些对象不应该由 Web 层处理,而应该由您可以从多进程环境访问的某种外部服务来处理。正如丹尼尔所提到的,您总是可以将它们放入缓存中(如果所述对象是可腌制的)。但感觉好像这些对象不属于网络层。
【讨论】:
你知道另一个允许这样做的python框架吗? 嗯,不是真的。大多数主流 Web 框架都在多进程环境中工作。 Java 是一种奇怪的生物,因为它总是在单个 JVM 上运行。 好吧,我明白了,在 JavaEE 中实现与单例会话 bean 相同的模式没有很好的方法。因此,我认为,我必须使用JavaEE。【参考方案2】:假设对象不能被腌制,您将需要创建一个应用程序来管理对象以及需要针对它发生的所有交互。最简单的实现可能是创建一个单进程 wsgi 应用程序(在不同的端口上),它公开一个 api 来执行您需要的所有操作。是否使用 RESTful api 或表单帖子取决于您的个人喜好。
【讨论】:
请问如何创建单进程wsgi应用?【参考方案3】:这些是数据库对象吗?因为如果是这样,db 本身就是真正的池,不需要做任何特别的事情——每个请求都可以独立地从 db 加载实例,修改它,然后将其保存回来。
评论后编辑好吧,最大的问题是生产网络服务器环境很可能是多进程的,因此任何全局变量(即池)都不会在进程之间共享。您需要将它们存储在可全局访问的某处。黑暗中的短片,但它们是否可以使用 Pickle 进行序列化?如果是这样,那么也许 memcache 可能会起作用。
【讨论】:
不,我不能将对象存储在数据库中,因为这些对象是用 C 语言编写的库下的包装器,该库是专家系统引擎 CLIPS 的 API。 也许,我可以在进程之间共享这个变量,就像 Java EE 中的单例会话 bean。(download.oracle.com/javaee/6/tutorial/doc/gipjg.html#gipim) 我有一个类似的问题:我需要一个具有访问外部数据源状态的类的实例。如果我在模块级别实例化其中一个实例,我是否会为每个工作人员获得一个实例,因此,该工作人员一次只能处理一个请求?我的 Django 代码的执行模型是什么?以上是关于Django中请求之间的共享对象的主要内容,如果未能解决你的问题,请参考以下文章
Flask 中的全局变量是线程安全的吗?如何在请求之间共享数据?