jk_lb_worker.c
来自「以便Apache与其他服务进行整合 Mod_JK安装」· C语言 代码 · 共 1,498 行 · 第 1/4 页
C
1,498 行
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//*************************************************************************** * Description: Load balancer worker, knows how to load balance among * * several workers. * * Author: Gal Shachor <shachor@il.ibm.com> * * Author: Mladen Turk <mturk@apache.org> * * Author: Rainer Jung <rjung@apache.org> * * Based on: * * Version: $Revision: 562194 $ * ***************************************************************************/#include "jk_pool.h"#include "jk_service.h"#include "jk_util.h"#include "jk_worker.h"#include "jk_lb_worker.h"#include "jk_ajp13.h"#include "jk_ajp13_worker.h"#include "jk_ajp14_worker.h"#include "jk_mt.h"#include "jk_shm.h"/* * The load balancing code in this */#define JK_WORKER_USABLE(w) ((w)->state != JK_LB_STATE_ERROR && (w)->state != JK_LB_STATE_PROBE && (w)->state != JK_LB_STATE_BUSY && (w)->activation != JK_LB_ACTIVATION_STOPPED && (w)->activation != JK_LB_ACTIVATION_DISABLED)#define JK_WORKER_USABLE_STICKY(w) ((w)->state != JK_LB_STATE_ERROR && (w)->state != JK_LB_STATE_PROBE && (w)->activation != JK_LB_ACTIVATION_STOPPED)static const char *lb_locking_type[] = { JK_LB_LOCK_TEXT_OPTIMISTIC, JK_LB_LOCK_TEXT_PESSIMISTIC, "unknown", NULL};static const char *lb_method_type[] = { JK_LB_METHOD_TEXT_REQUESTS, JK_LB_METHOD_TEXT_TRAFFIC, JK_LB_METHOD_TEXT_BUSYNESS, JK_LB_METHOD_TEXT_SESSIONS, "unknown", NULL};static const char *lb_state_type[] = { JK_LB_STATE_TEXT_IDLE, JK_LB_STATE_TEXT_OK, JK_LB_STATE_TEXT_RECOVER, JK_LB_STATE_TEXT_BUSY, JK_LB_STATE_TEXT_ERROR, JK_LB_STATE_TEXT_FORCE, JK_LB_STATE_TEXT_PROBE, "unknown", NULL};static const char *lb_activation_type[] = { JK_LB_ACTIVATION_TEXT_ACTIVE, JK_LB_ACTIVATION_TEXT_DISABLED, JK_LB_ACTIVATION_TEXT_STOPPED, "unknown", NULL};static const char *lb_first_log_names[] = { JK_NOTE_LB_FIRST_NAME, JK_NOTE_LB_FIRST_VALUE, JK_NOTE_LB_FIRST_ACCESSED, JK_NOTE_LB_FIRST_READ, JK_NOTE_LB_FIRST_TRANSFERRED, JK_NOTE_LB_FIRST_ERRORS, JK_NOTE_LB_FIRST_BUSY, JK_NOTE_LB_FIRST_ACTIVATION, JK_NOTE_LB_FIRST_STATE, NULL};static const char *lb_last_log_names[] = { JK_NOTE_LB_LAST_NAME, JK_NOTE_LB_LAST_VALUE, JK_NOTE_LB_LAST_ACCESSED, JK_NOTE_LB_LAST_READ, JK_NOTE_LB_LAST_TRANSFERRED, JK_NOTE_LB_LAST_ERRORS, JK_NOTE_LB_LAST_BUSY, JK_NOTE_LB_LAST_ACTIVATION, JK_NOTE_LB_LAST_STATE, NULL};struct lb_endpoint{ lb_worker_t *worker; jk_endpoint_t endpoint;};typedef struct lb_endpoint lb_endpoint_t;/* Calculate the greatest common divisor of two positive integers */static jk_uint64_t gcd(jk_uint64_t a, jk_uint64_t b){ jk_uint64_t r; if (b > a) { r = a; a = b; b = r; } while (b > 0) { r = a % b; a = b; b = r; } return a;}/* Calculate the smallest common multiple of two positive integers */static jk_uint64_t scm(jk_uint64_t a, jk_uint64_t b){ return a * b / gcd(a, b);}/* Return the string representation of the lb lock type */const char *jk_lb_get_lock(lb_worker_t *p, jk_logger_t *l){ return lb_locking_type[p->lblock];}/* Return the int representation of the lb lock type */int jk_lb_get_lock_code(const char *v){ if (!v) return JK_LB_LOCK_DEF; else if (*v == 'o' || *v == 'O' || *v == '0') return JK_LB_LOCK_OPTIMISTIC; else if (*v == 'p' || *v == 'P' || *v == '1') return JK_LB_LOCK_PESSIMISTIC; else return JK_LB_LOCK_DEF;}/* Return the string representation of the lb method type */const char *jk_lb_get_method(lb_worker_t *p, jk_logger_t *l){ return lb_method_type[p->lbmethod];}/* Return the int representation of the lb lock type */int jk_lb_get_method_code(const char *v){ if (!v) return JK_LB_METHOD_DEF; else if (*v == 'r' || *v == 'R' || *v == '0') return JK_LB_METHOD_REQUESTS; else if (*v == 't' || *v == 'T' || *v == '1') return JK_LB_METHOD_TRAFFIC; else if (*v == 'b' || *v == 'B' || *v == '2') return JK_LB_METHOD_BUSYNESS; else if (*v == 's' || *v == 'S' || *v == '3') return JK_LB_METHOD_SESSIONS; else return JK_LB_METHOD_DEF;}/* Return the string representation of the balance worker state */const char *jk_lb_get_state(worker_record_t *p, jk_logger_t *l){ return lb_state_type[p->s->state];}/* Return the int representation of the lb lock type */int jk_lb_get_state_code(const char *v){ if (!v) return JK_LB_STATE_DEF; else if (*v == 'i' || *v == 'I' || *v == 'n' || *v == 'N' || *v == '0') return JK_LB_STATE_IDLE; else if (*v == 'o' || *v == 'O' || *v == '1') return JK_LB_STATE_OK; else if (*v == 'r' || *v == 'R' || *v == '2') return JK_LB_STATE_RECOVER; else if (*v == 'b' || *v == 'B' || *v == '3') return JK_LB_STATE_BUSY; else if (*v == 'e' || *v == 'E' || *v == '4') return JK_LB_STATE_ERROR; else if (*v == 'f' || *v == 'F' || *v == '5') return JK_LB_STATE_FORCE; else if (*v == 'p' || *v == 'P' || *v == '6') return JK_LB_STATE_PROBE; else return JK_LB_STATE_DEF;}/* Return the string representation of the balance worker activation */const char *jk_lb_get_activation(worker_record_t *p, jk_logger_t *l){ return lb_activation_type[p->s->activation];}int jk_lb_get_activation_code(const char *v){ if (!v) return JK_LB_ACTIVATION_DEF; else if (*v == 'a' || *v == 'A' || *v == '0') return JK_LB_ACTIVATION_ACTIVE; else if (*v == 'd' || *v == 'D' || *v == '1') return JK_LB_ACTIVATION_DISABLED; else if (*v == 's' || *v == 'S' || *v == '2') return JK_LB_ACTIVATION_STOPPED; else return JK_LB_ACTIVATION_DEF;}/* Update the load multipliers wrt. lb_factor */void update_mult(lb_worker_t *p, jk_logger_t *l){ unsigned int i = 0; jk_uint64_t s = 1; JK_TRACE_ENTER(l); for (i = 0; i < p->num_of_workers; i++) { s = scm(s, p->lb_workers[i].s->lb_factor); } for (i = 0; i < p->num_of_workers; i++) { p->lb_workers[i].s->lb_mult = s / p->lb_workers[i].s->lb_factor; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s gets multiplicity %" JK_UINT64_T_FMT, p->lb_workers[i].s->name, p->lb_workers[i].s->lb_mult); } JK_TRACE_EXIT(l);}/* Reset all lb values. */void reset_lb_values(lb_worker_t *p, jk_logger_t *l){ unsigned int i = 0; JK_TRACE_ENTER(l); if (p->lbmethod != JK_LB_METHOD_BUSYNESS) { for (i = 0; i < p->num_of_workers; i++) { 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); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "syncing mem for lb '%s' from shm", p->s->name); 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->max_reply_timeouts = p->s->max_reply_timeouts; 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); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "syncing shm for lb '%s' from mem", p->s->name); 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->max_reply_timeouts = p->max_reply_timeouts; 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 */static char *get_path_param(jk_ws_service_t *s, const char *name){ char *id_start = NULL; for (id_start = strstr(s->req_uri, name); id_start; id_start = strstr(id_start + 1, name)) { if (id_start[strlen(name)] == '=') { /* * Session path-cookie was found, get it's value */ id_start += (1 + strlen(name)); if (strlen(id_start)) { char *id_end; id_start = jk_pool_strdup(s->pool, id_start); /* * The query string is not part of req_uri, however * to be on the safe side lets remove the trailing query * string if appended... */ if ((id_end = strchr(id_start, '?')) != NULL) { *id_end = '\0'; } /* * Remove any trailing path element. */ if ((id_end = strchr(id_start, ';')) != NULL) { *id_end = '\0'; } return id_start; } } } return NULL;}/* Retrieve the cookie with the given name */static char *get_cookie(jk_ws_service_t *s, const char *name){ unsigned i; char *result = NULL; for (i = 0; i < s->num_headers; i++) { if (strcasecmp(s->headers_names[i], "cookie") == 0) { char *id_start; for (id_start = strstr(s->headers_values[i], name); id_start; id_start = strstr(id_start + 1, name)) { if (id_start == s->headers_values[i] || id_start[-1] == ';' || id_start[-1] == ',' || isspace((int)id_start[-1])) { id_start += strlen(name); while (*id_start && isspace((int)(*id_start))) ++id_start; if (*id_start == '=' && id_start[1]) { /* * Session cookie was found, get it's value */ char *id_end; ++id_start; id_start = jk_pool_strdup(s->pool, id_start); if ((id_end = strchr(id_start, ';')) != NULL) { *id_end = '\0'; } if ((id_end = strchr(id_start, ',')) != NULL) { *id_end = '\0'; } if (result == NULL) { result = id_start; } else { size_t osz = strlen(result) + 1; size_t sz = osz + strlen(id_start) + 1; result =
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?