# A problem with the keepalive module and the direcitve proxy\_next\_upstream

**URL:** <https://www.ruby-forum.com/t/a-problem-with-the-keepalive-module-and-the-direcitve-proxy-next-upstream/229438>\
**Category:** NGINX\
**Created:** [January 14, 2013, 9:11am UTC](https://www.ruby-forum.com/t/a-problem-with-the-keepalive-module-and-the-direcitve-proxy-next-upstream/229438 "2013-01-14T09:11:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![yaoweibin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/e9bcb4/32.png) [@yaoweibin](https://www.ruby-forum.com/u/yaoweibin)\
**Post date:** [January 14, 2013, 9:11am UTC](https://www.ruby-forum.com/t/a-problem-with-the-keepalive-module-and-the-direcitve-proxy-next-upstream/229438/1 "2013-01-14T09:11:59Z")

</div>

Hi, folks,

We have found a bug with the keepalive module. When we used the  
keepalive  
module, the directive proxy\_next\_upstream seems disabled.

We use Nginx as reverse server. Our backend servers simply close  
connection  
when read some abnormal packets. Nginx will call the function  
ngx\_http\_upstream\_next() and try to use the next server. The ft\_type  
is NGX\_HTTP\_UPSTREAM\_FT\_ERROR. We want to turn off the try mechanism  
with  
such packets. Otherwise, it will try all the servers every time. We use  
directive proxy\_next\_upstream off. If it’s not keepalive connection,  
everything is fine. If it’s keepalive connection, it will run such code:

2858 if (u-\>peer.cached && ft\_type == NGX\_HTTP\_UPSTREAM\_FT\_ERROR) {  
2859 status = 0;  
2860  
2861 /\* TODO: inform balancer instead \*/  
2862  
2863 u-\>peer.tries++;  
2864

The status is cleared to be 0. The below code will never be touched:

2896 if (status) {  
2897 u-\>state-\>status = status;  
2898  
2899 if (u-\>peer.tries == 0 || !(u-\>conf-\>next\_upstream &  
ft\_type))  
{

The variable of tries and u-\>conf-\>next\_upstream become useless.

I don’t know why the cached connection should clear the status, Can we  
just  
remove the code from line 2858 to 2864? Is there any side effect?

---

<div class="post-metadata">

**Author:** ![yaoweibin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/e9bcb4/32.png) [@yaoweibin](https://www.ruby-forum.com/u/yaoweibin)\
**Post date:** [January 14, 2013, 11:52am UTC](https://www.ruby-forum.com/t/a-problem-with-the-keepalive-module-and-the-direcitve-proxy-next-upstream/229438/2 "2013-01-14T11:52:01Z")

</div>

Hello!

On Mon, Jan 14, 2013 at 04:11:20PM +0800, 姚伟斌 wrote:

> directive proxy\_next\_upstream off. If it’s not keepalive connection,  
> The status is cleared to be 0. The below code will never be touched:  
> remove the code from line 2858 to 2864? Is there any side effect?  
> Cached connection might be (legitimately) closed by an upstream  
> server at any time, so the code always retries if sending request  
> failed.

–  
Maxim D.

> **[F5 NGINX: Built for cloud-native apps. Ready for AI traffic.](https://www.f5.com/products/nginx)**
>
> Deliver modern applications with NGINX. Explore high-performance load balancing, API gateways, and web server solutions trusted by top global enterprises.

---

<div class="post-metadata">

**Author:** ![yaoweibin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/e9bcb4/32.png) [@yaoweibin](https://www.ruby-forum.com/u/yaoweibin)\
**Post date:** [January 23, 2013, 7:25am UTC](https://www.ruby-forum.com/t/a-problem-with-the-keepalive-module-and-the-direcitve-proxy-next-upstream/229438/3 "2013-01-23T07:25:35Z")

</div>

Hi, Maxim,

I have removed the above code. It seems work for us and there is no side  
effect. And we have put it on our busy production boxes for a week.

This patch could make nginx honor the tries and u-\>conf-\>next\_upstream  
variable.

The patch is here:

diff --git a/src/http/ngx\_http\_upstream.c b/src/http/ngx\_http\_upstream.c  
index 842b634…0a0dfc3 100644  
— a/src/http/ngx\_http\_upstream.c  
+++ b/src/http/ngx\_http\_upstream.c  
@@ -2845,6 +2845,12 @@ ngx\_http\_upstream\_next(ngx\_http\_request\_t \*r,  
ngx\_http\_upstream\_t \*u,  
“upstream timed out”);  
}

+#if 0  
if (u-\>peer.cached && ft\_type == NGX\_HTTP\_UPSTREAM\_FT\_ERROR) {  
status = 0;

@@ -2853,6 +2859,7 @@ ngx\_http\_upstream\_next(ngx\_http\_request\_t \*r,  
ngx\_http\_upstream\_t \*u,  
u-\>peer.tries++;

```
 } else {

```

+#endif  
switch(ft\_type) {

```
     case NGX_HTTP_UPSTREAM_FT_TIMEOUT:

```

@@ -2875,7 +2882,9 @@ ngx\_http\_upstream\_next(ngx\_http\_request\_t \*r,  
ngx\_http\_upstream\_t \*u,  
default:  
status = NGX\_HTTP\_BAD\_GATEWAY;  
}  
+#if 0  
}  
+#endif

```
 if (r->connection->error) {
     ngx_http_upstream_finalize_request(r, u,

```

~

2013/1/14 Ҧΰ [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![yaoweibin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/e9bcb4/32.png) [@yaoweibin](https://www.ruby-forum.com/u/yaoweibin)\
**Post date:** [January 14, 2013, 3:14pm UTC](https://www.ruby-forum.com/t/a-problem-with-the-keepalive-module-and-the-direcitve-proxy-next-upstream/229438/4 "2013-01-14T15:14:46Z")

</div>

The nginx end will close the cacahed connection actively in this next  
upstream function. I don’t know why it should always _retry_ other  
server  
and don’t honor the tries and u-\>conf-\>next\_upstream variable.

Thanks.

2013/1/14 Maxim D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![yaoweibin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/e9bcb4/32.png) [@yaoweibin](https://www.ruby-forum.com/u/yaoweibin)\
**Post date:** [January 23, 2013, 11:42pm UTC](https://www.ruby-forum.com/t/a-problem-with-the-keepalive-module-and-the-direcitve-proxy-next-upstream/229438/5 "2013-01-23T23:42:12Z")

</div>

Hello!

On Wed, Jan 23, 2013 at 02:25:10PM +0800, 姚伟斌 wrote:

> I have removed the above code. It seems work for us and there is no side  
> effect. And we have put it on our busy production boxes for a week.

Just removing the code is wrong thing to do, as it will no longer  
able to retry if an upstream server closes connection at the same  
time when nginx decides to send a request into it, and there is  
only one upstream server configured in a given upstream block.

[…]

–  
Maxim D.

> **[F5 NGINX: Built for cloud-native apps. Ready for AI traffic.](https://www.f5.com/products/nginx)**
>
> Deliver modern applications with NGINX. Explore high-performance load balancing, API gateways, and web server solutions trusted by top global enterprises.
