`

FastCGI开发者套件

阅读更多

FastCGI开发者套件
 
 

FastCGI开发者套件

Mark R. Brown
Open Market, Inc.

文档版本:1.08
1996年6月11日

Copyright © 1996 Open Market, Inc. 245 First Street, Cambridge, MA 02142 U.S.A.
Tel: 617-621-9500 Fax: 617-621-1703 URL: http://www.openmarket.com/
$Id: fcgi-devel-kit.htm,v 1.6 2002/02/25 00:42:59 robs Exp $


1. 介绍

FastCGI是对CGI的开放的扩展,它为所有因特网应用提供高性能,且没有Web服务器API的缺点(penalty)。

FastCGI被设计置于现存的Web服务器API之上。例如,Apache模块mod_fastcgi向Apache服务器添加FastCGI支持。FastCGI也能用在任何支持CGI的Web服务器上,只有简化的功能和下降的性能。

本FastCGI开发者套件被设计用来使得开发FastCGI应用更容易。当前套件支持用C/C++、Perl、Tcl和Java编写的FastCGI应用。

本文档:

  • 描述如何为你的开发平台配置和构建套件。
  • 讲述如何使用套件中的库编写应用。
  • 讲述如何利用支持FastCGI的Web服务器运行应用,或者利用任何Web服务器和cgi-fcgi

套件中包含技术白皮书doc/fastcgi-whitepaper/fastcgi.htm。在开始编写FastCGI应用以前,你应当至少阅读技术白皮书的前三章。性能论文将帮助你理解带FastCGI的应用设计如何影响性能。

FastCGI规范doc/fcgi-spec.html,定义FastCGI应用和支持FastCGI的Web服务器之间的接口。套件中的软件实现了该规范。编写应用不需要阅读规范。

FAQ文档中提供了附加信息,它包括与利用FastCGI的应用开发有关常见问答,还有一些一般性信息。

对于编写FastCGI应用,CGI编程经验是极有价值的。如果你没有足够的CGI编程经验,你应当阅读一本关于该主题的普及书籍,或者学习NCSA CGI页。CGI/1.1的更正式的论述见因特网CGI 1.1规范草案

2. 入门指南

套件是个压缩的tar(tar.Z)文件,通过fastcgi.comWeb页分发。解包该tar文件会创建一个新目录fcgi-devel-kit

使用Web浏览器的“打开文件”命令打开套件的索引页,fcgi-devel-kit/index.html。索引页给你套件结构的纵览,并帮助你游览套件。索引页也包括运行示例应用的链接,但是当利用“打开文件”命令打开index.html时,应用不会工作,因为它们不是通过Web服务器访问的。

为了 in earnest 地使用套件,你将需要一个由自己控制的Web服务器,一个以你的用户ID运行的Web服务器。Web服务器会启动你要调试的FastCGI应用;如果这些 进程以你的用户ID运行,将带给你极大的方便。最好拥有支持FastCGI的Web服务器。第4章论述Web服务器问题。

如果可以,把套件保存在从你的个人工作站可存取的文件系统上,在你的工作站上执行构建并在其上运行你的Web服务器。如果不行,调整配置以使套件从你的 Web服务器的机器可存取,并在某机器上构建套件和你的应用,该机器的配置方式同你的Web服务器完全一样。

要构建套件,在fcgi-devel-kit目录中执行该命令序列:

    % ./configure
% make

我们已经在这些平台上构建和应用了套件(以字母顺序列出):

  • BSD/OS 1.1 (Intel Pentium), gcc
  • Digital UNIX V3.2 148 (Alpha), gcc/cc
  • Hewlett-Packard HP-UX A.09.05 C and B.10.01 A (PA-RISC), gcc/cc
  • IBM AIX 1 4 (RS/6000), gcc
  • Silicon Graphics IRIX 5.3 11091812 (MIPS), gcc
  • Sun Solaris 2.4 and 2.5 (SPARC), gcc/cc
  • Sun SunOS 4.1.4 (SPARC), gcc

一旦构建了套件,就可依据第4章中的说明 bring up 你的Web服务器并运行示例应用。

3. 编写应用

3.1 使用fcgi_stdio

fcgi_stdio库为C CGI程序和程序员提供到FastCGI的最轻松的过渡。利用该库,你的应用既可用CGI运行,也可用FastCGI,这两种情况使用相同的库。

我们给出一对例子来介绍fcgi_stdio库:一个微型CGI程序和该程序向FastCGI的迁移。这两个示例程序被包括在套件中。

CGI程序是examples/tiny-cgi.c

    #include <stdio.h>
#include <stdlib.h>

void main(void)
{
int count = 0;
printf("Content-type: text/html\r\n"
"\r\n"
"<title>CGI Hello!</title>"
"<h1>CGI Hello!</h1>"
"Request number %d running on host <i>%s</i>\n",
++count, getenv("SERVER_NAME"));
}

该微型CGI程序的主要特性是:

  • 在该例中,程序通过用printf写入stdout来向Web服务器发送数据。CGI程序首先发送Content-type报头,然后发送一个小型的HTML文档。程序包含stdio.h以便访问printf函数。
  • 程序通过读取环境变量来获得Web服务器提供的参数。CGI程序利用getenv读取SERVER_NAME变量,并把其值包含在HTML文档中。程序包含stdlib.h以便访问getenv函数。

本例中的count变量退化了;CGI程序执行单个请求,所以请求数总是1。在FastCGI例子中该变量会更有意思。

相应的FastCGI是examples/tiny-fcgi.c

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

void main(void)
{
int count = 0;
while(FCGI_Accept() >= 0)
printf("Content-type: text/html\r\n"
"\r\n"
"<title>FastCGI Hello!</title>"
"<h1>FastCGI Hello!</h1>"
"Request number %d running on host <i>%s</i>\n",
++count, getenv("SERVER_NAME"));
}

该微型FastCGI程序的主要特性是:

  • 程序构造为通过调用函数FCGI_Accept开始的循环。在新请求到达前FCGI_Accept函数一直阻塞程序的执行。程序包含fcgi_stdio.h以便访问FCGI_Accept函数。
  • 在循环内部,FCGI_Accept创建一个CGI兼容的世界。printfgetenv操作恰如CGI程序中一样。本微型程序没用到的stdinstderr操作也恰如CGI程序中一样。

每次通过循环,count变量都递增,所以每次程序都显示不同的请求数。一旦你已经构建并运行,你可用浏览器中的刷新按钮示范这一点。

构建程序

如果你能构建examples/tiny-cgi.c,则构建examples/tiny-fcgi.c对你来说将会很容简单。你需要:

  • 把含有fcgi_stdio.h头文件的目录加入编译器的包含搜索路径。套件调用该目录的include
  • 把库libfcgi.a加入链接器的命令行,以便链接时它会被搜索。libfcgi.a库实现了在fcgi_stdio.h中定义的函数。套件访问含有该libfcgi库的目录。
  • 确定你的平台上的链接器是否缺省搜索伯克利socket库,并且如果不是,则增加链接器指令强制这种搜索。

构建这两个程序的Makefile可见examples/Makefile(由configure创建)。Autoconf处理平台依赖的链接问题;要知道如何做的,分析configure.inexamples/Makefile.in

运行程序

第4章全都是关于如何运行FastCGI应用的。

你能用CGI运行同fcgi_stdio库一起构建的应用程序。FCGI_Accept函数测试其环境以确定应用是如何被调用的。如果是作为CGI程序被调用,则首次访问FCGI_Accept实际上是个空操作,而且第二次访问返回-1。结果是请求循环消失了。

当然,当FastCGI应用使用CGI运行时,它得不到FastCGI的好处。例如,应用在给单个请求提供了服务后退出,这样它不能维持缓存的信息。

实现细节

fcgi_stdio.h首先包含stdio.h,然后定义宏以替换原来在stdio.h中定义的所有类型和例程,通过这种方式起作用。(stdio.h定义了几个与FILE *无关的例程,例如sprintfsscanffcgi_stdio.h不会替换它们。)例如,FILE变成FCGI_FILEprintf 变成FCGI_printf。如果阅读fcgi_stdio.h或者在预处理后分析C源代码,你将只看到这些新名字。

这种实现技术的一些结果是:

  • 在一些平台上,如果你在包含fcgi_stdio.h之后包含stdio.h,执行将会中断,因为stdio.h常常为函数定义类似getcputc的宏。幸运的是,在多数平台上,stdio.h通过靠近文件顶部的行实施保护以防多次包含,这些行看起来像
        #ifndef _STDIO_H
    #define _STDIO_H

    用于多次包含防护的特殊符号,本例中是_STDIO_H,因平台而异。只要你的平台针对多次包含对stdio.h进行保护,你就能不管这个问题。

  • 如果你的应用传递FILE *到库中实现的函数中,且你有库的源代码,则你会想要包含fcgi_stdio.h重新编译这些库。多数C编译器提供命令行选项用于在将要编译的程序中包含头文件;使用这样的编译器特性允许你不改变源码来重建你的库。例如gcc命令行
        gcc -include /usr/local/include/fcgi_stdio.h wonderlib.c

    促使gcc在读取模块wonderlib.c以前就包含fcgi_stdio.h

  • 如果你的应用传递FILE *到库中实现的函数中,但你没有库的源代码,则你需要在包含fcgi_stdio.h以前为这些库包含头文件。你不能向库实现的任何函数传递FCGI_Accept产生的stdinstdoutstderr流。你能向库函数传递Unix文件流,只要遵循这个模式:
        FILE *myStream = fopen(path, "r");
    answer = MungeStream(FCGI_ToFile(myStream));

    这里的MungeStream是你不能重新编译的库函数,FCGI_ToFile是把FCGI_FILE *转换为FILE *的宏。宏FCGI_ToFilefcgi_stdio.h中定义。

转换CGI程序

把CGI程序转换为FastCGI程序的主要任务是分离代码,从每次请求都需要运行的代码中分离出只需要执行一次的初始化程序的代码。在我们的微型例子中,初始化count变量在循环外面,而递增count变量在内部。

保持应用状态可能是个问题。你必须确保在处理一个请求中创建的任何应用状态不会无意识地影响后来的请求。FastCGI通过缓存提供有效的应用性能提升的可能;让缓存正确地运转取决于你。

内存泄漏可能是个问题。很多CGI程序不用担心内存泄漏,因为程序不会运行足够长的时间使之膨胀到构成问题。当转换到FastCGI时,你能使用类似Purify的工具从纯软件(Pure Software)来发现和修正内存泄漏,也能从Geodesic系统(Geodesic System)运行类似Great Circle的C垃圾收集器。

局限

当前fcgi_stdio库提供的兼容性存在一些限制:

  • 该库没提供FastCGI版本的函数fscanfscanf。如果你要把fscanfscanf应用到FastCGI程序的stdin上,工作区将会读取行或其他自然的单元到内存中,然后调用sscanf。如果你要把fscanf应用到Unix文件流,工作区将遵循模式:
        FILE *myStream = fopen(path, "r");
    count = fscanf(FCGI_ToFile(myStream), format, ...);

参考文献

FCGI_Accept man页doc/FCGI_Accept.3以传统形式描述了该函数。

FCGI_Finishdoc/FCGI_Finish.3),FCGI_SetExitStatusdoc/FCGI_SetExitStatus.3)和FCGI_StartFilterDatadoc/FCGI_StartFilterData.3)man页阐释了没有在上面说明的fcgi-stdio库的能力。

3.2 使用fcgiapp

fcgiapp库是FastCGI的第二个C库。它不提供fcgi_stdio那样高度的源代码兼容性;作为回报,它没有大量地使用#definefcgi_stdio实现为fcgiapp之上的薄层。

使用fcgiapp库构建的应用不能作为CGI程序运行;那个特性在fcgi_stdio层提供。

fcgiapp中定义的函数使用前缀FCGX_命名,而不是FCGI_。例如,FCGX_Acceptfcgiapp版的FCGI_Accept

fcgiapp库的文档采取在头文件include/fcgiapp.h中的大量的注释的形式。示例程序examples/tiny-fcgi2.cexamples/echo2.c示范如何使用fcgiapp

3.3 使用Perl和Tcl

A major advantage of the FastCGI approach to high-performance Web applications is its language-neutrality. CGI scripts written in popular languages such as Perl and Tcl can be evolved into high-performance FastCGI applications.

We have produced FastCGI-integrated Perl and Tcl interpreters. Doing so was easy, since Perl and Tcl are conventional C applications and fcgi_stdio was designed for converting conventional C applications. Essentially no source code changes were required in these programs; a small amount of code was added in order to make FCGI_Accept and other FastCGI primitives available in these languages. And because these interpreters were developed using fcgi_stdio, they run standard Perl and Tcl applications (e.g. CGI scripts) as well as FastCGI applications.

See the fastcgi.com Web page for more information about the Perl and Tcl libraries.

Here are the Perl and Tcl versions of tiny-fcgi:

#!./perl
use FCGI;
$count = 0;
while(FCGI::accept() >= 0) {
print("Content-type: text/html\r\n\r\n",
"<title>FastCGI Hello! (Perl)</title>\n",
"<h1>FastCGI Hello! (Perl)</h1>\n";
"Request number ", ++$count,
" running on host <i>";$env(SERVER_NAME)</i>");
}
#!./tclsh
set count 0
while {[FCGI_Accept] >= 0 } {
incr count
puts -nonewline "Content-type: text/html\r\n\r\n"
puts "<title>FastCGI Hello! (Tcl)</title>"
puts "<h1>FastCGI Hello! (Tcl)</h1>"
puts "Request number $count running on host <i>$env(SERVER_NAME)</i>"
}

Converting a Perl or Tcl CGI application to FastCGI is not fundamentally different from converting a C CGI application to FastCGI. You separate the portion of the application that performs one-time initialization from the portion that performs per-request processing. You put the per-request processing into a loop controlled byFCGI::accept (Perl) or FCGI_Accept (Tcl).

3.4 使用Java

Java不只适合于基于浏览器的小程序片。它已然适合编写一些Web服务器应用,而且随着Java编译器和其他Java工具的改进,它的应用范围将会增长。Java的模块、垃圾收集和线程对于编写常驻的应用服务器尤其有价值。

FCGIInterface类给Java应用提供设施,就像fcgi_stdio为C应用提供的那样。使用该库,你的Java应用能利用CGI或FastCGI运行。

套件中包括关于结合Java和FastCGI的独立的自带文档。FastCGI的源代码包含在目录java/src中,已编译代码在java/classes中。

这是Java版的tiny-fcgi

import FCGIInterface;

class TinyFCGI {
public static void main (String args[]) {
int count = 0;
while(new FCGIInterface().FCGIaccept()>= 0) {
count ++;
System.out.println("Content-type: text/html\r\n\r\n");
System.out.println(
"<title>FastCGI Hello! (Java)</title>");
System.out.println("<h1>FastCGI Hello! (Java)</h1>");
System.out.println(
"request number " + count + " running on host <i>" +
System.getProperty("SERVER_NAME") + "</i>");
}
}
}

4. 运行应用

4.1 使用支持FastCGI的Web服务器

当前支持FastCGI的Web服务器的列表见fastcgi.com网页。

一些支持FastCGI的Web服务器执行FastCGI应用的管理。你不需要启动和停止FastCGI应用;Web服务器会照看它。如果应用进程崩溃了,Web服务器重启它。

Web服务器通过新的配置指令支持FastCGI。由于这些指令是特定于服务器的,从每种服务器自带的文档获得更多信息。

4.2 在任何Web服务器上使用cgi-fcgi

程序cgi-fcgi允许你利用任何支持CGI的Web服务器运行FastCGI应用。

这里是cgi-fcgi如何运转的。cgi-fcgi是使用Unix域或TCP/IP socket与FastCGI应用通信的标准CGI程序。cgi-fcgi接受路径名或正监听的socket的主机/端口名为参数,并且连接到在那个socket上监听的FastCGI。然后cgi-fcgi把CGI环境变量和stdin数据转送到FastCGI应用,并把stdoutstderr数据从FastCGI应用转送到Web服务器。当FastCGI应用通知响应结束时,cgi-fcgi刷新其缓冲器并退出。

很显然,cgi-fcgi不如集成了FastCGI支持的服务器:

  • 通信比避免了每次FastCGI请求都fork/exec的Web服务器要慢。
  • cgi-fcgi不会执行应用管理,你需要自己提供。
  • cgi-fcgi只支持响应角色。

但是cgi-fcgi允许你开发这样的程序,它们在连接之间在内存中保持状态,这样做常常提供了超过常规的CGI的主要性能提升。而且你开发的使用cgi-fcgi的所有应用将能与集成了FastCGI支持的Web服务器合作。

在案例examples/tiny-fcgi应用中,文件examples/tiny-fcgi.cgi示范一种用cgi-fcgi运行典型的应用的方式:

    #!../cgi-fcgi/cgi-fcgi -f
-connect sockets/tiny-fcgi tiny-fcgi

在多数Unix平台上,执行本命令解释器文件会以-fexamples/tiny-fcgi.cgi为参数运行cgi-fcgi。(注意:在一些Unix平台上,包括HP-UX,命令解释器文件的第一行不能含有超过32个字符,包括换行符在内;你可能需要在类似/usr/local/bin的标准位置安装cgi-fcgi应用,或者在含有你的应用的目录中创建到cgi-fcgi的符号连接。)cgi-fcgi程序读取本命令解释器文件并连接其监听的socket为examples/sockets/tiny-fcgi的FastCGI应用。

继续这个例子,如果cgi-fcgi的连接尝试失败了,它创建一个新进程来运行程序examples/tiny-fcgi并监听socketexamples/sockets/tiny-fcgi。然后cgi-fcgi重新进行连接尝试,现在应该会成功。

cgi-fcgi程序还有两种操作方式。其中一种它连接到应用但是不启动它们;另一种它启动应用但是不连接它们。当使用TCP/IP时这些方式是必需的。cgi-fcgi man页doc/cgi-fcgi.1,告讲述全部情况。

要用cgi-fcgi运行示例应用,启动你的Web服务器并给它fcgi-devel-kit目录为其URL空间的根。如果运行你的Web服务器的机器称为bowser,并且你的服务器运行在端口8888上,你当打开URL http://bowser:8888/index.html以到达套件的索引页。现在索引页上通过cgi-fcgi运行示例应用的链接应该是有效的。

5. 已知的问题

On Digital UNIX 3.0 there's a problem with Unix domain listening sockets on NFS file systems. The symptom when using cgi-fcgi is an exit status of 38 (ENOTSOCK: socket operation on non-socket), but cgi-fcgi may dump core in this case when compiled optimized. Work-around: Store your Unix domain listening sockets on a non NFS file system, upgrade to Digital UNIX 3.2, or use TCP sockets.

On AIX there's a problem with shared listening sockets. The symptoms can include application core dumps and kernel panic. Work-around: Run a single FastCGI application server per listening socket.

6. 获得支持

邮件列表fastcgi-developers用于开发FastCGI应用中的问题的讨论。其主题包括支持FastCGI的Web服务器或它们的变更的公告,新应用库或它们的变更的公告,已知bug的公告,FastCGI应用编程中的设计折衷方案的讨论,以及开发计划和经验的讨论。要加入列表,参阅http://fastcgi.com/fastcgi-developers

在FastCGI主页http://www.fastcgi.com上有邮件存档的链接。


© 1996, Open Market, Inc. / mbrown@openmarket.com

回目录 [翻译]FastCGI开发者套件

分享到:
评论

相关推荐

    护卫神PHP套件FastCGI版PHP v5.4.zip

    护卫神PHP套件FastCGI版PHP,自动安装配置PHP MySQL PhpMyAdmin等Web环境的软件,完全免费。 护卫神PHP套件FastCGI版PHP安装内容如下:  (1)、PHP 5.4.31(FastCGI模式)  (2)、MySQL 5.5.19.0(MyISAM...

    fastcgi c++

    fastcgi fastcgi fastcgi fastcgi fastcgi

    护卫神·PHP套件 PHP5.6.9 FastCGI版

    护卫神PHP套件FastCGI版PHP,自动安装配置PHP+MySQL+PhpMyAdmin等Web环境的软件,完全。 护卫神PHP套件FastCGI版PHP安装内容如下: PHP 5.6.9(FastCGI模式) MySQL 5.6.14(MyISAM模式) MyODBC 5.2.6 Php

    护卫神·PHP套件集合包.zip

    PHP5.2(FastCGI-32bit)、PHP5.3(FastCGI-32bit)、PHP5.4(FastCGI-32bit)、PHP5.5(FastCGI-64bit)、PHP5.6(FastCGI-64bit)、PHP7.0(FastCGI-64bit)、PHP7.1(FastCGI-64bit)、 其中5.6版本最通用。 ...

    nginx+fastcgi编译与移植手册

    nginx fastcgi 编译与移植 手册 nginx fastcgi 编译与移植 手册 nginx fastcgi 编译与移植 手册

    FastCGI 下载FastCGI for IIS6下载 1.5(32位&64位)

    FastCGI 1.5 for IIS6,fastcgi.dll本身不具备解析脚本的能力他的作用是调度php的解析程序处理PHP。内含32位和64位两个版本。

    护卫神·PHP套件(FastCGI-PHP5.3.28-32bit)

    护卫神·PHP套件(FastCGI-PHP5.3.28-32bit)

    IIS FASTCGI安装程序

    用于IIS的FASTCGI模块安装包,版本1.5RC

    Java的FastCGI网关 jFastCGI

    Java的FastCGI网关 jFastCGI

    fastcgi头文件和库

    fastcgi头文件和库

    mod_fastcgi-2.4.6.tar.gz

    [原创] Redhat 上 FastCGI 安装与配置 软件包 相关软件包: httpd httpd-devel fcgi-2.4.0.tar.gz mod_fastcgi-2.4.6.tar.gz 请仔细阅读其中的README 配置httpd.conf: LoadModule fastcgi_module modules/mod_...

    FastCGI SDK

    FastCGI的官方开发包,包含C, C++, Perl, Java, 库等文档与开发资源。(FastCGI官网已经打不开了 QwQ)

    lighttpd fastcgi

    5.注意fastcgi程序编译方式 进入cgi-bin目录中编译方式如下 2228 gcc -o caoft.fcgi echo.c -lpthread -lfcgi 2229 gcc -o caoft.fcgi size.c -lpthread -lfcgi 2230 gcc -o caoft.fcgi threaded.c -lpthread -...

    FastCGI手册

    FastCGI规范和详细的例子

    fastcgi.zip

    fastcgi2.4.1 安装: ./configure make make install 现在官网已经没有了

    Apache FastCGI 配置过程小记

    对于配置过程其实比较简单只是纠结于在win32环境下apache 模块 mod_fcgid由于管道问题无法达成,而mod_fastcgi模块则可以达成

    FastCGI Extension for IIS

    FastCGI是可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。传统的CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器保持在内存中并接受FastCGI进程管理器调度,...

    win2003下搭建FastCGI php5.2.17

    所以被迫无奈重装服务器,在网上浏览的时候无意的发现PHP5.3的全新特效及改进,原有的ISAPI方式解析PHP脚本已经不被支持,PHP从5.3.0以后的版本开始使用微软的FastCGI模式,虽说PHP 5.3发布的Windows版已经不支持...

    swift-PerfectFastCGI-Perfect的FastCGI服务器

    Perfect FastCGI - Perfect的FastCGI服务器

    用VC++开发FastCGI+MySQL的基本源代码

    刚入门初始化,用VC++开发 FastCGI + MySQL 构建的工程文档,含源代码和MySQL 连接DLL

Global site tag (gtag.js) - Google Analytics