除了fastcgi之外还有一些其他的相关名词:cgi、fastcgi、wsgi。gi是gateway interface的缩写,所以前面3个都是属于一个大类型、一种规范;至于具体规范的谁、怎么规范的会有各自的不同。
cgi和fastcgi规范的都是http server与对应解释程序的之间的通信;比如apache与python、nginx与python等。只是它们规范的方式不一样;cgi是最原始的公用通信协议,它规定的是每次有请求就会新起一个应用进程来处理,在请求结束后关闭应用进程【导致反复新起进程、关闭进程,消耗系统资源】;fastcgi是cgi的扩展,目的就是解决cgi的这种资源消耗的弊端,它规定http server启动时同时启动了若干个应用进程【应用进程数可配置】,然后常驻内存等待接收请求并处理,处理完请求后继续等待不会退出。
由于cgi是直接对接那些有标准输出的应用即可,sh、tcl等;所以使用cgi协议时可以直接调用应用程序来启动应用进程,在执行结束后获得标准输出作为返回的html内容。而fastcgi则实现了固定的通信机制,它不能通过直接调用应用程序来执行结果,所以就需要一个支持fastcgi协议的web server/gateway来与之通信;这样请求就会通过fastcgi进程传输给特定的web请求处理程序【flup】,这个程序会根据业务逻辑处理请求并返回结果;最终通过fastcgi返回给前端的http server。
然后再看看fastcgi和wagi的关系,其实它们没有关系,虽然都是规范,但它们规范的不是一个地方,所以没有直接可关联的,唯一可关联的就是,有些程序会同时实现了这2种协议,比如:flup
fastcgi是通信规范,规定了通信的方式、协议;而wsgi是接口规范,规定了函数定义、调用。
最后还有一个spawn-fcgi,这是一个fastcgi进程管理器【最初是lighttpd的子模块,lighttpd也是一个与nginx类似的http server】,作用等同于其它http server中的fastcgi模块;只不过它实现的比较好、在某些情况下的效能会比较高,所以被大家分离出来广泛使用,以致独立出来作为一个项目。【所以就有了apache+spawn-fcgi、nginx+spawn-fcgi等】
下面总结了一张图,大概覆盖了上面所说的。
python、webpy、flup、nginx分别默认安装即可,完成后测试各软件默认安装是否正常,如果正常则开始修改nginx配置,添加配置一个虚拟主机,内容如下:
server{ listen 80; server_name www.test.com; root /path/to/web/root; access_log logs/www.xx.com.access.log main; location / { include fastcgi_params; ##包含默认的fastcgi参数 fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; fastcgi_pass 127.0.0.1:9002; ##把请求通过fastcgi传送给本机的9002端口 } location /static/ { #配置静态文件的访问 if (-f $request_filename) { #如果请求文件名是一个文件 rewrite ^/static/(.*)$ /static/$1 break; #直接跳转到对应的资源,中断fastcgi的传输 } } }
完了重载nginx配置,nginx -s reload,为了保险起见,也可以如下操作:
1、先测试一下nginx.conf文件:./nginx -t
2、没有问题在停止服务 ./nginx -s stop
3、启动服务 ./nginx
此时可以直接访问www.test.com,如果出现如下页面则表示配置nginx的fastcgi格式正确,可以继续后面的配置
#!/usr/bin/env python # -*- coding: utf-8 -*- import web urls = ("/.*", "hello") app = web.application(urls, globals()) class hello: def GET(self): return 'Hello, world!' if __name__ == "__main__": app.run()运行python程序,python code.py 9002 fastcgi
#!/usr/bin/env python # -*- coding: utf-8 -*- import web urls = ("/.*", "hello") app = web.application(urls, globals()) class hello: def GET(self): return 'Hello, world!' if __name__ == "__main__": web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr) ##这行是新增的 app.run()