⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jk_lb_worker.c

📁 jboss与apache集成的中间件,详情请参看文档说明.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  Copyright 1999-2004 The Apache Software Foundation * *  Licensed 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>                             * * Based on:                                                               * * Version:     $Revision: 1.91 $                                          * ***************************************************************************/#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 *//* * Time to wait before retry... */#define JK_WORKER_IN_ERROR(w) ((w)->in_error_state  && !(w)->is_disabled && !(w)->is_busy)#define JK_WORKER_USABLE(w)   (!(w)->in_error_state && !(w)->is_stopped && !(w)->is_disabled && !(w)->is_busy)struct lb_endpoint{    jk_endpoint_t *e;    lb_worker_t *worker;    jk_endpoint_t endpoint;};typedef struct lb_endpoint lb_endpoint_t;/* 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(id_start[-1])) {                    id_start += strlen(name);                    while (*id_start && isspace(*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 {                            int osz = strlen(result) + 1;                            int sz = osz + strlen(id_start) + 1;                            result =                                jk_pool_realloc(s->pool, sz, result, osz);                            strcat(result, ";");                            strcat(result, id_start);                        }                    }                }            }        }    }    return result;}/* Retrieve session id from the cookie or the parameter                      *//* (parameter first)                                                         */static char *get_sessionid(jk_ws_service_t *s){    char *val;    val = get_path_param(s, JK_PATH_SESSION_IDENTIFIER);    if (!val) {        val = get_cookie(s, JK_SESSION_IDENTIFIER);    }    return val;}static void close_workers(lb_worker_t * p, int num_of_workers, jk_logger_t *l){    int i = 0;    for (i = 0; i < num_of_workers; i++) {        p->lb_workers[i].w->destroy(&(p->lb_workers[i].w), l);    }}static int JK_METHOD maintain_workers(jk_worker_t *p, jk_logger_t *l){    unsigned int i = 0;    lb_worker_t *lb = (lb_worker_t *)p->worker_private;    for (i = 0; i < lb->num_of_workers; i++) {        if (lb->lb_workers[i].w->maintain) {            lb->lb_workers[i].w->maintain(lb->lb_workers[i].w, l);        }    }    return JK_TRUE;}static void retry_worker(worker_record_t *w,                         int recover_wait_time,                         jk_logger_t *l){    int elapsed = (int)difftime(time(NULL), w->s->error_time);    JK_TRACE_ENTER(l);    if (elapsed <= recover_wait_time) {        if (JK_IS_DEBUG_LEVEL(l))            jk_log(l, JK_LOG_DEBUG,                    "worker %s will recover in %d seconds",                    w->s->name, recover_wait_time - elapsed);    }    else {        if (JK_IS_DEBUG_LEVEL(l))            jk_log(l, JK_LOG_DEBUG,                    "worker %s is marked for recover",                    w->s->name);        w->s->in_recovering  = JK_TRUE;        w->s->in_error_state = JK_FALSE;        w->s->is_busy = JK_FALSE;    }    JK_TRACE_EXIT(l);}static worker_record_t *find_by_session(lb_worker_t *p,                                        const char *name,                                        jk_logger_t *l){    worker_record_t *rc = NULL;    unsigned int i;    for (i = 0; i < p->num_of_workers; i++) {        if (strcmp(p->lb_workers[i].s->name, name) == 0) {            rc = &p->lb_workers[i];            rc->r = &(rc->s->name[0]);            break;        }    }    return rc;}static worker_record_t *find_best_bydomain(lb_worker_t *p,                                           const char *domain,                                           jk_logger_t *l){    unsigned int i;    int total_factor = 0;    jk_u64_t mytraffic = 0;    jk_u64_t curmin = 0;    worker_record_t *candidate = NULL;    if (p->lblock == JK_LB_LOCK_PESSIMISTIC)        jk_shm_lock();    /* First try to see if we have available candidate */    for (i = 0; i < p->num_of_workers; i++) {        /* Skip all workers that are not member of domain */        if (strlen(p->lb_workers[i].s->domain) == 0 ||            strcmp(p->lb_workers[i].s->domain, domain))            continue;        /* Take into calculation only the workers that are         * not in error state, stopped or not disabled.         */        if (JK_WORKER_USABLE(p->lb_workers[i].s)) {            if (p->lbmethod == JK_LB_BYREQUESTS) {                p->lb_workers[i].s->lb_value += p->lb_workers[i].s->lb_factor;                total_factor += p->lb_workers[i].s->lb_factor;                if (!candidate || p->lb_workers[i].s->lb_value > candidate->s->lb_value)                    candidate = &p->lb_workers[i];            }            else {                mytraffic = (p->lb_workers[i].s->transferred/p->lb_workers[i].s->lb_factor) +                            (p->lb_workers[i].s->readed/p->lb_workers[i].s->lb_factor);                if (!candidate || mytraffic < curmin) {                    candidate = &p->lb_workers[i];                    curmin = mytraffic;                }            }        }            }    if (candidate) {        if (p->lbmethod == JK_LB_BYREQUESTS)            candidate->s->lb_value -= total_factor;        candidate->r = &(candidate->s->domain[0]);    }    if (p->lblock == JK_LB_LOCK_PESSIMISTIC)        jk_shm_unlock();    return candidate;}static worker_record_t *find_best_byrequests(lb_worker_t *p,                                             jk_logger_t *l){    unsigned int i;    int total_factor = 0;    worker_record_t *candidate = NULL;    if (p->lblock == JK_LB_LOCK_PESSIMISTIC)        jk_shm_lock();    /* First try to see if we have available candidate */    for (i = 0; i < p->num_of_workers; i++) {        /* If the worker is in error state run         * retry on that worker. It will be marked as         * operational if the retry timeout is elapsed.         * The worker might still be unusable, but we try         * anyway.         */        if (JK_WORKER_IN_ERROR(p->lb_workers[i].s)) {            retry_worker(&p->lb_workers[i], p->s->recover_wait_time, l);        }        /* Take into calculation only the workers that are         * not in error state, stopped or not disabled.         */        if (JK_WORKER_USABLE(p->lb_workers[i].s)) {            p->lb_workers[i].s->lb_value += p->lb_workers[i].s->lb_factor;            total_factor += p->lb_workers[i].s->lb_factor;            if (!candidate || p->lb_workers[i].s->lb_value > candidate->s->lb_value)                candidate = &p->lb_workers[i];        }    }    if (candidate)        candidate->s->lb_value -= total_factor;    if (p->lblock == JK_LB_LOCK_PESSIMISTIC)        jk_shm_unlock();    return candidate;}static worker_record_t *find_best_bytraffic(lb_worker_t *p,                                             jk_logger_t *l){    unsigned int i;    jk_u64_t mytraffic = 0;    jk_u64_t curmin = 0;    worker_record_t *candidate = NULL;    if (p->lblock == JK_LB_LOCK_PESSIMISTIC)        jk_shm_lock();    /* First try to see if we have available candidate */    for (i = 0; i < p->num_of_workers; i++) {        /* If the worker is in error state run

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -