山荣斥北 發表於 2020-4-26 23:33:00

python 异步Web框架sanic

<p>我们继续学习Python异步编程,这里将介绍异步Web框架sanic,为什么不是tornado?从框架的易用性来说,Flask要远远比tornado简单,可惜flask不支持异步,而sanic就是类似Flask语法的异步框架。</p>
<p>github:https://github.com/huge-success/sanic</p>
<p>不过sanic对环境有要求:</p>
<ul>
<li>macOS/linux</li>
<li>python 3.6+</li>
</ul>
<blockquote>
<p>不过,我在macOS上安装 sanic 还是踩了坑。依赖库<code>ujson</code>一直安装失败。最后不得不卸载官方python,安装 miniconda(第三方Python安装包,集成了一些额外的工具)。</p>
</blockquote>
<p>安装 sanic</p>
<pre><code class="language-shell">&gt; pip3 install sanic
</code></pre>
<h2 id="sanic-开发第一个例子">sanic 开发第一个例子</h2>
<p>编写官方的第一个例子<code>hello.py</code>:</p>
<pre><code class="language-py">from sanic import Sanic
from sanic.response import json
from sanic.exceptions import NotFound


app = Sanic(name="pyapp")

@app.route('/')
async def test(request):
    return json({'hello': 'world'})


if __name__ == '__main__':
    app.error_handler.add(
      NotFound,
      lambda r, e: sanic.response.empty(status=404)
    )
    app.run(host='0.0.0.0', port=8000)
</code></pre>
<p>运行上面的程序:</p>
<pre><code class="language-shell">&gt; python3 hello.py

Goin Fast @ http://0.0.0.0:8000
Starting worker
</code></pre>
<p>通过浏览器访问:<code>http://localhost:8000/</code></p>
<p><img src="https://img2020.cnblogs.com/blog/311516/202004/311516-20200426233424199-1823572962.png" alt="" loading="lazy"></p>
<h2 id="请求堵塞">请求堵塞</h2>
<p>针对上面的例子,假设<code>test()</code> 视图函数的处理需要5秒钟,那么请求就堵塞了。</p>
<pre><code class="language-py">……

from time import sleep

app = Sanic(name="pyapp")

@app.route('/')
async def test(request):
    sleep(5)
    return json({'hello': 'world'})

……
</code></pre>
<p>重启服务,通过浏览器发送请求,我们发现请求耗时5秒,这显然对用户就不能忍受的。</p>
<p><img src="https://img2020.cnblogs.com/blog/311516/202004/311516-20200426233507541-170828431.png" alt="" loading="lazy"></p>
<h2 id="异步非堵塞">异步非堵塞</h2>
<p>所以,我们要实现异步调用,修改后的完整代码如下:</p>
<pre><code class="language-py">import asyncio
from sanic import Sanic
from sanic.response import json
from sanic.exceptions import NotFound
from time import sleep, ctime

app = Sanic(name="pyapp")

async def task_sleep():
    print('sleep before', ctime())
    await asyncio.sleep(5)
    print('sleep after', ctime())


@app.route('/')
async def test(request):
    myLoop = request.app.loop
    myLoop.create_task(task_sleep())
    return json({'hello': 'world'})


if __name__ == '__main__':
    app.error_handler.add(
      NotFound,
      lambda r, e: sanic.response.empty(status=404)
    )
    app.run(host='0.0.0.0', port=8000)
</code></pre>
<p>关于python异步的使用参考上一篇文章,重新启动服务。这次前端就不在堵塞了。</p>
<p><img src="https://img2020.cnblogs.com/blog/311516/202004/311516-20200426233521445-112558328.png" alt="" loading="lazy"></p>
<p>如果看 sanic 的运行日志:</p>
<pre><code class="language-shell"> - (sanic.access): GET http://localhost:8000/200 17
sleep before Tue Apr 21 23:43:14 2020
sleep after Tue Apr 21 23:43:19 2020
</code></pre>
<p>他仍然在执行,但不会堵塞<code>test()</code>视图函数的响应。</p>
<blockquote>
<p>思考:假如我的需求是:请求之后先告诉我已经处理了,然后默默的去处理,什么时候处理来再主动把处理的结果告诉。那么这就需要用到 websocket了。</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/fnng/p/12783542.html
頁: [1]
查看完整版本: python 异步Web框架sanic