概念较多,很多地方暂没法求甚解,只能做一些感性的介绍,说的不清楚或有错误的地方大家再讨论。
以下代码可能有省略。
1. HTTP 基本原理
2. 动态内容处理
往往我们看到的网页都是用各种语言动态生成的,如 PHP 语言和使用 python 语言的 django 框架。
上述配置使用了 fastcgi 的方式,由 web server 将请求转交给监听在 8000 端口的 fastcgi 服务器,fastcgi 服务器处理后返回结果给 web server,再由 web server 返回给浏览器,流程如下图(图片源自《python 核心编程》)。以下代码可能有省略。
1. HTTP 基本原理
- 服务器上需要运行 web server 软件(下面以 nginx 为例,常见的还有 apache、lighttpd),nginx 以守护进程模式运行后,默认监听 tcp 的 80 端口,准备响应客户端的请求。
- 客户端(这里指浏览器)需要访问站点时,浏览器打开本地一个临时端口,主动向服务器上的 80 端口建立 tcp 连接,以和 nginx 进程进行通信。
连接建立后,浏览器发起请求
GET /index.html HTTP/1.1
HOST: test.com- nginx 响应请求,这里客户端请求的是静态文件,直接返回即可;对于动态内容的请求,见下一小节
HTTP/1.1 200 OK
Content-type: text/html
Date: Mon, 26 Apr 2010 20:23:51 GMT
Server: nginx/0.6.35
1e24
Content-type: text/html
Date: Mon, 26 Apr 2010 20:23:51 GMT
Server: nginx/0.6.35
1e24
<html>
<head>
<title>首页</title>
<script type="text/javascript" src="http://test.com/jiaoben.js"></script>
</head>
..........................
..........................
</html>
0
Connection closed by foreign host.
此响应包含 http header 和 html文本 两大部分。
Connection closed by foreign host.
此响应包含 http header 和 html文本 两大部分。
浏览器解析响应。对于 html 响应中包含的元素,需要进行新的一次请求,如上例中的 js 文件;若浏览器和服务器软件协商打开 keepalive 模式,则此次新的请求可以在已有的 tcp 连接上进行,否则需要重新三次握手来建立新连接。
2. 动态内容处理
往往我们看到的网页都是用各种语言动态生成的,如 PHP 语言和使用 python 语言的 django 框架。
- 用户输入 http://www.test.com/ 这样的 url,请求网站的根目录。
- 对于 php,配置服务器,指定默认的响应文件,如 index.php,并且配置以何种方式处理以 .php 结尾的文件。
location / {
index index.php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000; # 我们以这种方式来处理 php 文件,某程序监听了本机的9000端口。
}
}
location 后面跟的是相对目录,即 url 中 host 后面的目录部分。 对于 django 这种提供较完善解决方案的框架,它靠匹配 url 来进行决策,我们就不指定默认文件了,把所有请求全部交给某程序处理,配置如下。
location / {
fastcgi_pass 127.0.0.1:8000;
}
我们还可以控制让静态文件直接由 nginx 返回而不让 django 处理。
location /static/ {
alias /var/www/djangoproject/static/;
}
2.1 CGI & FASTCGI
apache、lighttpd 等 web server 软件都支持传统的 CGI,在简单配置后,将如下脚本(hello.py)放入指定目录。
#!/usr/bin/python
print "Content-type: text/html"
print ""
print ""
print "Hello World"
print ""
print "Content-type: text/html"
print ""
print ""
print "Hello World"
print ""
然后访问 http://test.com/cgi-path/hello.py 就能看到相应内容了。
其处理的过程大概是这样:对于每一个请求,创建一个新进程,然后初始化并执行上述程序,最后将数据返回给 web server 并释放内存资源。
后来出现的 fastcgi 方式对传统方法进行了改进,首先启动一个或多个 fastcgi 进程(可理解为 fastcgi 服务器/网关),然后对于每一个浏览器请求,web server 去连接已经启动好的 fastcgi 进程并转发请求,待得到结果后关闭此连接。
当然 fastcgi 方式和协议需要服务器软件支持,上述 3 种 web server 软件都支持,有关 fastcgi 好处和性能的讨论这里不再介绍,网上一抓一大把。
2.2 django
对于 django,概念有些拗口,注意区分 fastcgi 方式和协议的区别。
- WSGI,Web Server Gateway Interface,是 Python 应用程序和 Web 服务器之间的一种接口,能以 fastcgi 作为两者通信的底层协议规范
- django 能以 fastcgi 方式(而不是协议)启动自带的服务器进程,此进程叫做 WSGIServer,该 server 由 python 的 flup 库提供,具体采用什么协议可以在 manage.py runfcgi 的 protocol 参数中指定,注意除了fastcgi 协议(参数中写为 fcgi)还能选择 scgi 等其他协议。
- 现在我们知道 WSGIServer 就是上面介绍的 fastcgi 服务器/网关,它监听一个 tcp 端口(还能以 unix socket 方式监听,这里不再介绍),也就是前面配置文件中的 8000 端口。
- 在启动 WSGIServer 的时候需要指定一个 WSGIHandler,这个 Handler 关联了请求(request)和我们写的 django 应用,在每次请求到来时 Handler 会加载应用的 settings、middleware 和 环境变量,然后请求经 url 解析并交给指定 views 处理,最终处理结果返回给 WSGIServer。
一些参考:
- django/core/servers/fastcgi.py
- django/core/handlers/wsgi.py
- http://blogs.sun.com/oswald/entry/good_idea_python_with_fastcgi CGI 和 FASTCGI 的区别
- http://osdcpapers.cgpublisher.com/product/pub.84/prod.21 WSGI 入门的 PDF
- http://www.douban.com/note/13508388/ WSGI、flup、fastcgi、web.py的关系
没有评论:
发表评论