web架构的演化 - 从CGI到WSGI

web架构的演化 - 从CGI到WSGI_第1张图片
网络截图

web架构的的演进:

1. 静态网页时的设计:

web Server + FileSystem

2. 动态网页时的设计:

2.1. 抽象出gateway interface 也就是 web服务器和 web应用程序之间的接口规范。

这种接口规范规定了web服务器:

  1. 如何将request参数化后传递给 web应用程序,web应用如何将它的输出发送给webserver,
  2. 以及如何调用web application。
    CGI WSGI 都是webserver 与 web应用程序的接口规范:

例:
web Server + CGI + shell + DB
web Server + FastCGI + shell php + DB
web server + Serverlet + java + MVC
web Server + WSGI + Python + MVC
web Server + NODE.JS + js + db

CGI: rfc3875

2.2. 抽象出 framework

找出出后端web application开发时的通用的固定的流程, 抽象出开发框架。web框架的使用者来说,他们并不关心如何接收 HTTP 请求,也不关心如何将请求路由到具体方法处理并将响应结果返回给用户。只用按照接口规范的要求实现相关的business logic。框架建立的统一的基础设施, 它屏蔽了与业务逻辑无关的网络连接处理细节, 是开发者专注于业务本身而不是一般性的事物

例:

webserver + WSGI + django

2.3. 抽象出 application server

application server 为web application提供运行容器和调度管理。这使得 webserver 只专注于响应用户请求, application server 则web application的运行环境。

例如 fastcgi 中规定了一种进程管理器, 用来维护cgi程序的解释器进程池, 这就是AppServer的雏形。

webserver +uwsgi(线路规程) + uWSGI + WSGI (接口规范,不是api)+ django(framework)

(Nginx + uwsgi + uWSGI Server + WSGI + django)

2.4 抽象出线路规程(协议)

线路规程规定了webServer 与 App server 如何进行通信
uwsgi 线路规程, 实现Webserver与 uWSGI 进程的通信。

FASTCGI 规定了Webserver 如何与 进程管理通信

Web server

对于传统的客户端 - 服务器架构,其请求的处理过程是,客户端向服务器发送请求,服务器接收请求并处理请求,然后给客户端返回响应。在这个过程中,服务器的作用是:

  1. 接收请求
  2. 处理请求
  3. 返回响应

Web服务器是一类特殊的服务器,其作用是主要是接收 HTTP 请求并返回响应。提起 web服务器大家都不会陌生,常见的 web服务器有 Nginx,Apache,IIS等。在上图1的三层结构中,web服务器是最先接收用户请求的,并将响应结果返回给用户。

Application Server

随着web应用的动态化, 传统的静态web server对于动态内容无能为力,CGI技术用于生成动态内容。 但是CGI技术的性能很差, 主要是因为对于每个请求都要创建一个进程来运行cgi程序, 而进程创建的开销比较大, 严重拖慢了响应速度。随后fastcgi技术出现了, 为了解决cgi技术中存在的问题, fastcgi使用一种进程管理器, 用来维持一个进程池,提前创建进程,从而提高了响应速度。

web架构的演化 - 从CGI到WSGI_第2张图片
网络截图

uWSGI 是一个 WSGI 协议的实现,

uWSGI 包括四个部分:

  • 实现了 uwsgi协议, 与web server 通信
  • web server 内置支持协议模块:
  • application server协议支持模块: 实现了 WSGI, 与 python 框架交互
  • 进程控制程序: 为web request 的处理创建工作进程

为什么有了uWSGI为什么还需要nginx?因为nginx具备优秀的静态内容处理能力,然后将动态内容转发给uWSGI服务器,这样可以达到很好的客户端响应。 Nginx 通过 httpuwsgimodule 与 uWSGI 服务器进行交换

uwsgi 是一种链路协议.类似于fastcgi协议, 用于httpServer与ApplicationServer通信。

为什么使用uwsgi来隔离 framework 和webserver?
如果在nginx中直接用WSGI, 那么 nginx线程中就要启动python解释器,

