1. 由于 nginx 自身的机制,一般情况下,在处理子请求时是不允许终止的。所以协程也一样,在处理子请求时也是不能终止,所以主协程必须要使用 ngx.thread.wait 来等待这些协程终止才能结束请求。不过调用 ngx.exit,传入状态码为 ngx.ERROR(-1),408,444,499 可以终止正在处理子请求的协程。
2. 只有父协程才能杀死子协程,如果子协程正在处理子请求,那么不能终止,
3. 使用协程时千万要注意,如果由于一些因素,子协程是一个死循环,或者永久等待,那么该连接不被被主动关闭,永远卡在该阶段的 handler,就算 reload 都没用,除非重启 nginx 才能终止
4. 如果要在Lua代码层面实现非阻塞I/O,那么父协程必须处理子协程I/O等待的情况,并在事件发生时恢复子协程的执行。如果需要同时进行多个任务,那么父协程就需要负责多个协程间的调度。因为协程的拓扑可能是一个复杂的树状结构,所以协程的调度管理将变得异常复杂。https://www.cnblogs.com/logchen/p/15145525.html
5. ngx.thread.spawn生成新的"light thread",这个"light thread"运行优先级比它的父协程高,会优先运行,父协程被迫暂停。"light thread"运行结束或者yield后,再由ngx_http_lua_run_posted_threads去运行父协程。
下面情况,“轻线程”协程可能是“僵尸”状态:
1. 当前“轻线程”已经终止(无论成功还是错误地)
2. 它的父协程还存活,但是他的父协程已经不再使用 ngx.thread.wait 进行等待
6. 子请求超时控制最好在location
7. 在父协程中只要wiat过的子协程就会一直存在,例如spawn() a,b,c; 第一次wiat(a,b,c),后面只需要wiat()就可以(不建议这样写),不需要每次都wiat(a,b,c),因为a,b,c已经在wiat列表;bug雷区
8. 子协程的请求会影响父级请求的cosocket请求(准确的说是有其他子协程的请求)。比如 redis、ngx.location.capture,所以建议有cosocket的都放在子协程里面,子协程之间是不影响的。
上面7、8是要特别注意的,如何避坑