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 + -
显示快捷键?