资讯专栏INFORMATION COLUMN

FastCGI+lighttpd开发之介绍和环境搭建

gghyoo / 3305人阅读

摘要:原文开发之介绍和环境搭建由于需要做一些简单的基于的开发,开始学习和调研,本篇介绍和的概念以及基于官方的,以及搭建起简单的开发环境,以作备忘。所以程序其实没有语言限制,只要能够读取环境变量,读写标准输入输出即可。管理器有多种形式。

原文:FastCGI+lighttpd开发之介绍和环境搭建

由于需要做一些简单的基于FastCGI的Web开发,开始学习和调研,本篇介绍CGI和FastCGI的概念以及基于FastCGI官方的devkit,以及lighttpd搭建起简单的开发环境,以作备忘。

为啥要搞这个?

现在开发Web有N种选择,啥php,C#,java,ruby,nodejs...哪个都比开发FastCGI要简单和强大的多,为何还要跑到这么个底层来做Web服务呢?答案是嵌入式系统需求!我们知道嵌入式系统往往由于硬件的限制,为了节约处理器和内存,很多事情都需要省的点用。对于简单的Web服务,没有必要(或者不能)去使用高层次的编程框架,那么这个时候,就可以直接基于CGI那套协议来进行开发。通常在这个层次下,C语言是首选。

FastCGI和CGI的概念

要搞清楚FastCGI,必须先搞清楚CGI

参考

CGI与FastCGI

Nginx + CGI/FastCGI + C/Cpp

搞不清FastCgi与PHP-fpm之间是个什么样的关系

CGI

CGI是一种协议,用于扩展Web服务器原本的能力。我们知道,Web服务器最早是用来提供静态文件访问的,想要实现动态内容提供是比较困难的。CGI因此而产生。这是一套协议,简单的说,就是Web服务器在必要的时候,为了处理Request,会调起一个进程(CGI程序),让这个进程来处理请求,并将这个进程返回的结果返回给客户端。然后进程结束,下次请求重复这个过程。这个过程中涉及到Web进程和CGI程序进程的输入和输出协议,这个机制和协议就叫CGI。那么具体的说,在CGI程序中,输入和输出是通过stdin,stdout,stderr来进行的,请求的参数等则是通过环境变量来传递的。所以CGI程序其实没有语言限制,只要能够读取环境变量,读写标准输入输出即可。下图以Apache和Python为例,说明CGI的工作方式

Python的CGI扩展能够在Python解释器的帮助下,解释用户编写的Python脚本,从而输入输出,虽然这个模型相比上面阐述的基本模型要复杂一点,但是本质是相同的。

CGI的缺点很明显,每个请求都要启动进程来处理请求,进程启动的开销是没有必要的。

FastCGI

为了解决CGI的缺点,诞生了FastCGI。既然CGI的缺点是进程的频繁启动和关闭,那么是否可以有一个专门管理CGI进程的程序,在没有Request请求的情况下,保持多个CGI进程的挂起状态,当有请求的时候,分配一个进程来处理,处理完成后挂起,就像是进程池一样。这个进程池的管理程序称为FastCGI管理器,从字面看,它可以提高CGI程序的效率。

不光是处理模型的优化,CGI程序只能在Web服务器本机执行,而基于FastCGI的管理下,CGI程序可以被部署在远程,通过TCP Socket或者Unix domain Socket来传输数据,这种模式可以理解为FastCGI代理

FastCGI管理器有多种形式。例如:Apache和Lighttpd是通过模块的方式实现FastCGI管理器的,而Nginx则是通过FastCGI代理模式实现的(也就是说需要一个多带带的FastCGI管理器进程,该进程通过侦听TCP Socket或者Unix domain Socket在Nginx和CGI程序之间起到桥梁作用)。

同样是Apache和Python为例,下图为FastCGI的启动和运行的模型

Apache在调用用户脚本的时候,会依靠Apache内建的FastCGI模块来调度CGI进程,CGI进程也不会消亡,下次请求就不需要重新启动解析器了。而且CGI进程是通过Socket形式实现输入输出的,当然CGI程序在编写的时候,仍然是通过stdin,stdout,stderr来输入输出,只是最终可能是通过网络来实现的,这样做可以实现从CGI程序到FastCGI程序的平滑过渡。你会发现开发FastCGI程序跟开发CGI程序并没有多少区别。

关于Nginx的FastCGI代理模式,有必要多说几句。Nginx自身没有实现FastCGI管理器,但是Nginx可以支持FastCGI代理,我们来看看Nginx是如何配置php的就明白了:

location ~ .php$ {
    root  html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    include        fastcgi_params;
}

可以看到,Nginx其实是把请求扔给127.0.0.1:9000,那么还需要一个程序来监听127.0.0.1:9000啊,对了!这个程序就是php-fpm,所以我们在用Nginx配置php的时候需要:

php-fpm start

