5.2.2 reinit_request回调方法

reinit_request可能会被多次回调。它被调用的原因只有一个,就是在第一次试图向上游服务器建立连接时,如果连接由于各种异常原因失败,那么会根据upstream中conf参数的策略要求再次重连上游服务器,而这时就会调用reinit_request方法了。图5-4描述了典型的reinit_request调用场景。

下面简单地介绍一下图5-4中列出的步骤。

5.2.2 reinit_request回调方法 - 图1

图 5-4 reinit_request回调场景的序列图

1)Nginx主循环中会定期地调用事件模块,检查是否有网络事件发生。

2)事件模块在确定与上游服务器的TCP连接建立成功后,会回调upstream模块的相关方法处理。

3)upstream模块这时会把r->upstream->request_sent标志位置为1,表示连接已经建立成功了,现在开始向上游服务器发送请求内容。

4)发送请求到上游服务器。

5)发送方法当然是无阻塞的(使用了无阻塞的套接字),会立刻返回。

6)upstream模块处理第2步中的TCP连接建立成功事件。

7)事件模块处理完本轮网络事件后,将控制权交还给Nginx主循环。

8)Nginx主循环重复第1步,调用事件模块检查网络事件。

9)这时,如果发现与上游服务器建立的TCP连接已经异常断开,那么事件模块会通知upstream模块处理它。

10)在符合重试次数的前提下,upstream模块会毫不犹豫地再次用无阻塞的套接字试图建立连接。

11)无论连接是否建立成功都立刻返回。

12)这时检查r->upstream->request_sent标志位,会发现它已经被置为1了。

13)如果mytest模块没有实现reinit_request方法,那么是不会调用它的。而如果reinit_request不为NULL空指针,就会回调它。

14)mytest模块在reinit_request中处理完自己的事情。

15)处理完第9步中的TCP连接断开事件,将控制权交还给事件模块。

16)事件模块处理完本轮网络事件后,交还控制权给Nginx主循环。