V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
Askiz
V2EX  ›  NGINX

请问 lua+nginx 怎么实现并行?

  •  
  •   Askiz · 2022-07-26 21:33:03 +08:00 · 2149 次点击
    这是一个创建于 885 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ----

    ----

    ----

    ----
    这用不用 ngx.thread.spawn 时间都是一样的,请问问题出在哪呢?而且 ngx.thread.spawn 好像也不是异步执行挂在后台的。
    10 条回复    2022-07-26 23:27:18 +08:00
    westoy
        1
    westoy  
       2022-07-26 22:11:29 +08:00   ❤️ 1
    ngx.thread.spawn 是基于 nginx IO 事件和 lua coroutine 的协程封装, 拿来处理 IO 异步的, 跑这种 CPU 运算没什么用的, 这种重 CPU 运算要尽量拆分出 nginx , 要么跑 fcgi 、scgi 之类的, 要么后端单独起一个基于 fork 机制的 http 服务器, 然后 nginx proxy 给它
    clino
        2
    clino  
       2022-07-26 22:23:50 +08:00
    协程中间没有主动中断(比如说调用协程的 sleep ,或者等待 io )是无法跳出去运行其他协程的,这个和操作系统控制下的线程是不一样的
    所以你要像切换协程,中间就要主动自己打断才能给协程跳出的机会。
    eason1874
        3
    eason1874  
       2022-07-26 22:29:46 +08:00
    ngx.thread.spawn 是异步的吧,你要阻塞好像是要用 ngx.thread.wait 等待结果
    Askiz
        4
    Askiz  
    OP
       2022-07-26 22:33:39 +08:00 via Android
    @eason1874 但是感觉好像并没有异步,用了 ngx.spawn 还要等所有协程运行结束才能返回结果,可以看上面的运行截图
    eason1874
        5
    eason1874  
       2022-07-26 22:40:00 +08:00
    @Askiz 跑一半被中止了也是可能的,你得在 test 打日志才知道有没有真的运行结束
    HiCode
        6
    HiCode  
       2022-07-26 22:43:17 +08:00   ❤️ 1
    不太确定你想要实现什么样的结果。

    如果是希望提前返回结果给客户端,但继续执行其他操作,可以用 ngx.eof(),要注意此时 nginx 的 worker 还在被占用。

    如果是希望在当前请求之外,开启另外的线程去处理其他事务,可以用 ngx.timer 。
    Askiz
        7
    Askiz  
    OP
       2022-07-26 22:44:18 +08:00 via Android
    @eason1874 我试了一下是都有的
    eason1874
        8
    eason1874  
       2022-07-26 23:13:12 +08:00
    @Askiz 我刚测试了,是异步的,os.clock() 计算的时间不对,估计它只算父协程的时间,不包括轻线程的

    你用我这段代码试试

    ```
    local function test(name, sec)
    ngx.say(name .. " start: " .. ngx.localtime())
    ngx.sleep(sec)
    ngx.update_time()
    ngx.say(name .. " --end: " .. ngx.localtime())
    end

    ngx.say("pages start: " .. ngx.localtime())

    ngx.thread.spawn(test, 'test1', 1)
    ngx.thread.spawn(test, 'test2', 2)

    ngx.update_time()
    ngx.say("pages --end: " .. ngx.localtime())

    ```

    pages start: 2022-07-26 23:11:44
    test1 start: 2022-07-26 23:11:44
    test2 start: 2022-07-26 23:11:44
    pages --end: 2022-07-26 23:11:44
    test1 --end: 2022-07-26 23:11:45
    test2 --end: 2022-07-26 23:11:46
    eason1874
        9
    eason1874  
       2022-07-26 23:19:40 +08:00   ❤️ 1
    #8 补充

    如果你在 pages --end 下面就用 ngx.exit(200) 退出父协程,会发现没等 test end 页面就返回了

    如果在 test end 那里打日志,ngx.exit 提前退出之后,页面实时返回,也可以看到没有 end 日志,说明异步线程被中止了
    Askiz
        10
    Askiz  
    OP
       2022-07-26 23:27:18 +08:00 via Android
    @HiCode 我是想实现多个函数并发异步执行,通过信号量实现同步。每个函数都是一些正则匹配什么的运算。但似乎 ngx.thread.spawn 并不能实现。可能就像 1P 说的需要后端单独起一个可以实现并发异步的服务提供给 openresty 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2780 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 06:48 · PVG 14:48 · LAX 22:48 · JFK 01:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.