# Upstream keepalive - call for testing

**URL:** <https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170>\
**Category:** NGINX\
**Created:** [August 1, 2011, 6:08pm UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170 "2011-08-01T18:08:30Z")\
**Posts on this page:** 14\
**Page:** 4

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [September 8, 2011, 1:34am UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/61 "2011-09-08T01:34:50Z")

</div>

Thanks for the all-included patch from 1.1.2

It seems that keepalive connections aren’t working in combination with  
proxy\_buffering off; (c-\>read-\>ready is set to 1)  
It worked before this last update, is this the intended behavior ?

Thank you,

Matthieu.

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [September 9, 2011, 12:05am UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/62 "2011-09-09T00:05:53Z")

</div>

On Thu, Sep 8, 2011 at 2:27 AM, Maxim D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Linux with epoll, right? Please try the following patch:

Yes, Linux with epoll.  
The patch below seems to fix the issue. Thank you Maxim!

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [September 15, 2011, 12:55am UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/63 "2011-09-15T00:55:12Z")

</div>

I have run the nginx 1.1.2 via this patch for 7 days, except for one  
days have a large DDoS so I restart nginx for several seconds, it was  
very stable to work.  
Handle about 70million request without problem happen, I think the last  
problem may be have a memory corruption, you are right.  
I will check that server when have times.  
Thanks for your hard work.

MagicBear

## Maxim D. Wrote:

> > (gdb) p ngx\_cycle-\>log  
> > improper handling  
> > for details:
> 
> [http://mailman.nginx.org/pipermail/nginx-devel/201](http://mailman.nginx.org/pipermail/nginx-devel/201)  
> 1-September/001147.html
> 
> Maxim D.
> 
> * * *
> 
> nginx mailing list  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [mailman.nginx.org archive](http://mailman.nginx.org/mailman/listinfo/nginx)

Posted at Nginx Forum:  
[http://forum.nginx.org/read.php?2,213207,215217#msg-215217](http://forum.nginx.org/read.php?2,213207,215217#msg-215217)

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [September 16, 2011, 3:42am UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/64 "2011-09-16T03:42:52Z")

</div>

wow, this + last-modified and etags would really cut into the reason  
people  
use varnish in their nginx + varnish setup.

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [September 15, 2011, 7:52pm UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/65 "2011-09-15T19:52:03Z")

</div>

Hello,  
I have wrote a module to make nginx support 304 to decrease bandwidth  
usage.  
note: I have a newbie for nginx module development, so the above module  
may  
have some problem. Welcome to test it and feedback another problem with  
me.

You can download full patch file from here:  
[http://m-b.cc/share/proxy\_304.txt](http://m-b.cc/share/proxy_304.txt)

# User MagicBear [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

Upstream:  
add $upstream\_last\_modified variant.  
add handler for 304 Unmodified.  
Proxy:  
change to send If-Modified-Since header.

TODO:  
change write TO not block IO.

diff -ruN a/http/modules/ngx\_http\_proxy\_module.c  
b/http/modules/ngx\_http\_proxy\_module.c  
— a/http/modules/ngx\_http\_proxy\_module.c 2011-09-15  
22:23:03.284431407 +0800  
+++ b/http/modules/ngx\_http\_proxy\_module.c 2011-09-16  
01:41:44.654428632 +0800  
@@ -543,7 +543,7 @@  
{ ngx\_string(“Connection”), ngx\_string(“close”) },  
{ ngx\_string(“Keep-Alive”), ngx\_string(“”) },  
{ ngx\_string(“Expect”), ngx\_string(“”) },

- { ngx\_string(“If-Modified-Since”), ngx\_string(“”) },

- { ngx\_string(“If-Modified-Since”),  
ngx\_string(“$upstream\_last\_modified”) },  
{ ngx\_string(“If-Unmodified-Since”), ngx\_string(“”) },  
{ ngx\_string(“If-None-Match”), ngx\_string(“”) },  
{ ngx\_string(“If-Match”), ngx\_string(“”) },  
diff -ruN a/http/ngx\_http\_upstream.c b/http/ngx\_http\_upstream.c  
— a/http/ngx\_http\_upstream.c 2011-09-15 22:23:03.284431407 +0800  
+++ b/http/ngx\_http\_upstream.c 2011-09-16 01:41:44.654428632 +0800  
@@ -16,6 +16,8 @@  
ngx\_http\_upstream\_t \*u);  
static ngx\_int\_t ngx\_http\_upstream\_cache\_status(ngx\_http\_request\_t \*r,  
ngx\_http\_variable\_value\_t \*v, uintptr\_t data);  
+static ngx\_int\_t ngx\_http\_upstream\_last\_modified(ngx\_http\_request\_t \*r,
- ngx\_http\_variable\_value\_t \*v, uintptr\_t data);  
#endif

static void ngx\_http\_upstream\_init\_request(ngx\_http\_request\_t \*r);  
@@ -342,6 +344,10 @@  
ngx\_http\_upstream\_cache\_status, 0,  
NGX\_HTTP\_VAR\_NOCACHEABLE, 0 },

- { ngx\_string(“upstream\_last\_modified”), NULL,
- 

```
 ngx_http_upstream_last_modified, 0,

```

- 

```
 NGX_HTTP_VAR_NOCACHEABLE, 0 },

```

- 

#endif

```
 { ngx_null_string, NULL, NULL, 0, 0, 0 }

```

@@ -1618,6 +1624,80 @@  
u-\>buffer.last = u-\>buffer.pos;  
}

+#if (NGX\_HTTP\_CACHE)  
+

- 

```
   if (u->cache_status == NGX_HTTP_CACHE_EXPIRED &&

```

- 

```
                  u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED 

```

&&

- 

```
                  ngx_http_file_cache_valid(u->conf->cache_valid,

```

u-\>headers\_in.status\_n))

