1.cgi文件的代码php
#include "fcgi_stdio.h" #include <stdlib.h> #include <stdio.h> int main() { /* Initialization Code */ int count = 0; /* Start of response loop */ while (FCGI_Accept() >= 0) { //* body of response loop /*/ //FCGI_printf("Content-type: text/html/r/n" // "/r/n" // "" // "FastCGI Hello/! (C, fcgi_stdio library)" // "Request number %d running on host %s " // "Process ID: %d/n",++count,getenv("SERVER_NAME"), getpid()); FCGI_printf("Content-type: text/html\r\n\r\n"); FCGI_printf("<title>FastCGI Hello HI! (C, fcgi_stdio library)</title>\n"); FCGI_printf("Request number %d running on host %s Process ID: %d\n",++count,getenv("SERVER_NAME"), getpid()); } /* End of response loop */ return 0; }
过程当中可能遇到一些问题,提示502的错误,缘由在代码的cgi问题。html
使用fastcgi c api时注意的问题java
最近用fastcgi的c语言api写服务,发现一个问题。我用nginx来接收请求,并经过fastcgi_pass传递到c程序。在用curl测试请求的时候,发现c程序是有被调用的,可是nginx返回的响应一直是502 "upstream closed prematurely FastCGI stdout while reading response header from upstream"。在网上找了好久,也有一样的问题,可是通常都是说缘由是printf的时候没有按照http协议,好比说必定要printf("Content-type: text/html \r\n\r\n")。我按照这个格式写了,但仍是出错。最后发现是因为include了c和c++的一些头文件,好比,下面的代码就有可能出现这样的问题(也有可能不出现问题):ios
#include "fcgi_stdio.h" #include <iostream> #include <string> #include <map> #include <stdlib.h> #include <stdio.h> int main() { while(FCGI_Accept() >= 0) { ////////////////////////////////////////////////////////////////////////// //get content type and length ////////////////////////////////////////////////////////////////////////// printf("Content-type: text/*\r\n\r\n"); printf("<title>FastCGI Hello! (C, fcgi_stdio library)</title>\n"); } }
在官方的api使用例子里面,只有include “fcgi_stdio.h”和“stdlib.h”这两个头文件。因而我看了一下fcgi_stdio.h这个文件,发现它定义了一个宏,也叫printf,而事实上是调用了FCGI_printf这个函数。 而include其余的头文件可能会致使连接的时候连接到原来的printf实现,因此最保险的作法是:nginx
#include "fcgi_stdio.h" #include <iostream> #include <string> #include <map> #include <stdlib.h> #include <stdio.h> int main() { while(FCGI_Accept() >= 0) { ////////////////////////////////////////////////////////////////////////// //get content type and length ////////////////////////////////////////////////////////////////////////// FCGI_printf("Content-type: text/*\r\n\r\n"); FCGI_printf("<title>FastCGI Hello! (C, fcgi_stdio library)</title>\n"); } }
2.nginx的配置文件c++
#user nobody; #daemon off; #master_process off; worker_processes 1; error_log logs/80_error.log; error_log logs/80_notice.log notice; error_log logs/80_info.log info; error_log logs/80_debug.log debug; pid logs/80.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; error_log logs/80_http_debug.log debug; access_log logs/80_http_access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on;
//部署负载均衡 #upstream resinserver{ # server 127.0.0.1:8081 weight=1; # server 127.0.0.1:8082 weight=1; # server 127.0.0.1:8083 weight=1; # keepalive 1024; #} server { listen 8080; server_name 192.168.104.101 127.0.0.1 localhost; #charset koi8-r; #access_log logs/host.access.log main; #location / { # root html; # index index.html index.htm; #proxy_pass http://resinserver/; #proxy_set_header Host $host; #proxy_set_header X-Real-IP $remote_addr; #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #} //部署cgi文件 #location ~/.cgi$ { # fastcgi_pass 127.0.0.1:9002; # fastcgi_index index.cgi; # fastcgi_param SCRIPT_FILENAME cgibin$fastcgi_script_name; # include fastcgi_params; #} #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # #error_page 500 502 503 504 /50x.html; #location = /50x.html { # root html; #} # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 #
//这是我本身添加的 location ~\.cgi$ { root /usr/local/nginx/cgibin; fastcgi_pass 127.0.0.1:9002; fastcgi_index index.cgi; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; include fastcgi_params; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443 ssl; # server_name localhost; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} }
3.编译1.cgiweb
gcc -o 1.cgi 1.c -lfcgiapache
4.运行1.cgi文件api
注意这是一行命令哦。注意可能要sudo.
-p是指定fastcgi控制器绑定的TCP端口listen的.
若是你想调试单个fastcgi程序,能够把-f换成-n.
-F指定spawn-fcgi将fork多少个child进程。以后nginx对于此cgi的请求就能够并发了。显然这里的直接并发量是1000.
其余参数能够help看看:(看起来-C对不要php的我来讲没啥用.本文是初次使用记录性教程,这里就不纠结这些参数了)浏览器
Lenovo:/usr/local/nginx$ sbin/spawn-fcgi --help
/usr/local/nginx/sbin/spawn-fcgi -a 127.0.0.1 -p 9002 -C 25 -f /usr/local/nginx/cgibin/1.cgi
监听的端口是9002,对应nginx的配置文件的9002
关闭spawn-fcgi打开的fastcgi程序:
$ netstat -anp | grep 9000 #查看占用9000端口的程序ID
$ kill -9 PID #或killall 进程名
5.运行nginx
./sbin/nginx -c nginx.conf
6.在浏览器查看
http://192.168.104.101:8080/1.cgi
这是网上的一些测试,待有时间再作验证,先保存起来。。。
下载:http://home.tiscali.cz:8080/~cz210552/distfiles/webbench-1.5.tar.gz
安装:
tar zxvf webbench-1.5.tar.gz cd webbench-1.5
make && make install
使用:
webbench -c 500 -t 30 http://127.0.0.1/test.jpg
500是并发链接数,30是时间单位是秒
用ab测试的结果,在个人虚拟机上,看起来性能很不错
(Apache Bench是Apache自带的工具包)
ab -n 10000 -c 100 http://127.0.0.1/1.cgi
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
Server Software: nginx/0.7.38
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /1.cgi
Document Length: 143 bytes
Concurrency Level: 100
Time taken for tests: 3.982 seconds
Complete requests: 10000
Failed requests: 8399
(Connect: 0, Receive: 0, Length: 8399, Exceptions: 0)
Write errors: 0
Total transferred: 2658399 bytes
HTML transferred: 1438399 bytes
Requests per second: 2511.06 [#/sec] (mean)
Time per request: 39.824 [ms] (mean)
Time per request: 0.398 [ms] (mean, across all concurrent requests)
Transfer rate: 651.89 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 4.6 0 51
Processing: 22 39 6.8 36 93
Waiting: 4 39 6.8 36 93
Total: 24 39 8.2 36 97
Percentage of the requests served within a certain time (ms)
50% 36
66% 39
75% 41
80% 42
90% 48
95% 54
98% 70
99% 84
100% 97 (longest request)
模块列表
http://wiki.codemongers.com/NginxModules
FastCGI模块源码:nginx/src/http/modules/ngx_http_fastcgi_module.c