【问题标题】:What is the concurrency model in Openresty?Openresty 中的并发模型是什么?
【发布时间】:2014-02-06 19:32:45
【问题描述】:

我很难理解 openresty(或 nginx)的并发模型。我阅读了Lua variable scope,它解释了变量的生命周期,但它没有说明对它们的并发访问。

语言很难解释,所以我试着用代码来解释。想象一下我有这个 Lua 模块:

local counter = {count = 0}

function counter.incr(amount)
  counter.count = counter.count + (amount or 1)
end

return counter

然后我像这样在 openresty 中使用它:

server {
  location /incr {
    content_by_lua '
      local counter = require 'counter'
      counter.incr(1)
    '
  }
  location /decr {
    content_by_lua '
      local counter = require 'counter'
      counter.incr(-1)
    '
  }
  location /count {
    content_by_lua '
      local counter = require 'counter'
      ngx.write(counter.count)
    '
  }
}

我想了解并发模型以便回答这些问题:

  • 如果我对/incr 进行了 10 次并发调用,然后我又调用了/count,我能否确定结果将是 10(我假设不是,但为什么)?
  • 如果我对/incr 进行10 次并发调用,同时对/decr 进行另外10 次调用,我可以确定/count 将返回0 吗?
  • 工人数量如何影响结果?
  • 代码发生的阶段(即init_by_lua而不是content_by_lua)如何影响结果?

【问题讨论】:

    标签: concurrency nginx lua


    【解决方案1】:

    nginx 使用基于事件的架构,这意味着它使用单个线程1 和一个事件循环,当套接字准备好读取或写入时,它会处理套接字。这意味着请求并不是真正同时处理的,但多个请求可以快速一个一个地处理,即使单个请求的处理可能会出现任何套接字/IO 延迟。

    如果我对 /incr 进行 10 次并发调用,然后我调用 /count,我能否确定结果将是 10(我假设不是,但为什么)?

    是的。只要在所有/incr 请求完成后调用/count,结果将是10。想象一下已经完成了9 个请求,但是第10 个请求由于某种原因被发送者延迟了, 如果 /count 在 nginx 处理第 10 个请求之前被处理,你应该得到 9 作为结果。

    如果我对 /incr 进行 10 次并发调用,同时对 /decr 进行另外 10 次调用,我能否确定 /count 将返回 0?

    可以,但无法保证处理这些请求的顺序。请注意,在这种情况下,您不需要锁定状态或使用全局信号量或类似的东西。如果您在读取状态和写回状态之间有一些 I/O 调用,您可能会遇到麻烦(因为在此期间可以处理不同的请求),但这不是您的示例所做的。

    工人数量如何影响结果?

    Lua 实例在由同一个工作进程处理的请求之间共享,因此多个工作进程不会给您相同的结果。您的所有/incr 请求都可以发送给一个工作人员,但您的/count 请求可以发送给另一个工作人员,使用不同的Lua 实例(仍然)将count 设置为0。如果您需要在实例之间共享数据,您可能需要使用lua_shared_dict 之类的东西。有关其他选项,另请参阅data sharing 部分。

    代码发生的阶段(即 init_by_lua 而不是 content_by_lua)如何影响结果?

    init_by_lua仅在主进程加载配置文件时执行。

    1 据我所知,它可以派生多个实例来处理多核系统和其他一些情况。

    【讨论】:

    • 很棒的答案,非常感谢保罗。我能问你这一切是从哪里学来的吗?除了HttpLuaModule,我找不到任何没有主题的参考资料。
    • 谢谢@kikito;不久前,我在我们的 CS 课程中阅读了几篇关于 nginx 的论文。我对他们的事件驱动架构非常感兴趣,与其他线程/分叉服务器相比,它可以以更少的资源提供更好的结果。
    猜你喜欢
    • 2013-08-12
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多