- 

```
   {

```

- 

```
       ngx_int_t rc;

```

- 
- 

```
       rc = u->reinit_request(r);

```

- 
- 

```
       if (rc == NGX_OK) {

```

- 

```
           u->cache_status = NGX_HTTP_CACHE_BYPASS;

```

- 

```
           rc = ngx_http_upstream_cache_send(r, u);

```

- 
- 

```
                          time_t now, valid;

```

- 
- 

```
                          now = ngx_time();

```

- 
- 

```
                          valid = r->cache->valid_sec;

```

- 
- 

```
                          if (valid == 0) {

```

- 

```
                                  valid =

```

ngx\_http\_file\_cache\_valid(u-\>conf-\>cache\_valid,  
+  
u-\>headers\_in.status\_n);

- 

```
                                  if (valid) {

```

- 

```
                                          r->cache->valid_sec = 

```

now +  
valid;

- 

```
                                  }

```

- 

```
                          }

```

- 
- 

```
                          if (valid) {

```

- 

```
                                  r->cache->last_modified =

```

r-\>headers\_out.last\_modified\_time;

- 

```
                                  r->cache->date = now;

```

- 

```
                                  r->cache->body_start = (u_short)

```

(u-\>buffer.pos - u-\>buffer.start);  
+

- 

```
                                  // update Header

```

- 

ngx\_http\_file\_cache\_set\_header(r,  
u-\>buffer.start);  
+  
+  
ngx\_log\_debug1(NGX\_LOG\_DEBUG\_HTTP,  
r-\>connection-\>log, 0,  
+  
“update cache "%s" header to new expired.” ,  
r-\>cache-\>file.name.data);  
+

- 

```
                                  // Reopen file via RW

```

- 

```
                                  ngx_fd_t fd =

```

ngx\_open\_file(r-\>cache-\>file.name.data, NGX\_FILE\_RDWR, NGX\_FILE\_OPEN,  
0);  
+

- 

```
                                  if (fd == NGX_INVALID_FILE) {

```

- 

ngx\_log\_error(NGX\_LOG\_CRIT,  
r-\>connection-\>log, ngx\_errno,  
+  
ngx\_open\_file\_n " "%s" failed", r-\>cache-\>file.name.data);

- 

```
                                          return;

```

- 

```
                                  }

```

- 
- 

```
                                  // Write cache

```

- 

```
                                  if (write(fd, u->buffer.start,

```

