Upstream keepalive - call for testing

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.

On Thu, Sep 8, 2011 at 2:27 AM, Maxim D. [email protected] 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!

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
1-September/001147.html

Maxim D.


nginx mailing list
[email protected]
nginx Info Page

Posted at Nginx Forum:

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

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

User MagicBear [email protected]

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 [email protected]

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.

any news here? Is the latest patch stable?

Posted at Nginx Forum:

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”; ?

Br.,
Alex.

Posted at Nginx Forum:

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

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:

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:

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:

http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive

Maxim D.

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:

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.