我想编写一个FastCGI应用程序,它应该使用线程处理多个同时请求.我看一下SDK附带的threaded.c示例:
#define THREAD_COUNT 20 static int counts[THREAD_COUNT]; static void *doit(void *a) { int rc, i, thread_id = (int)a; pid_t pid = getpid(); FCGX_Request request; char *server_name; FCGX_InitRequest(&request, 0, 0); for (;;) { static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t counts_mutex = PTHREAD_MUTEX_INITIALIZER; /* Some platforms require accept() serialization, some don't.. */ pthread_mutex_lock(&accept_mutex); rc = FCGX_Accept_r(&request); pthread_mutex_unlock(&accept_mutex); if (rc < 0) break; server_name = FCGX_GetParam("SERVER_NAME", request.envp); FCGX_FPrintF(request.out,… … FCGX_Finish_r(&request); } return NULL; } int main(void) { int i; pthread_t id[THREAD_COUNT]; FCGX_Init(); for (i = 1; i < THREAD_COUNT; i++) pthread_create(&id[i], NULL, doit, (void*)i); doit(0); return 0; }
在FastCGI规范中有一个解释,Web服务器将如何确定FastCGI应用程序支持的连接数:
Web服务器可以查询应用程序中的特定变量.服务器通常会在应用程序启动时执行查询,以便自动化系统配置的某些方面.
...
•FCGI_MAX_CONNS:此应用程序将接受的最大并发传输连接数,例如"1"或"10".
•FCGI_MAX_REQS:此应用程序将接受的最大并发请求数,例如"1"或"50".
•FCGI_MPXS_CONNS:如果此应用程序不复用连接(即处理每个连接上的并发请求),则为"0",否则为"1".
但是此查询的返回值被硬编码到FastCGI SDK中,并为FCGI_MAX_CONNS和FCGI_MAX_REQS返回1,为FCGI_MPXS_CONNS返回0.所以threaded.c样本永远不会收到多个连接.
我用lighttpd和nginx测试了样本,应用程序一次只处理了一个请求.如何让我的应用程序处理多个请求?或者这是错误的方法?
使用http_load测试了threaded.c程序.该程序在nginx后面运行.程序只有一个实例在运行.如果请求是按顺序提供的,我预计即使并行发送,20个请求也需要40秒.以下是结果(我使用相同的数字作为Andrew Bradford - 20,21和40) -
20个请求,20个并行,耗时2秒 -
$ http_load -parallel 20 -fetches 20 request.txt 20 fetches, 20 max parallel, 6830 bytes, in 2.0026 seconds 341.5 mean bytes/connection 9.98701 fetches/sec, 3410.56 bytes/sec msecs/connect: 0.158 mean, 0.256 max, 0.093 min msecs/first-response: 2001.5 mean, 2002.12 max, 2000.98 min HTTP response codes: code 200 -- 20
21个请求,20个并行,耗时4秒 -
$ http_load -parallel 20 -fetches 21 request.txt 21 fetches, 20 max parallel, 7171 bytes, in 4.00267 seconds 341.476 mean bytes/connection 5.2465 fetches/sec, 1791.55 bytes/sec msecs/connect: 0.253714 mean, 0.366 max, 0.145 min msecs/first-response: 2001.51 mean, 2002.26 max, 2000.86 min HTTP response codes: code 200 -- 21
40个请求,20个并行,需要4秒 -
$ http_load -parallel 20 -fetches 40 request.txt 40 fetches, 20 max parallel, 13660 bytes, in 4.00508 seconds 341.5 mean bytes/connection 9.98732 fetches/sec, 3410.67 bytes/sec msecs/connect: 0.159975 mean, 0.28 max, 0.079 min msecs/first-response: 2001.86 mean, 2002.62 max, 2000.95 min HTTP response codes: code 200 -- 40
因此,它证明即使FCGI_MAX_CONNS,FCGI_MAX_REQS和FCGI_MPXS_CONNS值是硬编码的,也会并行提供请求.
当Nginx收到多个请求时,它会将它们全部放入FCGI应用程序的队列中.在发送第二个请求之前,它不会等待第一个请求的响应.在FCGI应用程序中,当一个线程在任何时间为第一个请求提供服务时,另一个线程不等待第一个请求完成,它将接收第二个请求并开始处理它.等等.
因此,您将失去的唯一时间是从队列中读取请求所需的时间.与处理请求所花费的时间相比,此时间通常可以忽略不计.