sizeof(ngx\_http\_file\_cache\_header\_t)) \< 0)

- 

```
                                  {

```

- 

ngx\_log\_error(NGX\_LOG\_CRIT,  
r-\>connection-\>log, ngx\_errno,  
+  
“write proxy\_cache "%s" failed”, r-\>cache-\>file.name.data);

- 

```
                                          return;

```

- 

```
                                  }

```

- 
- 

```
                                  if (ngx_close_file(fd) ==

```

NGX\_FILE\_ERROR) {  
+  
ngx\_log\_error(NGX\_LOG\_ALERT,  
r-\>connection-\>log, ngx\_errno,  
+  
ngx\_close\_file\_n " "%s" failed", r-\>cache-\>file.name.data);

- 

```
                                  }

```

- 

ngx\_log\_debug1(NGX\_LOG\_DEBUG\_HTTP,  
r-\>connection-\>log, 0,  
+  
“update cache "%s" header to new expired done.” ,  
r-\>cache-\>file.name.data);

- 

```
                          } else {

```

- 

```
                                  u->cacheable = 0;

```

- 

r-\>headers\_out.last\_modified\_time =  
-1;

- 

```
                          }

```

- 

```
       }

```

- 
- 

```
       ngx_http_upstream_finalize_request(r, u, rc);

```

- 

```
       return;

```

- 

```
   }

```

- 

+#endif  
+  
if (ngx\_http\_upstream\_test\_next(r, u) == NGX\_OK) {  
return;  
}  
@@ -4006,6 +4086,32 @@

```
 return NGX_OK;

```

}  
+  
+ngx\_int\_t  
+ngx\_http\_upstream\_last\_modified(ngx\_http\_request\_t \*r,

- ngx\_http\_variable\_value\_t \*v, uintptr\_t data)  
+{
- u\_char \*u;
- 
- if (r-\>upstream == NULL || r-\>upstream-\>cache\_status == 0 ||  
r-\>cache==NULL || r-\>cache-\>last\_modified \<= 0) {
- 

```
   v->not_found = 1;

```

- 

```
   return NGX_OK;

```

- }
- 
- v-\>valid = 1;
- v-\>no\_cacheable = 0;
- v-\>not\_found = 0;
- 

```
  u = ngx_pcalloc(r->pool, 30);

```

- if (u == NULL) {
- 

```
   return NGX_ERROR;

```

- }
- 
- v-\>len = 29;
- 

```
  ngx_http_time(u, r->cache->last_modified);

```

- v-\>data = u;
- 
- return NGX\_OK;  
+}

#endif

MagicBear

