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

📄 mod_proxy_balancer.c

📁 apache服务器源代码(版本号:2.2.2)
💻 C
📖 第 1 页 / 共 3 页
字号:
    char *route = NULL;    apr_status_t rv;    *worker = NULL;    /* Step 1: check if the url is for us     * The url we can handle starts with 'balancer://'     * If balancer is already provided skip the search     * for balancer, because this is failover attempt.     */    if (!*balancer &&        !(*balancer = ap_proxy_get_balancer(r->pool, conf, *url)))        return DECLINED;    /* Step 2: find the session route */    runtime = find_session_route(*balancer, r, &route, url);    /* Lock the LoadBalancer     * XXX: perhaps we need the process lock here     */    if ((rv = PROXY_THREAD_LOCK(*balancer)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,                     "proxy: BALANCER: lock");        return DECLINED;    }    if (runtime) {        int i, total_factor = 0;        proxy_worker *workers;        /* We have a sticky load balancer         * Update the workers status         * so that even session routes get         * into account.         */        workers = (proxy_worker *)(*balancer)->workers->elts;        for (i = 0; i < (*balancer)->workers->nelts; i++) {            /* Take into calculation only the workers that are             * not in error state or not disabled.             */            if (PROXY_WORKER_IS_USABLE(workers)) {                workers->s->lbstatus += workers->s->lbfactor;                total_factor += workers->s->lbfactor;            }            workers++;        }        runtime->s->lbstatus -= total_factor;        runtime->s->elected++;        *worker = runtime;    }    else if (route && (*balancer)->sticky_force) {        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,                     "proxy: BALANCER: (%s). All workers are in error state for route (%s)",                     (*balancer)->name, route);        PROXY_THREAD_UNLOCK(*balancer);        return HTTP_SERVICE_UNAVAILABLE;    }    PROXY_THREAD_UNLOCK(*balancer);    if (!*worker) {        runtime = find_best_worker(*balancer, r);        if (!runtime) {            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,                         "proxy: BALANCER: (%s). All workers are in error state",                         (*balancer)->name);            return HTTP_SERVICE_UNAVAILABLE;        }        *worker = runtime;    }    /* Rewrite the url from 'balancer://url'     * to the 'worker_scheme://worker_hostname[:worker_port]/url'     * This replaces the balancers fictional name with the     * real hostname of the elected worker.     */    access_status = rewrite_url(r, *worker, url);    /* Add the session route to request notes if present */    if (route) {        apr_table_setn(r->notes, "session-sticky", (*balancer)->sticky);        apr_table_setn(r->notes, "session-route", route);    }    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                 "proxy: BALANCER (%s) worker (%s) rewritten to %s",                 (*balancer)->name, (*worker)->name, *url);    return access_status;}static int proxy_balancer_post_request(proxy_worker *worker,                                       proxy_balancer *balancer,                                       request_rec *r,                                       proxy_server_conf *conf){    apr_status_t rv;    if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,            "proxy: BALANCER: lock");        return HTTP_INTERNAL_SERVER_ERROR;    }    /* TODO: calculate the bytes transferred     * This will enable to elect the worker that has     * the lowest load.     * The bytes transferred depends on the protocol     * used, so each protocol handler should keep the     * track on that.     */    PROXY_THREAD_UNLOCK(balancer);    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                 "proxy_balancer_post_request for (%s)", balancer->name);    return OK;}static void recalc_factors(proxy_balancer *balancer){    int i;    proxy_worker *workers;    /* Recalculate lbfactors */    workers = (proxy_worker *)balancer->workers->elts;    /* Special case if there is only one worker it's     * load factor will always be 1     */    if (balancer->workers->nelts == 1) {        workers->s->lbstatus = workers->s->lbfactor = 1;        return;    }    for (i = 0; i < balancer->workers->nelts; i++) {        /* Update the status entries */        workers[i].s->lbstatus = workers[i].s->lbfactor;    }}/* Manages the loadfactors and member status */static int balancer_handler(request_rec *r){    void *sconf = r->server->module_config;    proxy_server_conf *conf = (proxy_server_conf *)        ap_get_module_config(sconf, &proxy_module);    proxy_balancer *balancer, *bsel = NULL;    proxy_worker *worker, *wsel = NULL;    apr_table_t *params = apr_table_make(r->pool, 10);    int access_status;    int i, n;    const char *name;    /* is this for us? */    if (strcmp(r->handler, "balancer-manager"))        return DECLINED;    r->allowed = (AP_METHOD_BIT << M_GET);    if (r->method_number != M_GET)        return DECLINED;    if (r->args) {        char *args = apr_pstrdup(r->pool, r->args);        char *tok, *val;        while (args && *args) {            if ((val = ap_strchr(args, '='))) {                *val++ = '\0';                if ((tok = ap_strchr(val, '&')))                    *tok++ = '\0';                /*                 * Special case: workers are allowed path information                 */                if ((access_status = ap_unescape_url(val)) != OK)                    if (strcmp(args, "w") || (access_status !=  HTTP_NOT_FOUND))                        return access_status;                apr_table_setn(params, args, val);                args = tok;            }            else                return HTTP_BAD_REQUEST;        }    }    if ((name = apr_table_get(params, "b")))        bsel = ap_proxy_get_balancer(r->pool, conf,            apr_pstrcat(r->pool, "balancer://", name, NULL));    if ((name = apr_table_get(params, "w"))) {        proxy_worker *ws;        ws = ap_proxy_get_worker(r->pool, conf, name);        if (ws) {            worker = (proxy_worker *)bsel->workers->elts;            for (n = 0; n < bsel->workers->nelts; n++) {                if (strcasecmp(worker->name, ws->name) == 0) {                    wsel = worker;                    break;                }                ++worker;            }        }    }    /* First set the params */    if (bsel) {        const char *val;        if ((val = apr_table_get(params, "ss"))) {            if (strlen(val))                bsel->sticky = apr_pstrdup(conf->pool, val);            else                bsel->sticky = NULL;        }        if ((val = apr_table_get(params, "tm"))) {            int ival = atoi(val);            if (ival >= 0)                bsel->timeout = apr_time_from_sec(ival);        }        if ((val = apr_table_get(params, "fa"))) {            int ival = atoi(val);            if (ival >= 0)                bsel->max_attempts = ival;            bsel->max_attempts_set = 1;        }        if ((val = apr_table_get(params, "lm"))) {            proxy_balancer_method *provider;            provider = ap_lookup_provider(PROXY_LBMETHOD, val, "0");            if (provider) {                bsel->lbmethod = provider;            }        }    }    if (wsel) {        const char *val;        if ((val = apr_table_get(params, "lf"))) {            int ival = atoi(val);            if (ival >= 1 && ival <= 100) {                wsel->s->lbfactor = ival;                if (bsel)                    recalc_factors(bsel);            }        }        if ((val = apr_table_get(params, "wr"))) {            if (strlen(val) && strlen(val) < PROXY_WORKER_MAX_ROUTE_SIZ)                strcpy(wsel->s->route, val);            else                *wsel->s->route = '\0';        }        if ((val = apr_table_get(params, "rr"))) {            if (strlen(val) && strlen(val) < PROXY_WORKER_MAX_ROUTE_SIZ)                strcpy(wsel->s->redirect, val);            else                *wsel->s->redirect = '\0';        }        if ((val = apr_table_get(params, "dw"))) {            if (!strcasecmp(val, "Disable"))                wsel->s->status |= PROXY_WORKER_DISABLED;            else if (!strcasecmp(val, "Enable"))                wsel->s->status &= ~PROXY_WORKER_DISABLED;        }    }    if (apr_table_get(params, "xml")) {        ap_set_content_type(r, "text/xml");        ap_rputs("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n", r);        ap_rputs("<httpd:manager xmlns:httpd=\"http://httpd.apache.org\">\n", r);        ap_rputs("  <httpd:balancers>\n", r);        balancer = (proxy_balancer *)conf->balancers->elts;        for (i = 0; i < conf->balancers->nelts; i++) {            ap_rputs("    <httpd:balancer>\n", r);            ap_rvputs(r, "      <httpd:name>", balancer->name, "</httpd:name>\n", NULL);            ap_rputs("      <httpd:workers>\n", r);            worker = (proxy_worker *)balancer->workers->elts;            for (n = 0; n < balancer->workers->nelts; n++) {                ap_rputs("        <httpd:worker>\n", r);                ap_rvputs(r, "          <httpd:scheme>", worker->scheme,                          "</httpd:scheme>\n", NULL);                ap_rvputs(r, "          <httpd:hostname>", worker->hostname,                          "</httpd:hostname>\n", NULL);               ap_rprintf(r, "          <httpd:loadfactor>%d</httpd:loadfactor>\n",                          worker->s->lbfactor);                ap_rputs("        </httpd:worker>\n", r);                ++worker;            }            ap_rputs("      </httpd:workers>\n", r);            ap_rputs("    </httpd:balancer>\n", r);            ++balancer;        }        ap_rputs("  </httpd:balancers>\n", r);        ap_rputs("</httpd:manager>", r);    }    else {        ap_set_content_type(r, "text/html");        ap_rputs(DOCTYPE_HTML_3_2                 "<html><head><title>Balancer Manager</title></head>\n", r);        ap_rputs("<body><h1>Load Balancer Manager for ", r);        ap_rvputs(r, ap_get_server_name(r), "</h1>\n\n", NULL);        ap_rvputs(r, "<dl><dt>Server Version: ",                  ap_get_server_version(), "</dt>\n", NULL);        ap_rvputs(r, "<dt>Server Built: ",                  ap_get_server_built(), "\n</dt></dl>\n", NULL);        balancer = (proxy_balancer *)conf->balancers->elts;        for (i = 0; i < conf->balancers->nelts; i++) {            ap_rputs("<hr />\n<h3>LoadBalancer Status for ", r);            ap_rvputs(r, "<a href=\"", r->uri, "?b=",                      balancer->name + sizeof("balancer://") - 1,                      "\">", NULL);            ap_rvputs(r, balancer->name, "</a></h3>\n\n", NULL);            ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>"                "<th>StickySession</th><th>Timeout</th><th>FailoverAttempts</th><th>Method</th>"                "</tr>\n<tr>", r);            ap_rvputs(r, "<td>", balancer->sticky, NULL);            ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>",                apr_time_sec(balancer->timeout));            ap_rprintf(r, "<td>%d</td>\n", balancer->max_attempts);            ap_rprintf(r, "<td>%s</td>\n",                       balancer->lbmethod->name);            ap_rputs("</table>\n<br />", r);            ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>"                "<th>Worker URL</th>"                "<th>Route</th><th>RouteRedir</th>"                "<th>Factor</th><th>Status</th>"                "</tr>\n", r);

⌨️ 快捷键说明

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