Python Web编程概念梳理

Python Web编程概念梳理

主要讲解三个关键字

  1. 服务器
  2. WSGI
  3. 框架

前言

学编程有两种方式,一种是自上而下,一种是自下而上。

自上而下呢就是直接拿一些成熟的框架学习,看完一个简单的教程就能依葫芦画瓢作出一些小项目,比较容易获取成就感。Python Web服务端编程就是这样的,有许许多多成熟的框架,Django,flask,tornado,web.py.......学习一下这些框架的教程就能配合一个前端作出一些小网站。然后随着使用次数的增加,会发现很多的疑惑,去寻找答案,就慢慢的学习了底层的知识,感觉对框架的理解上了一个档次。

自下而上呢就是直接从底层开始学习,拿Python Web开发来说,可以从计算机网络,socket编程等等开始,但这一过程一般来说比较痛苦。

我呢就是自上而下的学习过程。我接触框架之前,掌握的只有python语法,基本的算法和数据结构等一系列学校里的专业课程。(计网当时还没学) 加入一个实验室后,学长就让我们用tornado框架做一个小网站,然后我就按照教程一点一点写,当然是写的很茫然,不知道为什么要引入这个,为什么引入那个,也不知道为什么别人就能给我发请求了。而且框架的那些条条框框根本记不住,每次写都得重新找教程,把一个大概的模板写好,然后开始写业务函数。

写过几个以后,居然觉得怎么这么简单,只要写几个业务函数,功能多就多写几个业务函数(年轻啊)。但是学着学着又觉得不对劲,用了很久就跟刚开始用一样,谈不上提升,因为写来写去都是在写业务函数。(如果有过来人指导我学习方向,一定轻松很多)

服务器

我之前一直不理解为什么需要apache,nginx这些服务器,也不知道他们的作用,因为我觉得python自己就有一些服务器的库,且tornado本身也有个服务器,所以在我之前的概念了,服务器就很模糊甚至不重要。

Python Web包括客户端和服务端,都是通过对系统提供的套接字(socket)编程来实现请求与响应,socket是操作系统提供的接口,但是各种编程语言都对它进行了封装成库,但是没有改变功能,只是是他更易使用。WEB服务器主要就是实现http协议,而http的底层协议是Tcp协议。

一个简单的TCP客户端和服务器

import socket

PORT = 7890

def server():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind('127.0.0.1', PORT)
    sock.listen(5)
    print('listening at port: ', PORT)
    while true:
        sc, sockname = sock.accept()
        data = sc.recv(4096)
        print('received data: ', data)
        sc.sendall(b'hello world')
        sc.close()

def client():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect('127.0.0.1', PORT)
    sock.sendall(b'hi, server')
    reply = sock.recv(4096)
    print('server said: ', reply)
    sock.close()

server通过bind()监听请求,一旦有请求就生成一个套接字与客户端连接,然后双方通过套接字发送信息。(明白大概意思就行,我也不会socket底层编程)

TCP协议是socket已经提供的,web服务器需要做的就是实现http协议以及如何提高服务器的效率,比如单线程,多线程,多进程,异步等等。而Python中有socket库,所以是可以用Python自己实现一个服务器的(只谈可操作性,我不会别人会-_-)。

那用Python写的http服务器与apache这些web服务器有什么区别呢?

apache这些服务器主要是返回静态内容的,我们自己编写的http服务器主要是返回一些动态内容。这里强调一下是主要,因为对于两种服务器来说两种内容都是可以支持的,不过是各有所长。所以都用或者只用一个都是可以的,这取决于不同的Web部署方案。但是apache这种服务器由于只要接受http请求并响应,所以在这方面做了很多优化,使其速度非常快,且更通用。

三种方案

  1. apache这类Web服务器只接受和响应静态请求,将动态请求转发给Python服务器。这样需要运行两个守护进程来监听请求

  2. apache接受全部请求,自己处理静态请求,动态请求调用CGI脚本执行后拿到结果返回。这样只有一个服务器

  3. 不使用apache这类服务器,直接使用Python服务器。