php-fpm可以帮Nginx实现CGI进程管理器的功能。看起来好麻烦有没有,为什么Apache无需php-fpm,原因上面说了,Apache是通过模块实现的,无需多带带启动php-fpm

那么,如何开始开发一个FastCGI程序呢,我们需要FastCGI的开发套件,以及一个合适的Web服务器,这里FastCGI套件从这里下载,Web服务器,我们选择了lighttpd,因为既然要直接开发CGI程序,那么通常你会选择尽可能轻量的Web服务器。当然支持FastCGI的Web服务器很多,这里有列表。

准备lighttpd

lighttpd的安装就不多说了,你可以选择编译安装或者源安装,我选择了编译安装,所以后续的启动啥的麻烦一点。

lighttpd的启动和重启

如果是编译安装的,那么你需要将源码包doc里面的config文件夹复制到/etc下,并重命名为lighttpd,这里面是lighttpd的一系列启动配置,然后像下面这样启动:

/usr/local/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf

如果你经常折腾Web服务器,这应该很好理解。当然你可以查看一下配置文件,了解个大概(尤其是日志文件的位置),由于配置文件有很多注释,分享一个命令,能去掉注释部分,只看重点:

sed -n "/^s*[^#]/p" /etc/lighttpd/lighttpd.conf

重启的话,可以通过下面命令先杀掉相关的进程,然后再启动

killall lighttpd
/usr/local/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf
lighttpd配置fastcgi模块

这个相对简单,在/etc/lighttpd/modules.conf,将里面的fastcgi模块的引用反注释掉

include "conf.d/fastcgi.conf"

那么关于fastcgi的配置就顺理成章的在conf.d/fastcgi.conf中了,其中关键的一句是:

server.modules += ( "mod_fastcgi" )

底下有很多示例配置,尤其是对php的配置示例,尤其详细,然而我们是直接做CGI程序,可以参考这个配置

fastcgi.debug = 1
fastcgi.server = (
    ".fcgi" => (
     "local" => (
      "socket" => socket_dir + "fcgitest-fcgi.socket",
      "checklocal" => "disable",
      "bin-path" => server_root + "/htdocs/cgi-bin/fh.fcgi",
      "idle-timeout" => 10,
      "min-procs" => 1,
      "max-procs" => 1
     )
    )
)

理解了FastCGI原理后,再来看这个其实很容易理解:

对所有.fcgi后缀的处理

通过fcgitest-fcgi.socket

/htdocs/cgi-bin/fh.fcgi程序来处理

最多同时驻留1个CGI进程,最少1个(对于嵌入式系统,并不是要处理高并发,多个进程并没有意义)

我们可以通过浏览器访问http://localhost/cgi-bin/fh.fcgi,即可执行fh.fcgi程序(这里htdocs是配置的文档根目录)。

那么接下来的重点是开发/htdocs/cgi-bin/fh.fcgi程序。

开始开发FastCGI程序 开发套件的安装

下载好套件后,解压在fcgi-devel-kit目录

cd fcgi-devel-kit
./configure
make
cd libfcgi
make
make install

显然我们其实需要的是FastCGI的includelib,上面的命令可以在/usr/local/lib下创建几个相关的库文件:

-rw-r--r--.  1 root root 204902 Nov 15 20:09 libfcgi.a
-rwxr-xr-x.  1 root root    704 Nov 15 20:09 libfcgi.la
lrwxrwxrwx.  1 root root     16 Nov 15 20:09 libfcgi.so -> libfcgi.so.0.0.0
lrwxrwxrwx.  1 root root     16 Nov 15 20:09 libfcgi.so.0 -> libfcgi.so.0.0.0
-rwxr-xr-x.  1 root root 145320 Nov 15 20:09 libfcgi.so.0.0.0

.a是静态库,.la是基于libtool的链接库。后面你可以选择使用.a来链接,也可以使用libtool工具,使用.la来构建。

完成套件的安装后,先创建一个项目文件,并将include和libtool工具拷贝进去(如果你不打算用libtool编译,可以不拷贝libtool)

mkdir -p ~/Projects/fh
cp -r ~/fcgi-devel-kit/include ~/Project/fh/fcgi_inc
cp ~/fcgi-devel-kit/libtool ~/Project/fh/libtool

创建一个main.c文件,并编辑如下:

#include 
#include 

