• [转] nginx+FastCGI+c++


    from: http://www.cnblogs.com/xiaouisme/archive/2012/08/01/2618398.html

    一 安装

    目的:不需支持php等。就html就行了。
    步骤:
    下载这些东西:
    Lenovo:~/下载/download4nginx$ ls

    md5-1.3.0.tgz openssl-1.0.1c.tar.gz zlib-1.2.7.tar.gz
    nginx-1.3.4.tar.gz pcre-8.31.tar.gz

    解压缩nginx-1.3.4.tar.gz到~/下载/.

    把其他库都解压缩得到md5-1.3.0、openssl-1.0.1c、zlib-1.2.7、pcre-8.31,
    把这些拷贝到~/下载/nginx-1.3.4

    Lenovo:~/下载$ ls 
    download4nginx nginx-1.3.4
    Lenovo:~/下载$ cd nginx-1.3.4
    Lenovo:~/下载/nginx-1.3.4$ vi my_configure.sh

    ./configure --prefix=/usr/local/nginx
    --with-pcre=pcre-8.31
    --with-zlib=zlib-1.2.7
    --with-openssl=openssl-1.0.1c
    --with-http_stub_status_module
    --with-http_ssl_module
    #上面这些库都是比较常用的,建议还是分开把这些库install了。

    make

    make install
    Lenovo:~/下载/nginx-1.3.4$ chmod +x my_configure.sh
    Lenovo:~/下载/nginx-1.3.4$ sudo ./my_configure.sh

    二 测试

    $ cd /usr/local/nginx
    $ sudo ./sbin/nginx
    浏览器:http://localhost 

    三 nginx命令

    启动:nginx 
    重启:kill -HUP `cat /usr/local/nginx/logs/nginx.pid`  #重新加载配置,并开启新的工作进程,关闭就的进程,此操作不会中断请求.
    杀死:kill -TERM `cat /usr/local/nginx/logs/nginx.pid`  #快速关闭程序,中止当前正在处理的请求 .
    关闭 : kill -QUIT `cat /usr/local/nginx/logs/nginx.pid`  #处理完当前请求后,关闭程序 .
    nginx -t  测试配置文件是否正确. 在运行时需要重新加载配置的时候,此命令非常重要,用来检测所修改的配置文件是否有语法错误.

    四、配置文件
    $ sudo cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf_bak
    参考:http://wiki.nginx.org/NginxFullExample

    五、其他零散的经验啊:

    1.设服务器的某站点域名:
    $ sudo vi /usr/local/nginx/conf/nginx.conf
    在某个server{里的server_name 后默认是localhost改成比如:my.nginxserver.com.
    再修改hosts文件:
    $ sudo vi /etc/hosts
    添加127.0.0.1 my.nginxserver.com
    重启nginx。

    2.


    六、nginx + fastcgi + C++

    nginx是支持fastcgi的。然而我们需要下一个fastcgi进程管理器,启动它才能执行fastcgi程序。(这里有几个概念要搞清 楚:nginx是nginx,fastcgi是fastcgi,前者支持后者,但是前者本身没有集成后者(/的功能)。对于ngingx,我们要配置 conf.nginx来设置如何支持fastcgi。而对于fastcgi,我们写的fastcgi程序需要一个调度者:fastcgi进程管理器。—— 纯属个人理解。)

    1. 下载spawn-fcgi-1.6.3.tar.gz : http://redmine.lighttpd.net/news/spawn7
    (
    这个spawn-fcgi就是fastcgi进程管理器。是lighttpd(一个类似apatch、nginx的项目,这里不需要它)中的一个子项目,c嘎嘎的。)
    $ ./configure && make
    $ sudo cp ./src/spawn-fcgi /usr/local/nginx/sbin/

    2.写fastcgi程序还需要fastcgi的库和头文件支持(就好像写多线程程序需要-lpthread一样):
    下载fastcgi的库 (里面还有fastcgi程序的examples噢)

     编译fastcgi库可能会出错,可能是fastcgi项目太老了,GCC又更新太快,修改include/fcgio.h,添加#include<cstdio>
    编译,安装。

    3. 现在写一个fastcgi程序:
    $ cd /usr/local/nginx
    $ sudo mkdir myfastcgi
    $ sudo vi helloFastCGI.c

    #include <iostream>
    #include <fcgi_stdio.h>
    #include <stdlib.h>

    using namespace std;

    int main()
    {
    int count = 0;

    while(FCGI_Accept() >= 0)
    {

    printf( "Content-type:text/html " );
    printf( "<p> Hello FastCGI !  </ p>" );
    printf( "<br /> Request number = [%d]", ++count );
    printf( "<br /> Process ID: %d ", getpid() );

    }

    return 0;
    }

    $ sudo vi Makefile

    all :
          g++ helloFastCGI.c -o helloFastCGI -L/usr/local/lib -lfcgi -Wl,-R /usr/local/lib
    $ sudo make
    $ ./helloFastCGI
    看到printf了说明程序链接都没问题了的。
    $ cp helloFastCGI /usr/local/nginx/myFastCGI #这个文件夹就放我的fast cgi程序。

    4.启动我们的fastcgi进程管理器——spawn-fcgi

    /usr/local/nginx/sbin/spawn-fcgi -a 127.0.0.1 -p 9000 -C 25 -f /usr/local/nginx/myFastCGI/helloFastCGI -F 1000

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


    关闭spawn-fcgi打开的fastcgi程序
    $ netstat -anp | grep 9000 #查看占用9000端口的程序ID
    $ kill -9 PID #或killall 进程名

    如果kill掉部分,剩下的cgi程序继续服务,如果全部kill掉,则返回502

    5.修改nginx配置文件:

    这个网上很多。我的如下(我特殊需求:不希望有缓存)。
    $ sudo vi /usr/local/nginx/conf/nginx.conf

    #user nobody;
    worker_processes 4;

    #error_log logs/error.log;
    #error_log logs/error.log notice;
    #error_log logs/error.log info;

    #pid logs/nginx.pid;

    worker_rlimit_nofile 102400;

    events {
    use epoll;
    worker_connections 102400;
    }


    http {
    include mime.types;
    default_type application/octet-stream;

    charset utf-8;

    server_names_hash_bucket_size 128;
    client_header_buffer_size 2k;
    large_client_header_buffers 4 4k;
    client_max_body_size 8m;

    #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
    # '$status $body_bytes_sent "$http_referer" '
    # '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log logs/access.log main;

    sendfile on;
    tcp_nopush on;

    keepalive_timeout 60;

    server {
    listen 80; // 这儿可以加ip,如果多网卡的话。 --- listen 10.228.132.191:80;
    server_name moa.provider.com;
    index index.htm index.html;
    #access_log logs/host.access.log main;

    location / {
    root html;
    index index.html index.htm;
    #fastcgi_pass 127.0.0.1:9000;
    }

    location ~ .cgi$ {
    #root fcgi;
    #server_name moa.fastcgi.com;
    #rewrite (.*).cgi /$1 break; //c/c++编译出来没有后缀,所以这里去掉后缀,否则nginx会出现503,403等等错误(不知道为什么就是没有404)。
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.cgi;
    fastcgi_param SCRIPT_FILENAME fcgi$fastcgi_script_name;
    #include fastcgi.conf;
    include fastcgi_params;
    #fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name; //定义fastcgi程序jue dui路径
    }

    #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;
    }
    }
    }

    # 改了很多,很乱。不是个好例子。仅仅是个hello world~~

    6  有几个概念必须讲清楚——
    1. .ginx收到cgi请求后,会看有多少个该cgi程序的进程(spawn-fcgi -F指定的参数),然后根据并发量来调用(调度)cgi程序。
    2. 原版spawn-fcgi(可参考下面七参考资料里daemon版spawn-fcgi)在fork了cgi程序后,自己就退出了。这时fork了的 cgi程序的父进程ID都是1了,即init系统进程。这样,如果想并发就需要你的fastcgi去支持并发,可google:fastcgi并发
    3. 关于php,nginx是用fastcgi来解析php的。这个负责解析的fastcgi程序并不多,好像就1个,因此这cgi不能大并发,但是没关系 nginx支持cgi缓存~所以php网页的并发请求跟fastcgi关系不大。其实可以把fastcgi对于php的作用当作一个编译器,编译完 后,php都有了缓存,再请求就不需要再次跑fastcgi来解析php脚本了,php就是个该死的脚本啊~~ 

     我自己也不知道讲清楚没。其实我自己也不知道自己清楚没。:-)

     

    七、参考资料:

     
    1.http://wiki.nginx.org/NginxFullExample (配置)
    2.Nginx配置与应用详解 (详你妹)

    3.Nginx-httpFastCGIModule: http://wiki.nginx.org/HttpFcgiModule
    4.网站压力测试工具webbench[原创] (还不错.  $ webbench -c 1000 -t 30 http://127.0.0.1/test.jpg)
    5.spawn-fcgi与fcgi的运行机制分析 (这个还不错,把spawn-fcgi改 成了守护程序。但是在调用daemon函数的时候应该传参数(1, 0)。ps:实际上这个spawn-fcgi只是会截获孩子进程的CLD_DUMPED(它coredumped了)然后增加一个孩子进程(就是检测某到 某孩子coredumped了就再fork一个).)
    6.http://wbwk2005.blog.51cto.com/2215231/550540 讲fastcGI技术优点已经如何效率的。必读。

    7. Fastcgi 白皮书 (不错,简单明了的讲了fastcgi架构原理,给出了fastcgi白皮书链接,FCGI_Record就是http request内容 ~)
    8. fastcgi并发: http://www.google.com.hk/search?sourceid=chrome&client=ubuntu&channel=cs&ie=UTF-8&q=fastcgi%E5%B9%B6%E5%8F%91

    9. linux下进程的最大线程数、进程最大数、进程打开的文件数


    八、 我的记录

    参考了上面的参考资料8和6之后,我决定 spawn-fcgi -F 100, 然后在每个cgi程序里开1000个线程(把线程的栈改设为1KB,或者还是1M吧),这样并发就是100*1000 = 10W了。足够了。不过我cgi程序会用来给后面的真正的推送服务主程序发请求。所以后面的并发也是一道关卡。

    ------------------------------------------------------------------------------
    依然零散的经验啊:
    nginx添加被fastcgi识别的自定义header:
    自定义header:
    在nginx.conf里面加:
    http {
    ....
    underscores_in_headers on;#这样就可以支持下划线的header了,默认不支持.
    ....
    location  .... {
                fastcgi_pass 127.0.0.1:9000;
                include fastcgi_params;
            }
    然后在fastcgi_params里添加想增加的header:
    fastcgi_param     REQUEST_COMMAND   $http_request_command;#“request_command”就是你添加的希望被识别的自定义header.在fastcgi程序 i里这样取header:FCGX_GetParam("REQUEST_COMMAND", request->envp);
    (request是FCGX_Request *)。  

     

  • 相关阅读:
    关于w3wp进程占用过多cpu的问题
    调试事务时的小坑
    PowerDesign中的Reverse Engineering
    对数据访问层的重构(及重构中Perl的应用)
    请教关于在asp.net站点中使用静态变量的问题
    .net面试应知应会(zt)
    关于代码运行效率问题的一个总结和一点疑问
    自己写的一个使用游标的小例子
    怎样才能写出尽可能让编译器找出潜在错误的代码?
    关于连接字符串中IMEX参数的一个问题
  • 原文地址:https://www.cnblogs.com/qiangxia/p/4885840.html
Copyright © 2020-2023  润新知