httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matt Stevenson <mavricknzw...@yahoo.com>
Subject proxy_ajp connect timeout fix.
Date Wed, 08 Oct 2008 20:55:43 GMT
Hi,

I've used mod_jk (1/2) for years. I've always had an issue when a backend server goes down,
not tomcat/jboss stopped but dead. Recently some people I work with have been using mod_proxy
and mod_proxy_ajp. This seems to have the same issue.

The code (proxy_util.c) assumes that apr_socket_timeout_set works for all connects. I don't
believe it does, not unless it is in non blocking mode. I wrote the code below for"ap_proxy_connect_backend"
before I looked deeper into the apr libs (sorry its not in diff format, and for the hard 2
sec timeout). The code seems to work fine for linux (and probably other unix). I've basically
redone the apr code in apr_wait_for_io_or_timeout (should have dug deeper first).

Anyway the current release code doesn't seem to work for me for down boxes (to test point
an ajp proxy at a non existant IP on the network and a live server). I think if you put the
socket in non-blocking mode first and with a timeout apr will try to handle a connect timeout
(I haven't had a chance to try), switch back to non blocking after connect.

Regards
Matt

 
if (worker->keepalive) {
            if ((rv =  apr_socket_opt_set(newsock,
                            APR_SO_KEEPALIVE, 1))  != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv,  s,
                             "apr_socket_opt_set(SO_KEEPALIVE): Failed to  set"
                             " Keepalive");
            }
         }
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                      "proxy: %s: fam %d socket created to connect to %s",
                      proxy_function, backend_addr->family, worker->hostname);
 
        apr_socket_opt_set(newsock,  APR_SO_NONBLOCK, 1);
        apr_socket_timeout_set(newsock, 0);
 
        rv = apr_socket_connect(newsock,  backend_addr);
        if( rv != APR_SUCCESS &&  APR_STATUS_IS_EINPROGRESS(rv)){
 
            apr_pollfd_t pfds[1];
             apr_status_t status;
            apr_int32_t  nfds;
 

            pfds[0].reqevents = APR_POLLOUT;
             pfds[0].desc_type = APR_POLL_SOCKET;
            pfds[0].desc.s =  newsock;
 
            rv = apr_poll(&pfds[0], 1, &nfds,  apr_time_from_sec(2));
        }
 
        /* if an error occurred, loop round and try again */
        if  (rv != APR_SUCCESS) {
            apr_socket_close(newsock);
             loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
             ap_log_error(APLOG_MARK, loglevel, rv, s,
                         "proxy:  %s: attempt to connect to %pI (%s) failed",
                          proxy_function,
                          backend_addr,
                         worker->hostname);
             backend_addr = backend_addr->next;
            continue;
         }
 
        apr_socket_opt_set(newsock, APR_SO_NONBLOCK, 0);
 
        /* Set a timeout on the socket */


      

Mime
View raw message