int main(){
 int count = 0;
 while(FCGI_Accept() >= 0){
    printf("Content-type: text/html
"
           "
"
           "FastCGI Hello! (C, fcgi_stdio library)"
           "

FastCGI Hello! (C, fcgi_stdio library)

" "Request number %d running on host %s ", ++count, getenv("SERVER_NAME")); } }

上面的程序跟普通的CGI程序的关键区别在于while(FCGI_Accept() >= 0),这个条件会在没有请求需要处理的时候阻塞,那么进程就会挂起,并在正常情况下不会退出。这样就实现了进程驻留的效果。

编译和链接

使用libtool进行编译和链接

./libtool --mode=compile gcc -I fcgi_inc -c main.c

rm -f .libs/main.lo
gcc -I fcgi_inc -c main.c  -fPIC -DPIC -o .libs/main.lo
gcc -I fcgi_inc -c main.c -o main.o >/dev/null 2>&1
mv -f .libs/main.lo main.lo

编译得到的是main.lomain.o,前者用于继续用libtool链接FastCGI的lib,后者可用于普通的链接。

接着链接:

./libtool --mode=link gcc -o fh main.lo /usr/local/lib/libfcgi.la

gcc -o fh main.o  /usr/local/lib/libfcgi.so -lnsl  -Wl,--rpath -Wl,/usr/local/lib -Wl,--rpath -Wl,/usr/local/lib

得到的程序fh,是通过main.o/usr/local/lib/libfcgi.so链接后生成的(动态链接),可以看到libtool实际上只是对gcc的一个包装而已。据说是为了方便解决依赖库,笔者折腾了好久才弄清楚。

最后,将fh复制到目标目录,并重命名。当然如果fh.fcgi进程已经由lighttpd启动,需要杀掉进程,再覆盖。

cp -f fh /srv/www/htdocs/cgi-bin/fh.fcgi

最后使用浏览器的访问效果:

需要注意的是,访问的文件还是必须物理存在的(因为没有配置任何rewrite),比如这里访问的cgi-bin/fg.fcgi,实际上映射了/srv/www/htdocs/cgi-bin/fg.fcgi文件,然后再用fastcgi的方式来处理。否则只会返回404,笔者在这里卡了一下。

结语

花了一天时间,简单实验的FastCGI的开发,后续还需要使用IDE来开发,并实现交叉编译,后面再折腾了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21223.html

相关文章

  • FastCGI+lighttpd开发介绍环境搭建

    摘要:原文开发之介绍和环境搭建由于需要做一些简单的基于的开发,开始学习和调研,本篇介绍和的概念以及基于官方的,以及搭建起简单的开发环境,以作备忘。所以程序其实没有语言限制,只要能够读取环境变量,读写标准输入输出即可。管理器有多种形式。 原文:FastCGI+lighttpd开发之介绍和环境搭建 由于需要做一些简单的基于FastCGI的Web开发,开始学习和调研,本篇介绍CGI和FastCGI...

    lindroid 评论0 收藏0
  • FastCGI+lighttpd开发介绍环境搭建

    摘要:原文开发之介绍和环境搭建由于需要做一些简单的基于的开发,开始学习和调研,本篇介绍和的概念以及基于官方的,以及搭建起简单的开发环境,以作备忘。所以程序其实没有语言限制,只要能够读取环境变量,读写标准输入输出即可。管理器有多种形式。 原文:FastCGI+lighttpd开发之介绍和环境搭建 由于需要做一些简单的基于FastCGI的Web开发,开始学习和调研,本篇介绍CGI和FastCGI...

    Sleepy 评论0 收藏0
  • 利用lighttpd Web引擎在Ubuntu 16.04系统中搭建网站系统

    摘要:我们在服务器中搭建建站系统较为多见的是利用或者是,这个应该是占用大部分网站站长使用的引擎。利用引擎在系统中搭建网站系统第一升级软件源和系统如果我们有必要的话可以也将当前服务器别名更换成需要的,一般我们就默认。配置完毕后重启生效。 我们在Linux服务器中搭建建站系统较为多见的是利用Nginx或者是Apache,这个应该是占用大部分网站站长使用的WEB引擎。但是,也有很多网友会选择其他引...

    mengera88 评论0 收藏0
  • PHP|什么是CGI, FastCGI, PHP-CGI, PHP-FPM, Spawn-FCGI

    摘要:当客户端请求到达时,进程管理器选择并连接到一个解释器。什么是是一个管理器,是只用于的可以在下载得到其实是源代码的一个补丁,旨在将进程管理整合进包中。与功能比较都是守护的进程管理器。 什么是CGI CGI全称是公共网关接口(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行交谈的一种工具,其程序须运行在网络服务器上。 CGI可以用任何一种语言编...

    el09xccxy 评论0 收藏0
  • PHP fastcgi_finish_request 方法

    摘要:介绍每有一个用户请求,都会先要创建的子进程,然后处理请求,处理完后结束这个子进程,这就是模式。当子进程关闭连接时,请求便告处理完成。子进程接着等待并处理来自进程管理器的下一个连接。运行在模式时,提供的方法。 本文介绍,PHP运行在FastCGI模式时,FPM提供的方法:fastcgi_finish_request。 在说这个方法之前,我们先了解PHP有哪些常用的运行模式? PHP运行模...

    macg0406 评论0 收藏0

发表评论

0条评论

gghyoo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<