From stack over flow
It is generally best to run Python in a separate process from your main web server. That way, the web server can have lots of tiny threads that serve static content really fast, while your separate Python processes will be big and heavyweight and each be running their own Python interpreter. So plain WSGI is bad, because it bloats every single one of your nginx threads with a big Python interpreter. Using flup or gunicorn or uWSGI behind nginx is much better, because that frees up nginx to simply serve content, and lets you choose how many tiny light nginx threads to run, independently of your choice of how many heavyweight Python threads you bring up to serve dynamic content. People seem very happy with gunicorn at the moment, but any of those three options should work fine.

Web框架层

Web框架的作用主要是方便我们开发 web应用程序,HTTP请求的动态数据就是由 web框架层来提供的。

WebFrameWork 是怎么方便web app开发的?

首先, 在没有框架帮助的情况下, 我们要实现 业务逻辑, 面对不同的请求如何路由到具体的业务逻辑, 也就是路由逻辑,已经数据如何访问, 视图如何设计等等问题。

以MVC开发模式来说, 我们要实现MVC 这三个方面的各种细节。 每次开发一个新的app都有大量重复的工作要做。 这些重复的固定的工作与流程被抽象出来,每次只用开发相应的业务逻辑, 大大加快了web开发的速度。

常见的 web框架有Flask,Django等,我们以 Flask 框架为例子,展示 web框架的作用:

from flask import Flask 
app = Flask(__name__) 
@app.route('/hello')  
def hello_world(): 
  return  'Hello World!'  
if __name__ == '__main__': 
  app.run(host='0.0.0.0', port=8080)

以上简单的几行代码,就创建了一个 web应用程序对象 app。app 监听机器所有 ip 的 8080 端口,接受用户的请求连接。我们知道,HTTP 协议使用 URL 来定位资源,上面的程序会将路径 /hello 的请求交由 hello_world 方法处理,hello_world 返回 ‘Hello World!’ 字符串。对于 web框架的使用者来说,他们并不关心如何接收 HTTP 请求,也不关心如何将请求路由到具体方法处理并将响应结果返回给用户。Web框架的使用者在大部分情况下,只需要关心如何实现业务的逻辑即可。

WSGI层

WSGI 不是服务器,也不是用于与程序交互的API,更不是真实的代码,WSGI 只是一种接口,它只适用于 Python 语言,其全称为 Web Server Gateway Interface,定义了 web服务器和 web应用之间的接口规范。也就是说,只要 web服务器和 web应用都遵守WSGI协议,那么 web服务器和 web应用就可以随意的组合。

下面的代码展示了 web服务器是如何与 web应用组合在一起的。

def application(env, start_response): 
  start_response('200 OK', [('Content-Type', 'text/html')]) 
  return [b"Hello World"]
  • 方法 application由 web服务器调用,参数env,start_response 由 web服务器实现并传入。
  • env是一个字典,包含了类似 HTTP_HOST,HOST_USER_AGENT,SERVER_PROTOCO 等环境变量。
  • start_response则是一个方法,该方法接受两个参数,分别是status,response_headers。

application方法的主要作用是,设置 http 响应的状态码和 Content-Type 等头部信息,并返回响应的具体结果。

上述代码就是一个完整的 WSGI 应用,当一个支持 WSGI 的 web服务器接收到客户端的请求后,便会调用这个 application方法。WSGI 层并不需要关心env,start_response 这两个变量是如何实现的,就像在 application 里面所做的,直接使用这两个变量即可。

Web 服务器与应用程序之间显然要进行交互,这时就出现了很多 Web 服务器与应用程序之间交互的规范,最早出现的是 CGI,后来又出现了改进 CGI 性能的FasgCGI,Java 专用的 Servlet 规范,Python 专用的 WSGI 规范等等。有了统一标准,程序的可移植性就大大提高了。这里我们只介绍 WSGI。

你可能感兴趣的:(web架构的演化 - 从CGI到WSGI)