首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GEvent / GUnicorn与C10k问题

GEvent / GUnicorn与C10k问题
EN

Stack Overflow用户
提问于 2014-07-10 19:31:02
回答 1查看 2.1K关注 0票数 4

C10K问题告诉我们传统的web服务器充其量只有大约10K的限制。

像nginx这样的服务器使用单线程模型和异步通信,而不是线程来处理传入的请求。AFAIK 格事件使用小绿 (在同一线程中可切换的执行上下文)代替线程。

这就引出了两个问题(同样地:假设我们处于异步模型中--在gevent和gunicorn中思考):

  1. 在这种情况下:是否存在资源垄断的风险?对于基于绿色的服务器,我将进一步限制这个问题:假设资源占用实际上是一个互斥锁(互斥锁阻塞当前线程,尽管不是当前进程;但现在如果我们使用绿锁,我们就不再处于多线程架构中了.我错了吗?)。
  2. 如果我们不是一个基于绿色的体系结构(也不是一个线程架构):Websockets是如何在服务器上实现的?

另一个问题是Django:

  1. 当我不在视图中且无法直接到达视图参数时,如何标识当前请求?我使用threading.local (在自定义中间件中填充)标识当前线程的做法很糟糕,但在这段时间里,我没有考虑非线程架构(只要我可以说“一个请求(暗示)一个线程”,我的代码就很好)。

在一个场景中,这将帮助我识别当前的request,当一个表单调用( clean() /定制)字段的clean()方法时(即根据当前请求根据数据验证值)。但是,如果我的普通请求超过了10k的限制,并且使用了异步(非线程)方法,这个方法就会失败。

EN

回答 1

Stack Overflow用户

发布于 2014-07-16 20:50:37

(编辑- gevent.monkey.patch_all() -在wsgy.py脚本文件中运行-自动将线程局部变量修补为绿色局部变量,因此GEvent (或带有GUnicorn的GUnicorn)不需要这种使用Werkzeug的替代方法-如果您以某种方式使用没有GEvent的绿地,则可能需要此解决方案)

当我想起瓶架时我找到了一个答案

烧瓶是一个框架,它支持“全局”的许多对象,如sessionrequest,它们的“外观”类似于threading.local对象。主要区别在于它们是上下文局部变量而不是线程局部变量,而上下文是任意当前执行堆栈

线程有自己的上下文(因此,当阅读线程理论时,上下文切换的概念)。进程有它的上下文,它包含线程(和主线程)。

到目前为止,在我们所知道的理论中,一个进程包含一个线程,一个线程包含它自己的执行上下文。除非线程能够创建自己的数据上下文,否则数据总是共享的。这就是线程局部变量(变量/数据)概念出现的地方。

但是,为了解决并发执行的概念,并考虑到C10K问题,首选在一个线程中异步执行,而不是使用相应的上下文开关的多个阻塞线程(特别是关于python,在默认的python distr0中有GIL )。Greenlet是作为一个相同的线程交换上下文创建的,现在层次结构改变了:

代码语言:javascript
复制
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的上下文局部变量帮助创建(恰当地说)上下文--局部变量(上下文意味着线程、请求或进程--取决于服务器分发请求的方式),这可以帮助我们存储特定于绿地的数据,并避免使用线程局部变量:

代码语言:javascript
复制
#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 None
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24684781

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档