zoukankan      html  css  js  c++  java
  • nginx下面部署fast-cgi和C++【原】

    1.cgi文件的代码

    #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
    
    ");
                    FCGI_printf("<title>FastCGI Hello HI! (C, fcgi_stdio library)</title>
    ");
                    FCGI_printf("Request number %d running on host %s Process ID: %d
    ",++count,getenv("SERVER_NAME"), getpid());
        }
        /* End of response loop */
        return 0;
    }
    

    过程中可能遇到一些问题,提示502的错误,原因在代码的cgi问题。

     使用fastcgi c api时注意的问题

    最近用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 ")。我按照这个格式写了,但还是出错。最后发现是由于include了c和c++的一些头文件,比如,下面的代码就有可能出现这样的问题(也有可能不出现问题):

     

    #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/*
    
    "); 
    		printf("<title>FastCGI Hello! (C, fcgi_stdio library)</title>
    ");
        }
    }

    在官方的api使用例子里面,只有include “fcgi_stdio.h”和“stdlib.h”这两个头文件。于是我看了一下fcgi_stdio.h这个文件,发现它定义了一个宏,也叫printf,而事实上是调用了FCGI_printf这个函数。 而include其他的头文件可能会导致链接的时候链接到原来的printf实现,所以最保险的做法是:

     

    #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/*
    
    "); 
    		FCGI_printf("<title>FastCGI Hello! (C, fcgi_stdio library)</title>
    ");
        }
    }
    

     

    2.nginx的配置文件

    #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.cgi

        gcc -o 1.cgi 1.c -lfcgi

        4.运行1.cgi文件

    注意这是一行命令哦。注意可能要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

     这是网上的一些测试,待有时间再做验证,先保存起来。。。

    3.webbench压力测试工具

    下载: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)

    4.Nginx模块

    模块列表
    http://wiki.codemongers.com/NginxModules

    FastCGI模块源码:nginx/src/http/modules/ngx_http_fastcgi_module.c

  • 相关阅读:
    CSS画出三角形(利用Border)
    Javascript中style,currentStyle和getComputedStyle的区别以及获取css操作方法
    用canvas实现验证码的绘制
    tinymce富文本编辑器升级问题
    同步和异步
    this
    发送短信——案例
    SpringMvc框架【多测师】
    通过百度文字识别的API来实现把图片内容写入到txt文件当中【多测师】
    史上最全软件测试工程师常见的面试题总结(七)【多测师】
  • 原文地址:https://www.cnblogs.com/xiatian1071/p/3523837.html
Copyright © 2011-2022 走看看