Random Thoughts

Recent content on Random Thoughts

马上订阅 Random Thoughts RSS 更新: https://blog.joway.io/index.xml

Lemon : Koa 风格的 Python 异步 Web 框架

2018年1月8日 08:00

前段时间想要写一些简短高效的 API ,背后的工作无非就是一些计算和数据处理,但是可能并发量会比较高。当我在 Python 的生态里去搜寻一些靠谱的 Web 框架时,很难找到一个设计优秀且运行效率高的框架。尤其是当我已经习惯了 NodeJS 的 Koa 那种简洁明了的设计时,很难再喜欢上像 Flask 那种装饰器的写法和各种概念拢杂在一起的设计。最后实在没有办法,就自己写了个符合我个人审美的框架 Lemon

什么是 Web 框架

在讲 Lemon 的设计前,我们先来看一看一个请求是如何被响应的 ,以及框架在其中的作用是什么 :

当一个请求从客户端进入服务器,首先以 TCP 包的形式被接收到,这个时候我们需要手动去建立连接,接收到 TCP 报文后我们需要去判断它的协议,然后再解成相应协议(一般都是HTTP协议)的报文,传给 application 去处理,当处理完后还要把结果写回成 TCP 报文传回去,如果有 keep alive 还需要去手动管理这个连接的生命周期。以上这些统称为 server 部分。

而和开发者关系最密切的 application 部分做的就是拿到一个 http 或其它协议的报文,然后根据其信息做针对性的响应,传给 server 。

无论你是使用任何语言任何框架,都逃不开上面这个处理过程。而我们在比较框架的时候,无外乎是对以下几个方面做一些针对性的优化:

  1. TCP报文解析成 HTTP(或其它协议) 报文的效率
  2. 并发策略 (多线程,多进程,协程,线程池,Event Loop)
  3. application 本身的运行效率 (由框架的效率,所用的语言和使用者自身的代码质量共同决定)

对于第一点,python有一个叫 httptools 的库就是使用了 NodeJS 的 http parser 以达到高性能解包的目的。

针对第二点,有许多OS层面和工程层面的技术在致力于解决这个问题。uvloop 就是其中的一种,采用事件循环的方式,底层用的是 libuv , 同样也是 NodeJS 的底层异步IO库 。

第三点可能是我们大部分人的考虑的重点,需要各自根据团队情况,在开发效率和运行效率中间进行权衡。作为框架本身,它能够做的极致就是不给 application 拖后腿,而现实中,大部分时间其实都是在运行用户自己编写的代码。

当我们在谈论一个 Web 框架的时候,更多是在谈论第三点 application 的部分。第一二两点是 server 的实现部分。大部分时候,框架自身并不会去实现一个完整的 server 。为了让我们使用各种框架来进行开发的 application 能够在不同 server 中可以运行,会指定一些接口标准,在 Python 里同步的比如 wsgi , 异步的比如 asgi 。