写点旧东西,最近一直再看 django
源代码,发现对运行机制还是蛮感兴趣的(太懒了,这块一直没有深入研究过),因为扯到了 wsgi
规范,就想到了原始的 cgi 接口规范
, 这里就先写写我对 cgi 接口规范
的认知,同时也为了下次组内分享预留个开头。
1991年8月6日,这是个伟大的日子,web 页面首次在因特网上登场,回去早期,web 服务器主要是用来共享静态数据,只是简单的响应浏览器发来的 http
请求,并将存储在服务器上的静态文件返给浏览器。所以早期的 web 服务器的结构如下:
因为早期的用户只有高大上的科学家,这样的架构无可厚非,毕竟只是为了共享自己的一些资料,方便交流。
随着时间的推移,互联网逐渐平民化,技术在进化,网站越来越复杂,远古时代的架构已经不能满足用户的需求。针对用户强烈的动态交互需求,另外一方面,服务器自己并不能运行类似 python
脚本文件,既然服务器没法做,只能联合第三方一起搞,此时与第三方通信还是需要有个约定的,服务器给第三方参数,第三方返回给服务器结果,最后服务器把结果返回给客户端,此后名扬江湖的 CGI(Common Gateway Interface)
诞生了。
CGI
定义了 Web服务器
与外部应用程序之间的通信接口标准,因此 Web服务器
可以通过 CGI
执行外部程序,让外部程序根据Web请求内容生成动态的内容。 Perl
因为跨操作系统和易于修改的特性成为 CGI
的主要编写语言。当然, CGI
可以用任何支持标准输入输出和环境变量的语言编写,比如 Shell
脚本, C/C++
语言,只要符合接口标准即可。比如你用 C
语言编写 CGI
程序,你把希望返回的 HTML
内容通过 printf
输出就可以发送给 Web服务器
,进而返回给用户。
服务器与 CGI 脚本通信是通过标准的输入输出和环境变量完成的。
浏览器通过HTML表单或超链接请求指向一个 CGI
应用程序的 URL
。
服务器收发到请求。
服务器执行所指定的 CGI
应用程序。
CGI
应用程序执行所需要的操作,通常是基于浏览者输入的内容。
CGI
应用程序把结果格式化为网络服务器和浏览器能够理解的文档(通常是 HTML网页
)。
web 服务器
把结果返回到浏览器中。
CGI 模式性能
CGI
的跨平台性能极佳,几乎可以在任何操作系统上实现。 CGI
方式在遇到连接请求(用户请求)先要创建 CGI
的子进程,激活一个 CGI
进程,然后处理请求,处理完后结束这个子进程。这就是 fork-and-execute
模式。所以用 CGI
方式的服务器有多少连接请求就会有多少 CGI
子进程,子进程反复加载是 CGI
性能低下的主要原因。当用户请求数量非常多时, 会大量挤占系统的资源如内存,CPU 时间
等,造成效能低下。
web 服务器: lighttpd
,脚本语言: python
, 平台: mac
#!/usr/bin/env python # -*- coding: UTF-8 -*- import os print "Content-Type: text/plain;charset=utf-8/n" print os.environ.get('SERVER_PROTOCOL') print os.environ.get('QUERY_STRING') print "Hello World!"
输入 url 如下:
http://127.0.0.1:8080/cgi-bin/test.py?name=kycool&id=0989238423
返回结果:
HTTP/1.1 name=kycool&id=0989238423 Hello World!
debug 工具中打开
通过例子就会发现,运行模式如下:
例子较为简单,复杂的业务如果写完,估计自己可以造个框架轮子了,因为 CGI
性能低下的原因, python
相关的 wsgi
出现了......