💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 6.3 Nginx与FastCGI nginx 不能像apache那样直接执行外部可执行程序,但nginx可以作为代理服务器,将请求转发给后端服务器,这也是nginx的主要作用之一。其中nginx就支持FastCGI代理,接收客户端的请求,然后将请求转发给后端fastcgi进程。下面介绍如何使用C/C++编写cgi/fastcgi,并部署到nginx中。 通过前面的介绍知道,fastcgi进程由FastCGI进程管理器管理,而不是nginx。这样就需要一个FastCGI管理,管理我们编写fastcgi程序。本文使用spawn-fcgi作为FastCGI进程管理器。 ## spawn-fcgi spawn-fcgi是一个通用的FastCGI进程管理器,简单小巧,原先是属于lighttpd的一部分,后来由于使用比较广泛,所以就迁移出来作为独立项目了。spawn-fcgi使用pre-fork 模型,功能主要是打开监听端口,绑定地址,然后fork-and-exec创建我们编写的fastcgi应用程序进程,退出完成工作。fastcgi应用程序初始化,然后进入死循环侦听socket的连接请求。 ### 安装 * 获取spawn-fcgi编译安装包,在 http://redmine.lighttpd.net/projects/spawn-fcgi/wiki 上可以获取当前最新的版本。 * 解压缩spawn-fcgi-x.x.x.tar.gz包。 * 进入解压缩目录,执行./configure。 * make & make install 如果遇到以下错误: 如果遇到以下错误: ```bash ./autogen.sh: x: autoreconf: not found ``` 因为没有安装automake 工具,ubuntu用下面的命令安装好就可以了: ```bash sudo apt-get install autoconf automake libtool 。 ``` spawn-fcgi的帮助信息可以通过man spawn-fcgi或spawn-fcgi –h获得,下面是部分常用spawn-fcgi参数信息: ```bash f <fcgiapp> 指定调用FastCGI的进程的执行程序位置 -a <addr> 绑定到地址addr。 -p <port> 绑定到端口port。 -s <path> 绑定到unix domain socket -C <childs> 指定产生的FastCGI的进程数,默认为5。(仅用于PHP) -P <path> 指定产生的进程的PID文件路径。 -F <childs> 指定产生的FastCGI的进程数(C的CGI用这个) -u和-g FastCGI使用什么身份(-u 用户 -g 用户组)运行, CentOS下可以使用apache用户,其他的根据情况配置,如nobody、www-data等。 ``` ### 编写fastgci应用程序 使用C/C++编写fastcgi应用程序,可以使用FastCGI软件开发套件或者其它开发框架,如fastcgi++。 本文使用FastCGI软件开发套件——fcgi http://www.filewatcher.com/d/Gentoo/distfiles/Other/fcgi-2.4.1-SNAP-0910052249.tar.gz.614929.html 通过此套件可以轻松编写fastcgi应用程序,安装fcgi: ```bash ./configue make ``` 如果编译出现类似以下错误: ```bash cgio.cpp: In destructor 'virtual fcgi_streambuf::~fcgi_streambuf()': fcgio.cpp:50: error: 'EOF' was not declared in this scope fcgio.cpp: In member function 'virtual int fcgi_streambuf::overflow(int)': fcgio.cpp:70: error: 'EOF' was not declared in this scope fcgio.cpp:75: error: 'EOF' was not declared in this scope fcgio.cpp: In member function 'virtual int fcgi_streambuf::sync()': fcgio.cpp:86: error: 'EOF' was not declared in this scope fcgio.cpp:87: error: 'EOF' was not declared in this scope fcgio.cpp: In member function 'virtual int fcgi_streambuf::underflow()': fcgio.cpp:113: error: 'EOF' was not declared in this scope make[2]: *** [fcgio.lo] Error 1 make[2]: Leaving directory `/root/downloads/fcgi-2.4.1-SNAP-0910052249/libfcgi' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/root/downloads/fcgi-2.4.1-SNAP-0910052249' make: *** [all] Error 2 ``` 解决办法:在include/fcgio.h文件中加上** ```cpp #include <cstdio> ``` ,然后再次编译 ```bash sudo make install ``` 编写一个fcgi简单的应用程序: ```cpp #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include "fcgi_stdio.h" int main(int argc, char *argv[]) { int count = 0; while (FCGI_Accept() >= 0) { printf("Content-type: text/html\r\n"); printf("\r\n"); printf("<title>Fast CGI Hello!</title>"); printf("<h1>Fast CGI Hello!</h1>"); printf("Request number %d running on host <i>%s</i>\n", ++count, getenv("SERVER_NAME")); } return 0; } ``` 编译: ```bash gcc fcgi_demo.c -o demo -lfcgi ``` 这个就是其中一个针对client一个http请求的业务服务应用程序。 需要在后台跑起来,并且让spawn负责管理。 ```bash spawn-fcgi -a 127.0.0.1 -p 8081 -f ./demo ``` ### 有关nginx的fcgi的配置 ```bash server { listen 80; server_name localhost; #access_log logs/host.access.log main; location / { #proxy #proxy_pass http://backup.com; root html; index index.html index.htm; } #监听用户的demo.cgi请求,通过fastcgi_pass 交给本地8081端口处理 #此时spwan-cgi已经将8081端口交给之前我们写好的demo进程处理 location /demo { fastcgi_pass 127.0.0.1:8081; fastcgi_index demo.cgi; include fastcgi.conf; } #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; } } ``` 这样nginx收到http://localhost/demo请求时,会匹配到location /demo 块,将请求传到后端的fastcgi应用程序处理。 ![](https://img.kancloud.cn/ab/16/ab169ae269156b3e2ac5ddaa8de078a9_455x151.png)