resty.http在执行阻塞式http请求(比如long poll之类的)期间,是否可以检测到ngx.worker.exiting()并终止当前的http请求?

237 views
Skip to first unread message

pickl...@gmail.com

unread,
Dec 19, 2017, 8:33:32 PM12/19/17
to openresty
  比如在openresty中使用http去定时拉取consul的服务变更http://127.0.0.1:8500/v1/health/service/testapi?wait=5m&index=23454072,这个请求会在有长达5分钟的时间内当consul检测服务有变更时返回结果,否则只有5分钟计时结束时http才会有返回。但是如果在此期间内如果想要使用nginx -s quit结束服务的话,则会有nginx的worker因为http请求未结束而处于shuting down的状态。
  http在此期间能否接收或检测到ngx.worker.exiting()的状态并作出实时响应,终止掉当前正在处理的http请求。
  还有,当openresty收到quit信号后,处理http请求的worker如何结束循环并通知master我已经ok了,可以优雅的退出了?如果什么也不做,那么等若干时间之后nginx也能自动检测到所有worker都ok了,可以退出了,但这个过程会持续比较长的时间。这里我使用了os.exit()立即结束worker,合适吗?还有更好的方式吗?
  此外这个定时拉取consul服务变更的操作是在worker中使用定时器去循环获取的,对于这种循环获取数据的逻辑,还有什么更合适更高效的调用方式吗?
  O(∩_∩)O谢谢。

tokers

unread,
Dec 19, 2017, 9:07:00 PM12/19/17
to openresty
Hello!

> 比如在openresty中使用http去定时拉取consul的服务变更http://127.0.0.1:8500/v1/health/service/testapi?wait=5m&index=23454072,这个请求会在有长达5分钟的时间
> 内当consul检测服务有变更时返回结果,否则只有5分钟计时结束时http才会有返回。但是如果在此期间内如果想要使用nginx -s quit结束服务的话,则会有nginx的
> worker因为http请求未结束而处于shuting down的状态。
>  http在此期间能否接收或检测到ngx.worker.exiting()的状态并作出实时响应,终止掉当前正在处理的http请求。

目前应该是不支持的。

>  还有,当openresty收到quit信号后,处理http请求的worker如何结束循环并通知master我已经ok了,可以优雅的退出了?如果什么也不做,那么等若干时间之后
> nginx也能自动检测到所有worker都ok了,可以退出了,但这个过程会持续比较长的时间。这里我使用了os.exit()立即结束worker,合适吗?还有更好的方式吗?

master 告知 worker 退出后,worker 会取消监听,处理完所有的事件(网络事件以及定时器事件)后再退出。退出不需要再告诉 master。nginx/1.11.6 之前的版本,我记得 shut down 会因为 HTTP/2 的一个 bug 而可能一直没法退出,nginx/1.11.11 新加了一个 worker_shutdown_timeout,即你可以自己控制退出时的超时时间。os.exit() 会直接把进程退掉,此时该进程维持的连接就会被关闭,可能这个请求的逻辑并没完全处理完,这种粗暴的退出方式对客户端不友好。

>  此外这个定时拉取consul服务变更的操作是在worker中使用定时器去循环获取的,对于这种循环获取数据的逻辑,还有什么更合适更高效的调用方式吗?
>  O(∩_∩)O谢谢。

你是每个 worker 单独去拉的吗?可以考虑全局启动一个定时器拉取到共享内存。
另外不知道你 consul 里数据的大小如何,如果大的话,不妨加一个版本号的控制,每次拉取时,可以先获取版本号,如果版本号一致,数据没必要更新;如果不一致,则再拉去数据更新。有兴趣的话可以参考下我写的这个库:https://github.com/upyun/lua-resty-sync

pickl...@gmail.com

unread,
Dec 20, 2017, 10:33:07 PM12/20/17
to openresty
> 目前应该是不支持的。
  恩,我知道现在是没有,有没有计划纳入支持?

>  master 告知 worker 退出后,worker 会取消监听...
 是不友好,所以想了解是否有更好的函数。服务到了这个阶段,除了这个定时器跑的http拉取以外就没有其它的操作了。关键是即使之后这个拉取结束循环退出了,也不知怎么通知nginx去结束所有进程,一般都还要等过了若干时间后nginx才检测并完成quit的操作。

> 你是每个 worker 单独去拉的吗?可以考虑全...
 代码写得很赞,不过我的逻辑侧重于http阻塞拉取这个比较重的耗时操作。我想表达的是耗时的逻辑请求,除了放定时器里,还有其它的处置方式吗?

 O(∩_∩)O谢谢。


在 2017年12月20日星期三 UTC+8上午10:07:00,tokers写道:

tokers

unread,
Dec 21, 2017, 2:36:47 AM12/21/17
to openresty
>> 目前应该是不支持的。
>  恩,我知道现在是没有,有没有计划纳入支持?

这个可能得问问作者了。 :)


>>  master 告知 worker 退出后,worker 会取消监听...
> 是不友好,所以想了解是否有更好的函数。服务到了这个阶段,除了这个定时器跑的http拉取以外就没有其它的操作了。关键是即使之后这个拉取结束循环退出了,> 也不知怎么通知nginx去结束所有进程,一般都还要等过了若干时间后nginx才检测并完成quit的操作。

这个库里有个 API,可以让当前进程 quit (gracefully)。

>> 你是每个 worker 单独去拉的吗?可以考虑全...
> 代码写得很赞,不过我的逻辑侧重于http阻塞拉取这个比较重的耗时操作。我想表达的是耗时的逻辑请求,除了放定时器里,还有其它的处置方式吗?

在 OpenResty/Nginx 处理定时任务最好的地方就是定时器。

tokers

unread,
Dec 21, 2017, 2:38:20 AM12/21/17
to openresty
另外如果你的这个业务,全局只需要一个定时器,不妨交给 cache manager process 或者 priviledge_agent 这样的 helper 进程来处理。这两个进程虽然不监听端口,但是也是可以处理定时器任务的。

Reply all
Reply to author
Forward
0 new messages