Author: rjung Date: Thu Nov 23 18:13:59 2006 New Revision: 478746 URL: http://svn.apache.org/viewvc?view=rev&rev=478746 Log: Adding locking strategy and balancing method as manageable to the status worker. Since the shm worker gets longer and longer, and since it contains quite a few members, which are read mostly, I started to keep copies of the read mostly members which belong to the lb in the lb worker. A sequence number indicated, if the local copies have to be updated from shm.
Modified: tomcat/connectors/trunk/jk/native/common/jk_lb_worker.c tomcat/connectors/trunk/jk/native/common/jk_lb_worker.h tomcat/connectors/trunk/jk/native/common/jk_shm.h tomcat/connectors/trunk/jk/native/common/jk_status.c Modified: tomcat/connectors/trunk/jk/native/common/jk_lb_worker.c URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_lb_worker.c?view=diff&rev=478746&r1=478745&r2=478746 ============================================================================== --- tomcat/connectors/trunk/jk/native/common/jk_lb_worker.c (original) +++ tomcat/connectors/trunk/jk/native/common/jk_lb_worker.c Thu Nov 23 18:13:59 2006 @@ -166,6 +166,33 @@ p->lb_workers[i].s->lb_value = 0; } } + JK_TRACE_EXIT(l); +} + +/* Syncing config values from shm */ +void jk_lb_pull(lb_worker_t * p, jk_logger_t *l) { + JK_TRACE_ENTER(l); + p->sticky_session = p->s->sticky_session; + p->sticky_session_force = p->s->sticky_session_force; + p->recover_wait_time = p->s->recover_wait_time; + p->retries = p->s->retries; + p->lbmethod = p->s->lbmethod; + p->lblock = p->s->lblock; + p->sequence = p->s->sequence; + JK_TRACE_EXIT(l); +} + +/* Syncing config values from shm */ +void jk_lb_push(lb_worker_t * p, jk_logger_t *l) { + JK_TRACE_ENTER(l); + p->s->sticky_session = p->sticky_session; + p->s->sticky_session_force = p->sticky_session_force; + p->s->recover_wait_time = p->recover_wait_time; + p->s->retries = p->retries; + p->s->lbmethod = p->lbmethod; + p->s->lblock = p->lblock; + p->s->sequence = p->sequence; + JK_TRACE_EXIT(l); } /* Retrieve the parameter with the given name */ @@ -541,7 +568,7 @@ * balancer. Of course you will need a some kind of * session replication between those two remote. */ - if (p->s->sticky_session_force) + if (p->sticky_session_force) candidate = NULL; else if (*candidate->s->redirect) candidate = find_by_session(p, candidate->s->redirect, l); @@ -665,7 +692,7 @@ sessionid = next; rc = NULL; } - if (!rc && p->s->sticky_session_force) { + if (!rc && p->sticky_session_force) { if (p->lblock == JK_LB_LOCK_PESSIMISTIC) jk_shm_unlock(); else { @@ -727,7 +754,13 @@ jk_b_set_buffer_size(s->reco_buf, p->worker->max_packet_size); jk_b_reset(s->reco_buf); s->reco_status = RECO_INITED; - if (p->worker->s->sticky_session) { + + jk_shm_lock(); + if (p->worker->sequence != p->worker->s->sequence) + jk_lb_pull(p->worker, l); + jk_shm_unlock(); + + if (p->worker->sticky_session) { /* Use sessionid only if sticky_session is * defined for this load balancer */ @@ -736,7 +769,7 @@ if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "service sticky_session=%d id='%s'", - p->worker->s->sticky_session, sessionid ? sessionid : "empty"); + p->worker->sticky_session, sessionid ? sessionid : "empty"); while (attempt <= num_of_workers && rc == -1) { worker_record_t *rec = @@ -798,6 +831,8 @@ if (p->worker->s->busy > p->worker->s->max_busy) p->worker->s->max_busy = p->worker->s->busy; rec->s->busy++; + if (rec->s->busy > rec->s->max_busy) + rec->s->max_busy = rec->s->busy; if (p->worker->lbmethod == JK_LB_METHOD_REQUESTS) rec->s->lb_value += rec->s->lb_mult; else if (p->worker->lbmethod == JK_LB_METHOD_SESSIONS && @@ -805,8 +840,6 @@ rec->s->lb_value += rec->s->lb_mult; else if (p->worker->lbmethod == JK_LB_METHOD_BUSYNESS) rec->s->lb_value += rec->s->lb_mult; - if (rec->s->busy > rec->s->max_busy) - rec->s->max_busy = rec->s->busy; if (p->worker->lblock == JK_LB_LOCK_PESSIMISTIC) jk_shm_unlock(); @@ -1084,8 +1117,8 @@ unsigned int num_of_workers; const char *secret; - p->s->sticky_session = jk_get_is_sticky_session(props, p->s->name); - p->s->sticky_session_force = jk_get_is_sticky_session_force(props, p->s->name); + p->sticky_session = jk_get_is_sticky_session(props, p->s->name); + p->sticky_session_force = jk_get_is_sticky_session_force(props, p->s->name); secret = jk_get_worker_secret(props, p->s->name); if (jk_get_lb_worker_list(props, @@ -1113,16 +1146,9 @@ } } - /* Calculate the maximum packet size from all workers - * for the recovery buffer. - */ - for (i = 0; i < num_of_workers; i++) { - unsigned int ms = jk_get_max_packet_size(props, worker_names[i]); - if (ms > p->max_packet_size) - p->max_packet_size = ms; - } for (i = 0; i < num_of_workers; i++) { const char *s; + unsigned int ms; strncpy(p->lb_workers[i].s->name, worker_names[i], JK_SHM_STR_SIZ); p->lb_workers[i].s->lb_factor = @@ -1130,6 +1156,12 @@ if (p->lb_workers[i].s->lb_factor < 1) { p->lb_workers[i].s->lb_factor = 1; } + /* Calculate the maximum packet size from all workers + * for the recovery buffer. + */ + ms = jk_get_max_packet_size(props, worker_names[i]); + if (ms > p->max_packet_size) + p->max_packet_size = ms; p->lb_workers[i].s->distance = jk_get_distance(props, worker_names[i]); if ((s = jk_get_worker_jvm_route(props, worker_names[i], NULL))) @@ -1216,12 +1248,14 @@ pThis->retries = jk_get_worker_retries(props, p->s->name, JK_RETRIES); - p->s->retries = pThis->retries; - p->s->recover_wait_time = jk_get_worker_recover_timeout(props, p->s->name, + p->retries = pThis->retries; + p->recover_wait_time = jk_get_worker_recover_timeout(props, p->s->name, WAIT_BEFORE_RECOVER); - if (p->s->recover_wait_time < 1) - p->s->recover_wait_time = 1; + if (p->recover_wait_time < 1) + p->recover_wait_time = 1; p->maintain_time = jk_get_worker_maintain_time(props); + if(p->maintain_time < 0) + p->maintain_time = 0; p->s->last_maintain_time = time(NULL); p->lbmethod = jk_get_lb_method(props, p->s->name); @@ -1236,6 +1270,11 @@ return JK_FALSE; } + jk_shm_lock(); + p->sequence++; + jk_lb_push(p, log); + jk_shm_unlock(); + JK_TRACE_EXIT(log); return JK_TRUE; } @@ -1317,7 +1356,8 @@ private_data->worker.destroy = destroy; private_data->worker.maintain = maintain_workers; private_data->worker.retries = JK_RETRIES; - private_data->s->recover_wait_time = WAIT_BEFORE_RECOVER; + private_data->recover_wait_time = WAIT_BEFORE_RECOVER; + private_data->sequence = 0; *w = &private_data->worker; JK_TRACE_EXIT(l); return JK_LB_WORKER_TYPE; Modified: tomcat/connectors/trunk/jk/native/common/jk_lb_worker.h URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_lb_worker.h?view=diff&rev=478746&r1=478745&r2=478746 ============================================================================== --- tomcat/connectors/trunk/jk/native/common/jk_lb_worker.h (original) +++ tomcat/connectors/trunk/jk/native/common/jk_lb_worker.h Thu Nov 23 18:13:59 2006 @@ -44,6 +44,7 @@ #define JK_LB_METHOD_BUSYNESS (3) #define JK_LB_METHOD_SESSIONS (4) #define JK_LB_METHOD_DEF (JK_LB_METHOD_REQUESTS) +#define JK_LB_METHOD_MAX (JK_LB_METHOD_SESSIONS) #define JK_LB_METHOD_TEXT_REQUESTS ("Request") #define JK_LB_METHOD_TEXT_TRAFFIC ("Traffic") #define JK_LB_METHOD_TEXT_BUSYNESS ("Busyness") @@ -52,6 +53,7 @@ #define JK_LB_LOCK_OPTIMISTIC (1) #define JK_LB_LOCK_PESSIMISTIC (2) #define JK_LB_LOCK_DEF (JK_LB_LOCK_OPTIMISTIC) +#define JK_LB_LOCK_MAX (JK_LB_LOCK_PESSIMISTIC) #define JK_LB_LOCK_TEXT_OPTIMISTIC ("Optimistic") #define JK_LB_LOCK_TEXT_PESSIMISTIC ("Pessimistic") #define JK_LB_LOCK_TEXT_DEF (JK_LB_LOCK_TEXT_OPTIMISTIC) @@ -120,10 +122,16 @@ { worker_record_t *lb_workers; unsigned int num_of_workers; + char name[JK_SHM_STR_SIZ+1]; + int sticky_session; + int sticky_session_force; + int recover_wait_time; + int retries; int lbmethod; int lblock; time_t maintain_time; unsigned int max_packet_size; + unsigned int sequence; jk_pool_t p; jk_pool_atom_t buf[TINY_POOL_SIZE]; @@ -144,6 +152,8 @@ const char *jk_lb_get_state(worker_record_t *p, jk_logger_t *l); const char *jk_lb_get_activation(worker_record_t *p, jk_logger_t *l); void reset_lb_values(lb_worker_t *p, jk_logger_t *l); +void jk_lb_pull(lb_worker_t * p, jk_logger_t *l); +void jk_lb_push(lb_worker_t * p, jk_logger_t *l); void update_mult(lb_worker_t * p, jk_logger_t *l); #ifdef __cplusplus Modified: tomcat/connectors/trunk/jk/native/common/jk_shm.h URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_shm.h?view=diff&rev=478746&r1=478745&r2=478746 ============================================================================== --- tomcat/connectors/trunk/jk/native/common/jk_shm.h (original) +++ tomcat/connectors/trunk/jk/native/common/jk_shm.h Thu Nov 23 18:13:59 2006 @@ -59,6 +59,10 @@ struct jk_shm_worker { int id; + /* Sequence counter starting at 0 and increasing + * every time we change the config + */ + unsigned int sequence; /* Number of currently busy channels */ volatile int busy; /* Maximum number of busy channels */ @@ -89,6 +93,9 @@ int sticky_session_force; int recover_wait_time; int retries; + int lbmethod; + int lblock; + unsigned int max_packet_size; /* Statistical data */ volatile time_t error_time; /* Service transfer rate time */ Modified: tomcat/connectors/trunk/jk/native/common/jk_status.c URL: http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_status.c?view=diff&rev=478746&r1=478745&r2=478746 ============================================================================== --- tomcat/connectors/trunk/jk/native/common/jk_status.c (original) +++ tomcat/connectors/trunk/jk/native/common/jk_status.c Thu Nov 23 18:13:59 2006 @@ -407,6 +407,12 @@ if (lb != NULL) { unsigned int j; int selected = -1; + + jk_shm_lock(); + if (lb->sequence != lb->s->sequence) + jk_lb_pull(lb, l); + jk_shm_unlock(); + jk_puts(s, "<table><tr>" "<th>Type</th><th>Sticky session</th>" "<th>Force Sticky session</th>" @@ -416,15 +422,23 @@ "<th>Recovery timeout</th>" "</tr>\n<tr>"); jk_putv(s, "<td>", status_worker_type(w->type), "</td>", NULL); - jk_putv(s, "<td>", status_val_bool(lb->s->sticky_session), + jk_putv(s, "<td>", status_val_bool(lb->sticky_session), "</td>", NULL); - jk_putv(s, "<td>", status_val_bool(lb->s->sticky_session_force), + jk_putv(s, "<td>", status_val_bool(lb->sticky_session_force), "</td>", NULL); - jk_printf(s, "<td>%d</td>", lb->s->retries); + jk_printf(s, "<td>%d</td>", lb->retries); jk_printf(s, "<td>%s</td>", jk_lb_get_method(lb, l)); jk_printf(s, "<td>%s</td>", jk_lb_get_lock(lb, l)); - jk_printf(s, "<td>%d</td>", lb->s->recover_wait_time); + jk_printf(s, "<td>%d</td>", lb->recover_wait_time); jk_puts(s, "</tr>\n</table>\n<br/>\n"); + + jk_puts(s, "<table><tr>" + "<th>Busy</th><th>Max Busy</th>" + "</tr>\n<tr>"); + jk_printf(s, "<td>%d</td>", lb->s->busy); + jk_printf(s, "<td>%d</td>", lb->s->max_busy); + jk_puts(s, "</tr>\n</table>\n<br/>\n"); + jk_puts(s, "<table><tr>" "<th>Name</th><th>Type</th><th>jvmRoute</th><th>Host</th><th>Addr</th>" "<th>Act</th><th>Stat</th><th>D</th><th>F</th><th>M</th><th>V</th><th>Acc</th><th>Err</th><th>CE</th>" @@ -490,8 +504,6 @@ jk_puts(s, "value=\"update\">\n"); jk_puts(s, "<input type=\"hidden\" name=\"w\" "); jk_putv(s, "value=\"", wr->s->name, "\">\n", NULL); - jk_puts(s, "<input type=\"hidden\" name=\"id\" "); - jk_printf(s, "value=\"%u\">\n", selected); jk_puts(s, "<input type=\"hidden\" name=\"lb\" "); jk_printf(s, "value=\"%u\">\n", i); @@ -539,19 +551,49 @@ jk_puts(s, "value=\"update\"/>\n"); jk_puts(s, "<input type=\"hidden\" name=\"w\" "); jk_putv(s, "value=\"", dworker, "\"/>\n", NULL); - jk_puts(s, "<input type=\"hidden\" name=\"id\" "); - jk_printf(s, "value=\"%u\"/>\n", i); jk_puts(s, "<table>\n<tr><td>Retries:</td><td><input name=\"lr\" type=\"text\" "); - jk_printf(s, "value=\"%d\"/></td></tr>\n", lb->s->retries); + jk_printf(s, "value=\"%d\"/></td></tr>\n", lb->retries); jk_puts(s, "<tr><td>Recover time:</td><td><input name=\"lt\" type=\"text\" "); - jk_printf(s, "value=\"%d\"/></td></tr>\n", lb->s->recover_wait_time); + jk_printf(s, "value=\"%d\"/></td></tr>\n", lb->recover_wait_time); jk_puts(s, "<tr><td>Sticky session:</td><td><input name=\"ls\" type=\"checkbox\""); - if (lb->s->sticky_session) + if (lb->sticky_session) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/></td></tr>\n"); jk_puts(s, "<tr><td>Force Sticky session:</td><td><input name=\"lf\" type=\"checkbox\""); - if (lb->s->sticky_session_force) + if (lb->sticky_session_force) + jk_puts(s, " checked=\"checked\""); + jk_puts(s, "/></td></tr>\n"); + jk_puts(s, "<tr><td>Method:</td><td></td></tr>\n"); + jk_puts(s, "<tr><td> Requests</td><td><input name=\"lm\" type=\"radio\""); + jk_printf(s, " value=\"%d\"", JK_LB_METHOD_REQUESTS); + if (lb->lbmethod == JK_LB_METHOD_REQUESTS) + jk_puts(s, " checked=\"checked\""); + jk_puts(s, "/></td></tr>\n"); + jk_puts(s, "<tr><td> Traffic</td><td><input name=\"lm\" type=\"radio\""); + jk_printf(s, " value=\"%d\"", JK_LB_METHOD_TRAFFIC); + if (lb->lbmethod == JK_LB_METHOD_TRAFFIC) + jk_puts(s, " checked=\"checked\""); + jk_puts(s, "/></td></tr>\n"); + jk_puts(s, "<tr><td> Busyness</td><td><input name=\"lm\" type=\"radio\""); + jk_printf(s, " value=\"%d\"", JK_LB_METHOD_BUSYNESS); + if (lb->lbmethod == JK_LB_METHOD_BUSYNESS) + jk_puts(s, " checked=\"checked\""); + jk_puts(s, "/></td></tr>\n"); + jk_puts(s, "<tr><td> Sessions</td><td><input name=\"lm\" type=\"radio\""); + jk_printf(s, " value=\"%d\"", JK_LB_METHOD_SESSIONS); + if (lb->lbmethod == JK_LB_METHOD_SESSIONS) + jk_puts(s, " checked=\"checked\""); + jk_puts(s, "/></td></tr>\n"); + jk_puts(s, "<tr><td>Locking:</td><td></td></tr>\n"); + jk_puts(s, "<tr><td> Optimistic</td><td><input name=\"ll\" type=\"radio\""); + jk_printf(s, " value=\"%d\"", JK_LB_LOCK_OPTIMISTIC); + if (lb->lblock == JK_LB_LOCK_OPTIMISTIC) + jk_puts(s, " checked=\"checked\""); + jk_puts(s, "/></td></tr>\n"); + jk_puts(s, "<tr><td> Pessimistic</td><td><input name=\"ll\" type=\"radio\""); + jk_printf(s, " value=\"%d\"", JK_LB_LOCK_PESSIMISTIC); + if (lb->lblock == JK_LB_LOCK_PESSIMISTIC) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/></td></tr>\n"); jk_puts(s, "</table>\n"); @@ -636,14 +678,24 @@ /* Skip non lb workers */ continue; } - jk_printf(s, " <jk:balancer id=\"%d\" name=\"%s\" type=\"%s\" sticky=\"%s\" stickyforce=\"%s\" retries=\"%d\" recover=\"%d\" >\n", + + jk_shm_lock(); + if (lb->sequence != lb->s->sequence) + jk_lb_pull(lb, l); + jk_shm_unlock(); + + jk_printf(s, " <jk:balancer id=\"%d\" name=\"%s\" type=\"%s\" sticky=\"%s\" stickyforce=\"%s\" retries=\"%d\" recover=\"%d\" method=\"%s\" lock=\"%s\" busy=\"%d\" max_busy=\"%d\">\n", i, lb->s->name, status_worker_type(w->type), - status_val_bool(lb->s->sticky_session), - status_val_bool(lb->s->sticky_session_force), - lb->s->retries, - lb->s->recover_wait_time); + status_val_bool(lb->sticky_session), + status_val_bool(lb->sticky_session_force), + lb->retries, + lb->recover_wait_time, + jk_lb_get_lock(lb, l), + jk_lb_get_method(lb, l), + lb->s->busy, + lb->s->max_busy); for (j = 0; j < lb->num_of_workers; j++) { worker_record_t *wr = &(lb->lb_workers[j]); ajp_worker_t *a = (ajp_worker_t *)wr->w->worker_private; @@ -697,15 +749,27 @@ if (w && w->type == JK_LB_WORKER_TYPE) { lb = (lb_worker_t *)w->worker_private; - i = status_int("lr", s->query_string, lb->s->retries); + + if (lb->sequence != lb->s->sequence) + jk_lb_pull(lb, l); + + i = status_int("lr", s->query_string, lb->retries); if (i > 0) - lb->s->retries = i; - i = status_int("lt", s->query_string, lb->s->recover_wait_time); + lb->retries = i; + i = status_int("lt", s->query_string, lb->recover_wait_time); if (i < 1) i = 1; - lb->s->recover_wait_time = i; - lb->s->sticky_session = status_bool("ls", s->query_string, lb->s->sticky_session); - lb->s->sticky_session_force = status_bool("lf", s->query_string, lb->s->sticky_session_force); + lb->recover_wait_time = i; + lb->sticky_session = status_bool("ls", s->query_string, lb->sticky_session); + lb->sticky_session_force = status_bool("lf", s->query_string, lb->sticky_session_force); + i = status_int("lm", s->query_string, lb->lbmethod); + if (i > 0 && i <= JK_LB_METHOD_MAX) + lb->lbmethod = i; + i = status_int("ll", s->query_string, lb->lblock); + if (i > 0 && i <= JK_LB_LOCK_MAX) + lb->lblock = i; + lb->sequence++; + jk_lb_push(lb, l); } else { int n = status_int("lb", s->query_string, -1); @@ -721,18 +785,13 @@ if (!w || w->type != JK_LB_WORKER_TYPE) return; lb = (lb_worker_t *)w->worker_private; - i = status_int("id", s->query_string, -1); - if (i >= 0 && i < (int)lb->num_of_workers) - wr = &(lb->lb_workers[i]); - else { - for (i = 0; i < (int)lb->num_of_workers; i++) { - if (strcmp(dworker, lb->lb_workers[i].s->name) == 0) { - wr = &(lb->lb_workers[i]); - break; - } + for (i = 0; i < (int)lb->num_of_workers; i++) { + if (strcmp(dworker, lb->lb_workers[i].s->name) == 0) { + wr = &(lb->lb_workers[i]); + break; } } - if (!wr) + if (!wr || i == (int)lb->num_of_workers) return; a = (ajp_worker_t *)wr->w->worker_private; @@ -780,9 +839,9 @@ if (w && w->type == JK_LB_WORKER_TYPE) { lb = (lb_worker_t *)w->worker_private; + lb->s->max_busy = 0; for (i = 0; i < lb->num_of_workers; i++) { worker_record_t *wr = &(lb->lb_workers[i]); - wr->s->busy = 0; wr->s->client_errors = 0; wr->s->elected = 0; wr->s->elected_snapshot = 0; @@ -803,15 +862,15 @@ { char cmdtype[32]; if (!req) - return 0; + return 0; if (status_cmd("cmd", req, cmdtype, sizeof(cmdtype)) != NULL) { - if (!strncmp(cmdtype, "list", strlen("list"))) + if (!strncmp(cmdtype, "list", strlen("list"))) return 0; - else if (!strncmp(cmdtype, "show", strlen("show"))) + else if (!strncmp(cmdtype, "show", strlen("show"))) return 1; - else if (!strncmp(cmdtype, "update", strlen("update"))) + else if (!strncmp(cmdtype, "update", strlen("update"))) return 2; - else if (!strncmp(cmdtype, "reset", strlen("reset"))) + else if (!strncmp(cmdtype, "reset", strlen("reset"))) return 3; } return 0; --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]