2011/9/15 magicbear [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [December 29, 2011, 4:04pm UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/66 "2011-12-29T16:04:30Z")

</div>

Hello!

On Thu, Dec 29, 2011 at 07:47:21AM -0500, philipp wrote:

> any news here? Is the latest patch stable?

It’s in 1.1.x branch since 1.1.4.

Maxim D.

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [December 29, 2011, 1:47pm UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/67 "2011-12-29T13:47:47Z")

</div>

any news here? Is the latest patch stable?

Posted at Nginx Forum:

> **[Re: upstream keepalive - call for testing](https://forum.nginx.org/read.php?2,213207,220663#msg-220663)**
>
> Hello! JFYI: Last week I posted patch to nginx-devel@ which adds keepalive support to various backends (as with upstream keepalive module), including fastcgi and http backends (this in turn means nginx now able to talk HTTP/1.1 to backends, in...

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [March 8, 2012, 3:30pm UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/68 "2012-03-08T15:30:55Z")

</div>

Hi Maxim,  
when is it possible to use this module for a proxy server like keeping  
the connection persistent for proxy\_pass “[http://google.com](http://google.com)”; ?

Br.,  
Alex.

Posted at Nginx Forum:

> **[Re: upstream keepalive - call for testing](https://forum.nginx.org/read.php?2,213207,223633#msg-223633)**
>
> Hello! JFYI: Last week I posted patch to nginx-devel@ which adds keepalive support to various backends (as with upstream keepalive module), including fastcgi and http backends (this in turn means nginx now able to talk HTTP/1.1 to backends, in...

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [March 9, 2012, 7:19am UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/69 "2012-03-09T07:19:01Z")

</div>

Alex,

It’s been several months since it got integrated into the main branch,  
check the docs  
[http://nginx.org/en/docs/http/ngx\_http\_upstream\_module.html#keepalive](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive)

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [March 12, 2012, 3:35pm UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/70 "2012-03-12T15:35:21Z")

</div>

Ahh, sorry for my stupidity!!

Anyway - the patches that’s attached to this topic - are they patched in  
the devel release of nginx as well?  
Also can the module support HTTP connections currently?

Br.,  
Alex.

Posted at Nginx Forum:

> **[Re: upstream keepalive - call for testing](https://forum.nginx.org/read.php?2,213207,223759#msg-223759)**
>
> Hello! JFYI: Last week I posted patch to nginx-devel@ which adds keepalive support to various backends (as with upstream keepalive module), including fastcgi and http backends (this in turn means nginx now able to talk HTTP/1.1 to backends, in...

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [March 12, 2012, 6:40pm UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/71 "2012-03-12T18:40:46Z")

</div>

Hi Maxim,  
thank you very much.

What would you suggest to set keepalive connections to, if I’m going to  
keep a persistent connection to a remote website, with Nginx being setup  
as a proxy caching server?

Br.,  
Alex.

Posted at Nginx Forum:

> **[Re: upstream keepalive - call for testing](https://forum.nginx.org/read.php?2,213207,223767#msg-223767)**
>
> Hello! JFYI: Last week I posted patch to nginx-devel@ which adds keepalive support to various backends (as with upstream keepalive module), including fastcgi and http backends (this in turn means nginx now able to talk HTTP/1.1 to backends, in...

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [March 12, 2012, 3:54pm UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/72 "2012-03-12T15:54:39Z")

</div>

Hello!

On Mon, Mar 12, 2012 at 10:35:03AM -0400, alexscott wrote:

> Ahh, sorry for my stupidity!!
> 
> Anyway - the patches that’s attached to this topic - are they patched in  
> the devel release of nginx as well?  
> Also can the module support HTTP connections currently?

The patches and the upstream keepalive module are included in  
1.1.x, instructions how configure nginx to use persistent  
connections with upstream servers are available here:

> **[Module ngx\_http\_upstream\_module](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive)**
>
> The ngx\_http\_upstream\_module module is used to define groups of servers that can be referenced by the proxy\_pass, fastcgi\_pass, uwsgi\_pass, scgi\_pass, memcached\_pass, and grpc\_pass directives.

Maxim D.

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [March 12, 2012, 8:56pm UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/73 "2012-03-12T20:56:08Z")

</div>

The upstream server is able to handle all requests if necessary. So will  
you still suggest keepalive 1; for such a config or do you have any  
other ideas as well?

Posted at Nginx Forum:

> **[Re: upstream keepalive - call for testing](https://forum.nginx.org/read.php?2,213207,223772#msg-223772)**
>
> Hello! JFYI: Last week I posted patch to nginx-devel@ which adds keepalive support to various backends (as with upstream keepalive module), including fastcgi and http backends (this in turn means nginx now able to talk HTTP/1.1 to backends, in...

---

<div class="post-metadata">

**Author:** ![Maxim\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/da6949/32.png) [@Maxim\_D](https://www.ruby-forum.com/u/Maxim_D)\
**Post date:** [March 12, 2012, 7:00pm UTC](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170/74 "2012-03-12T19:00:08Z")

</div>

Hello!

On Mon, Mar 12, 2012 at 01:40:17PM -0400, alexscott wrote:

> Hi Maxim,  
> thank you very much.
> 
> What would you suggest to set keepalive connections to, if I’m going to  
> keep a persistent connection to a remote website, with Nginx being setup  
> as a proxy caching server?

This depends on expected load and a number of connections upstream  
server is able to handle. Usually

```
keepalive 1;

```

is a good starting point.

Maxim D.

[Previous page](https://www.ruby-forum.com/t/upstream-keepalive-call-for-testing/210170.md?page=3)
