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 */