Gunicorn工人和线程

时间:2016-07-17 20:24:58

标签: gunicorn

就Gunicorn而言,我知道有各种工人类,但对于这次对话,我只是在看同步和异步类型。

从我的理解......

sync
workers = (2 * cpu) + 1
worker_class = sync

async (gevent)
workers = 1
worker_class = gevent
worker_connections = a value (lets say 2000)

因此(基于4核系统)使用同步工作器我可以并行处理最多9个连接。使用Async,我可以拥有高达2000,同时带有异步的警告。

问题

  • 那么线程适合哪里?我可以为同步和添加线程吗? 异步工作者类型?
  • 围绕枪支工人的最佳选择是什么? 我是否应该将一个gunicorn放在Django API前面 并行处理100个请求的要求?
  • gevent和sync工作线程是否安全?

1 个答案:

答案 0 :(得分:60)

让我尝试一下答案。让我们假设在开始时我的部署只有一名炮手工人。这允许我一次只处理一个请求。我的工作人员的工作只是打电话给google.com并获取查询的搜索结果。现在我想提高吞吐量。我有以下选项

仅保留一名工作人员并增加该工作人员的线程数

这是最简单的。由于线程比进程更轻量级(更少的内存消耗),我只保留一个worker并添加几个线程。 Gunicorn将确保主人可以向工人发送多个请求。由于worker是多线程的,因此它能够处理4个请求。太棒了。现在为什么我需要更多的工人呢?

要回答这个问题,假设我需要对google返回的搜索结果进行一些处理。例如,我可能还想为每个结果查询计算素数。现在我正在使我的工作负载计算受限,我用python的全局解释器锁来解决问题。即使我有4个线程,但一次只能有一个线程实际处理结果。这意味着要获得真正的并行性能,我需要不止一个工人。

增加工人数,但所有工人都是单线程

为什么我需要这个,当我需要真正的并行处理时。每个工作人员都可以并行拨打google.com,获取结果并进行任何处理。全部并行。太棒了。但缺点是流程越来越重,我的系统可能无法满足增加员工以实现并行性的要求。因此,最好的解决方案是增加工作人员,并为每个工作人员添加更多线程。

增加工人数量,每个工人都是多线程的

我想这不需要进一步解释。

将工作人员类型更改为Async

现在我为什么要这样做?要回答,请记住,即使线程消耗内存。有geventine(你可以查找的一个基本结构),由gevent库实现,允许你在不必创建线程的情况下获取线程。因此,如果你制作你的gunicorn使用工人类型的gevent,你可以获得不必在你的工人中创建线程的好处。假设您正在获取线程而无需显式创建它们。

因此,要回答您的问题,如果您使用的是除Sync之外的其他任何内容的worker_type,则无需增加gunicorn配置中的线程数。你可以通过各种方式做到这一点,但它有点挫败了目的。

希望这有帮助。

我也会尝试回答具体问题。

  • 不,Async worker类不存在thread选项。 这实际上需要通过文档更清楚。 想知道为什么没有发生这种情况。

  • 这是一个需要更多了解您具体知识的问题 应用。如果处理这些100的并行请求 只涉及I / O类操作,比如从DB获取,保存, 从其他一些应用程序收集数据,然后你可以使用 线程工作者。但如果情况不是这样,你想要 在n核CPU上执行,因为任务非常计算 绑定,也许像计算素数,你需要利用 同步工作者。异步的原因略有不同。使用 异步,您需要确保您的处理不受计算限制, 这意味着您将无法使用多个核心。 您获得的优势是多线程将占用的内存 不会在那里。但你有其他问题,如非猴子修补 库。仅当线程工作者不符合时才移至Async 你的要求。

  • 同步,非线程工作者是最好的选择,如果你想要绝对的 您的图书馆之间的安全线程。