C10K问题告诉我们传统的web服务器充其量只有大约10K的限制。
像nginx这样的服务器使用单线程模型和异步通信,而不是线程来处理传入的请求。AFAIK 格事件使用小绿 (在同一线程中可切换的执行上下文)代替线程。
这就引出了两个问题(同样地:假设我们处于异步模型中--在gevent和gunicorn中思考):
另一个问题是Django:
threading.local (在自定义中间件中填充)标识当前线程的做法很糟糕,但在这段时间里,我没有考虑非线程架构(只要我可以说“一个请求(暗示)一个线程”,我的代码就很好)。在一个场景中,这将帮助我识别当前的request,当一个表单调用( clean() /定制)字段的clean()方法时(即根据当前请求根据数据验证值)。但是,如果我的普通请求超过了10k的限制,并且使用了异步(非线程)方法,这个方法就会失败。
发布于 2014-07-16 20:50:37
(编辑- gevent.monkey.patch_all() -在wsgy.py脚本文件中运行-自动将线程局部变量修补为绿色局部变量,因此GEvent (或带有GUnicorn的GUnicorn)不需要这种使用Werkzeug的替代方法-如果您以某种方式使用没有GEvent的绿地,则可能需要此解决方案)
当我想起瓶架时我找到了一个答案
烧瓶是一个框架,它支持“全局”的许多对象,如session和request,它们的“外观”类似于threading.local对象。主要区别在于它们是上下文局部变量而不是线程局部变量,而上下文是任意当前执行堆栈。
线程有自己的上下文(因此,当阅读线程理论时,上下文切换的概念)。进程有它的上下文,它包含线程(和主线程)。
到目前为止,在我们所知道的理论中,一个进程包含一个线程,一个线程包含它自己的执行上下文。除非线程能够创建自己的数据上下文,否则数据总是共享的。这就是线程局部变量(变量/数据)概念出现的地方。
但是,为了解决并发执行的概念,并考虑到C10K问题,首选在一个线程中异步执行,而不是使用相应的上下文开关的多个阻塞线程(特别是关于python,在默认的python distr0中有GIL )。Greenlet是作为一个相同的线程交换上下文创建的,现在层次结构改变了:
Process 1--* thread 1--* greenlet (and now the requests are here)因此,Greenlet的概念是在Gevent这样的服务器中用Python创建和实现的,您不能再使用线程本地数据,因为请求不再绑定到线程(也就是说,它们可以是共享相同的线程本地上下文,争夺数据)。
现在上下文本身就是绿色环境,我们需要一个上下文本地的概念,而不是线程局部变量。
那么: Flask如何使用上下文本地来隔离每个请求的数据呢?(例如一次会议、一项请求)。与上下文无关的隔离的答案在这里:
Werkzeug的语境本地人
Werkzeug和烧瓶有相同的创造者。Werkzeug是,不是a Framework,而是--您可以在任何WSGI框架(例如Django)中使用的一组实用程序。框架本身就是Flask,它实际上依赖于Werkzeug的实用程序。
Werkzeug的上下文局部变量帮助创建(恰当地说)上下文--局部变量(上下文意味着线程、请求或进程--取决于服务器分发请求的方式),这可以帮助我们存储特定于绿地的数据,并避免使用线程局部变量:
#a python module for my django project where I define
#a custom field class which statically needs to know the
#current request.
#I was using, instead, a threadlocal. The usage is THE SAME.
#the main difference is that threads are GCed, while contexts
#not necessarily, so you must ALWAYS release them explicitly
#using release_local, for the current context.
#this code below used to have `threading.local` instances
#instead of `werkzeug.local.Local` instances.
#as I said before, assigning data works like before, but
#the main difference is when releasing the data.
from werkzeug.local import Local, release_local
class AutocompleteField(object):
DATA = Local()
@staticmethod
def set_request(request):
AutocompleteField.DATA.request = request
@staticmethod
def unset_request(request):
release_local(AutocompleteField.DATA)
@staticmethod
def get_request():
try:
return AutocompleteField.DATA.request
except AttributeError as e:
return Nonehttps://stackoverflow.com/questions/24684781
复制相似问题