当然服务器的功能还有很多,比如缓存,负载,反向代理,安全等等,所以需要考虑很多方面来决定如何选择所要的服务器。

WSGI

WSGI的全称是Web Server Gateway Interface,即Web服务器网关接口。具体的来说,WSGI是一个规范,定义了Web服务器如何与Python应用程序进行交互,使得使用Python写的Web应用程序可以和Web服务器(包含上面两种)对接起来。WSGI一开始是在PEP-0333中定义的,最新版本是在Python的PEP-3333定义的。(不懂吧,那就继续看)

为什么要有WSGI呢?

一般来说后端是不需要编写服务器的,因为有很多现成的解决方案,所以只需要写一些应用程序来供调用。

目前最广泛的部署方案是:

首先,部署一个Web服务器专门用来处理HTTP协议层面相关的事情,比如如何在一个物理机上提供多个不同的Web服务(单IP多域名,单IP多端口等)这种事情。

然后,部署一个用各种语言编写(Java, PHP, Python, Ruby等)的应用程序,这个应用程序会从Web服务器上接收客户端的请求,处理完成后,再返回响应给Web服务器,最后由Web服务器返回给客户端。

由上一节内容可以知道,服务器有很多种,不同的服务器接口不同,那么采用这种方案,Web服务器与应用程序就需要知道如何交互,就出现了很多规范,最早的一个是CGI,然后有Java专用的Servlet规范以及Python专用的WSGI规范。定义规范就是为了定义统一的标准,提升程序的移植性。

在WSGI中定义了两个角色,Web服务器端称为server或者gateway,应用程序端称为application或者framework。server端接受用户请求后根据规范调用application端。这也是大多数框架里运行时都需要一个application的原因。

application对象定义形式

def app(environ, start_response):
    pass

environ参数是一个Python字典,存放与客户端相关的信息,start_response是一个可调用对象,接受两个必选参数和一个可选参数。

application一个简单的示例

def app(environ, start_response):
    host = environ.get('HTTP_HOST', '127.0.0.1')
    path = environ.get('PATH_INFO', '/')
    if ':' in host:
        host, port = host.split(':', 1)
    if '?' in path:
        path, query = path.split('?', 1)
    headers = [('Content-Type', 'text/plain; charset=utf-8')]
    if environ['REQUEST_METHOD'] != 'GET':
        start_response('501 Not Implemented', headers)
        yield b'501 Not Implemented'
    elif host != '127.0.0.1' or path != '/':
        start_response('404 Not Found', headers)
        yield b'404 Not Found'
    else:
        start_response('200 OK', headers)

框架

从上面那个app的示例代码可以看出,如果我们不使用Web框架,就需要自己根据environ的信息来作一系列的判断,而且这些判断是繁琐的,却意义不大的。

让框架帮我们做完这些苦力活,帮助我们过滤掉与服务不符的主机名,路径以及方法等没用的请求,我们就可以专心的处理业务函数。框架能帮我们将environ分析为一个对象,直接供我们调用,并帮我们返回除了响应体以外的一些http相关的信息。当然框架还可以实现很多其他东西,比如Django的admin等。

但是有一种框架比较特殊,那就是tornado这类支持协程或绿色线程的异步服务器,所以导致我在学tornado的时候没遇到过WSGI,但是看其他框架却经常出现这些词汇。

至于框架的选择,我给不出太多的意见。主流的就是Django和Flask,但遗憾的是在我什么都不懂的时候,实验室要求我们使用tornado框架。不是说tornado不好,但是tornado这种编程风格确实是新手不友好的,且文档,学习资料与Django比起来少了太多太多,之后我会换一个框架开始学习,Django和Flask中选择一个,因为这些社区环境昊,教程比较多,适合自学。

水平不高,如有错误请指出!谢谢![email protected]

你可能感兴趣的:(Python Web编程概念梳理)