o procedimento é muito simples.
o processador tem um queue ( fila de espera) de processos, o principio logico é se deixarmos a fila de espera crescer muito , vai ficar de tal maneira atulhado que vai acabar por se ir abaixo.
a maquina unix guarda num ficheiro
/proc/loadavg
o numero de processos em espera.
por exempolo neste momento fazendo cat /proc/loadavg obtenho isto:
0.97 1.08 3.44 1/169 302
significa que no ultimo minuto tivemos em media 0.97 processos em espera
nos ultimos 5 minutos a media foi de 1.08 e nos ultimos 15 foi de 3.44
bom se cada vez que o servidor receb um pedido olhar para o primeiro valor fica a saber se a maquina esta muito ocupada.
assim o que ele faz é olhar para o primeiro valor e se for superior a 60 não aceita mais pedidos ate ter tudo despachado e manda o erro ou http 503 .
para os mais curiosos :
/*
Instructions :
==============
Install : apxs -i -a -c mod_load.c
Configure : MaxLoad apache directive (default is 25)
Apache 2.0 version :
--------------------
Copyright (C) 2005
Planet-Work SARL
http://www.planet-work.fr/
Frederic VANNIERE -
f.vanniere@planet-work.com
Original Apache 1.3 version :
-----------------------------
Copyright (C) 2000,2001,2002,2003
SedNove Inc.
439 OAK
St-Lambert, QC, Canada
All rights reserved.
Pierre Laplante
Wed Nov 20 15:53:45 2002
Pierre.Laplante@sednove.com
*/
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include "http_main.h"
#include "util_script.h"
#include "util_md5.h"
#include "ap_config.h"
#include "unistd.h"
/*#define DEBUGLVL 9*/
#ifdef DEBUGLVL
#define DEBUG(lvl,x...) if (lvl<DEBUGLVL) fprintf(stderr, x);
#else
#define DEBUG(lvl,x...)
#endif
module AP_MODULE_DECLARE_DATA load_module;
typedef struct {
int max_load;
} load_handler_config;
static void *
create_config(apr_pool_t *p, server_rec *s) {
load_handler_config *c;
DEBUG(5, "create_config\n");
c = (load_handler_config *) apr_pcalloc(p, sizeof(load_handler_config));
c -> max_load = 25;
DEBUG(5, "create_config c=%x.\n", c);
return (void *) c;
}
static const char *
my_handler(cmd_parms *parms, void *mconfig, char *to) {
load_handler_config *c;
DEBUG(5, "my_handler, to=%s, mconfig=%x, parms=%x/%x\n", to, mconfig, parms, parms);
c = (load_handler_config *) ap_get_module_config(parms->server->module_config,
&load_module);
DEBUG(5, "c=%x\n", c);
c -> max_load = atoi(to);
return NULL;
}
static const command_rec load_cmds[] =
{
AP_INIT_TAKE1("MaxLoad",my_handler,(void*) 0,RSRC_CONF,"Set max Loadavg." ),
{NULL}
};
static int load_handler(request_rec *r) {
int fd;
float la;
char buf[1024];
load_handler_config *c;
DEBUG(5, "load_handler\n");
c = (load_handler_config *) ap_get_module_config(r->server->module_config,
&load_module);
DEBUG(5, "c=%x\n", c);
DEBUG(5, "load = %d \n", c -> max_load);
fd = open("/proc/loadavg", O_RDONLY);
if (read(fd, buf, 1024) <=0) {
//ap_log_reason("Can't open /proc/loadavg", "/proc/loadavg", r);
ap_log_error(APLOG_MARK, APLOG_ERR,0,NULL, "Can't open /proc/loadavg");
return DECLINED;
} else {
sscanf(buf, "%f", &la);
if (la > c -> max_load) {
ap_log_error(APLOG_MARK, APLOG_ERR,0,NULL,
"load is too high %f/%d ...\n", la, c->max_load);
return HTTP_SERVICE_UNAVAILABLE;
}
}
close(fd);
return DECLINED;
}
static void
load_register_hooks (apr_pool_t * p)
{
ap_hook_access_checker(load_handler,NULL,NULL,APR_HOOK_FIRST);
}
module AP_MODULE_DECLARE_DATA load_module =
{
STANDARD20_MODULE_STUFF,
NULL, /* per-directory config creator */
NULL, /* dir config merger */
create_config, /* server config creator */
NULL, /* server config merger */
load_cmds, /* command table */
load_register_hooks
};