Concurrency Openresty中的并发模型是什么?
我很难理解openresty(或nginx)的并发模型。我读了,它解释了变量的生存期,但它没有说明对它们的并发访问 很难用文字来解释,所以让我试着用代码来解释。假设我有这个Lua模块:Concurrency Openresty中的并发模型是什么?,concurrency,nginx,lua,Concurrency,Nginx,Lua,我很难理解openresty(或nginx)的并发模型。我读了,它解释了变量的生存期,但它没有说明对它们的并发访问 很难用文字来解释,所以让我试着用代码来解释。假设我有这个Lua模块: local counter = {count = 0} function counter.incr(amount) counter.count = counter.count + (amount or 1) end return counter 然后我在openresty中使用它,如下所示: serve
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)
'
}
}
我想了解并发模型,以便回答以下问题:
- 如果我同时调用10次
,然后调用/incr
,我可以确定结果是10次吗(我假设不是,但为什么)/count
- 如果我同时对
执行10次调用,同时又对/incr
执行10次调用,我是否可以确保/decr
将返回0/count
- 工人数量如何影响结果
- 代码发生的阶段(即
而不是init_by_lua
)如何影响结果content_by_lua
/incr
请求完成后调用/count
,结果将是10。假设9个请求已经完成,但是第10个请求由于某种原因被发送方延迟,如果在nginx处理第10个请求之前处理了/count
,那么结果应该是9个
如果我同时对/incr执行10次调用,同时又对/decr执行10次调用,我是否可以确保/count将返回0
是的,但不能保证这些请求的处理顺序。注意,在这种情况下,您不需要锁定您的状态或使用全局信号量或类似的东西。如果在读取状态和写回状态之间有一些I/O调用,您可能会遇到麻烦(因为在此期间可以处理不同的请求),但这不是您的示例所做的
工人数量如何影响结果
Lua实例在由同一工作进程处理的请求之间共享,因此多个工作进程不会给出相同的结果。您的所有/incr
请求都可以转到一个worker,但是您的/count
请求可以转到另一个worker,而另一个Lua实例(仍然)将count
设置为0。如果需要在实例之间共享数据,则可能需要使用以下内容。有关其他选项,请参见上的一节
代码发生的阶段(即init_by_lua而不是content_by_lua)如何影响结果
init_by_lua
仅在主进程加载配置文件时执行
1我过于简单化了,因为它可以分叉多个实例来处理多核系统和其他一些情况,正如我所记得的那样。回答太棒了,非常感谢Paul。我能问一下你是从哪里学到这些的吗?我找不到任何关于这个主题的参考资料。谢谢@kikito;不久前,作为CS课程的一部分,我读了几篇关于nginx的论文。我对他们的事件驱动体系结构非常感兴趣,与其他线程/fork服务器相比,该体系结构能够以更少的资源提供更好的结果。