jk_lb_worker.c

来自「Tomcat 4.1与WebServer集成组件的源代码包.」· C语言 代码 · 共 627 行 · 第 1/2 页

C
627
字号
/* ========================================================================= * *                                                                           * *                 The Apache Software License,  Version 1.1                 * *                                                                           * *          Copyright (c) 1999-2001 The Apache Software Foundation.          * *                           All rights reserved.                            * *                                                                           * * ========================================================================= * *                                                                           * * Redistribution and use in source and binary forms,  with or without modi- * * fication, are permitted provided that the following conditions are met:   * *                                                                           * * 1. Redistributions of source code  must retain the above copyright notice * *    notice, this list of conditions and the following disclaimer.          * *                                                                           * * 2. Redistributions  in binary  form  must  reproduce the  above copyright * *    notice,  this list of conditions  and the following  disclaimer in the * *    documentation and/or other materials provided with the distribution.   * *                                                                           * * 3. The end-user documentation  included with the redistribution,  if any, * *    must include the following acknowlegement:                             * *                                                                           * *       "This product includes  software developed  by the Apache  Software * *        Foundation <http://www.apache.org/>."                              * *                                                                           * *    Alternately, this acknowlegement may appear in the software itself, if * *    and wherever such third-party acknowlegements normally appear.         * *                                                                           * * 4. The names  "The  Jakarta  Project",  "Jk",  and  "Apache  Software     * *    Foundation"  must not be used  to endorse or promote  products derived * *    from this  software without  prior  written  permission.  For  written * *    permission, please contact <apache@apache.org>.                        * *                                                                           * * 5. Products derived from this software may not be called "Apache" nor may * *    "Apache" appear in their names without prior written permission of the * *    Apache Software Foundation.                                            * *                                                                           * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES * * INCLUDING, BUT NOT LIMITED TO,  THE IMPLIED WARRANTIES OF MERCHANTABILITY * * AND FITNESS FOR  A PARTICULAR PURPOSE  ARE DISCLAIMED.  IN NO EVENT SHALL * * THE APACHE  SOFTWARE  FOUNDATION OR  ITS CONTRIBUTORS  BE LIABLE  FOR ANY * * DIRECT,  INDIRECT,   INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL * * DAMAGES (INCLUDING,  BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE GOODS * * OR SERVICES;  LOSS OF USE,  DATA,  OR PROFITS;  OR BUSINESS INTERRUPTION) * * HOWEVER CAUSED AND  ON ANY  THEORY  OF  LIABILITY,  WHETHER IN  CONTRACT, * * STRICT LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF  ADVISED  OF THE * * POSSIBILITY OF SUCH DAMAGE.                                               * *                                                                           * * ========================================================================= * *                                                                           * * This software  consists of voluntary  contributions made  by many indivi- * * duals on behalf of the  Apache Software Foundation.  For more information * * on the Apache Software Foundation, please see <http://www.apache.org/>.   * *                                                                           * * ========================================================================= *//*************************************************************************** * Description: Load balancer worker, knows how to load balance among      * *              several workers.                                           * * Author:      Gal Shachor <shachor@il.ibm.com>                           * * Based on:                                                               * * Version:     $Revision: 1.12 $                                           * ***************************************************************************/#include "jk_pool.h"#include "jk_service.h"#include "jk_util.h"#include "jk_worker.h"#include "jk_lb_worker.h"/* * The load balancing code in this  *//*  * Time to wait before retry... */#define WAIT_BEFORE_RECOVER (60*1) #define ADDITINAL_WAIT_LOAD (20)struct worker_record {    char    *name;    double  lb_factor;    double  lb_value;    int     is_local_worker;    int     in_error_state;    int     in_recovering;    time_t  error_time;    jk_worker_t *w;};typedef struct worker_record worker_record_t;struct lb_worker {    worker_record_t *lb_workers;    unsigned num_of_workers;    jk_pool_t p;    jk_pool_atom_t buf[TINY_POOL_SIZE];    char *name;     jk_worker_t worker;    int  in_local_worker_mode;    int  local_worker_only;    int  sticky_session;};typedef struct lb_worker lb_worker_t;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, '?')) {                     *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;    for(i = 0 ; i < s->num_headers ; i++) {        if(0 == strcasecmp(s->headers_names[i], "cookie")) {            char *id_start;            for(id_start = strstr(s->headers_values[i], name) ;                 id_start ;                 id_start = strstr(id_start + 1, name)) {                if('=' == id_start[strlen(name)]) {                    /*                     * Session 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);                        if(id_end = strchr(id_start, ';')) {                            *id_end = '\0';                        }                        return id_start;                    }                }            }        }    }    return NULL;}/* ========================================================================= *//* 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 char *get_session_route(jk_ws_service_t *s){    char *sessionid = get_sessionid(s);    char *ch;    if(!sessionid) {        return NULL;    }    /*     * Balance parameter is appended to the end     */      ch = strrchr(sessionid, '.');    if(!ch) {        return 0;    }    ch++;    if(*ch == '\0') {        return NULL;    }    return ch;}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 double get_max_lb(lb_worker_t *p) {    unsigned i;    double rc = 0.0;        for(i = 0 ; i < p->num_of_workers ; i++) {        if(!p->lb_workers[i].in_error_state) {            if(p->lb_workers[i].lb_value > rc) {                rc = p->lb_workers[i].lb_value;            }        }                }    return rc;}static worker_record_t *get_most_suitable_worker(lb_worker_t *p,                                                  jk_ws_service_t *s, int attempt){    worker_record_t *rc = NULL;    double lb_min = 0.0;        unsigned i;    char *session_route = NULL;    if (p->sticky_session) {        session_route = get_session_route(s);    }    if(session_route) {        for(i = 0 ; i < p->num_of_workers ; i++) {            if(0 == strcmp(session_route, p->lb_workers[i].name)) {                /* First attempt will allways be to the                   correct host. If this is indeed down and no                   hope of recovery, we'll go to fail-over                */                if(attempt>0 && p->lb_workers[i].in_error_state) {                   break;                } else {                    return &(p->lb_workers[i]);                }            }        }    }    for(i = 0 ; i < p->num_of_workers ; i++) {        if (!p->in_local_worker_mode || p->lb_workers[i].is_local_worker || !p->local_worker_only) {            if(p->lb_workers[i].in_error_state) {                if(!p->lb_workers[i].in_recovering) {                    time_t now = time(0);                    if((now - p->lb_workers[i].error_time) > WAIT_BEFORE_RECOVER) {                        p->lb_workers[i].in_recovering  = JK_TRUE;                        p->lb_workers[i].error_time     = now;                        rc = &(p->lb_workers[i]);                            break;                    }                }            } else {                if(p->lb_workers[i].lb_value < lb_min || !rc) {                    lb_min = p->lb_workers[i].lb_value;                    rc = &(p->lb_workers[i]);                    if (rc->is_local_worker) break;                }            }        }    }    if(rc && !rc->is_local_worker) {        rc->lb_value += rc->lb_factor;                    }    return rc;}    static int JK_METHOD service(jk_endpoint_t *e,                              jk_ws_service_t *s,                             jk_logger_t *l,                             int *is_recoverable_error){

⌨️ 快捷键说明

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