为何要用Sanic,请见 让你的Python(Web应用)飞起来,(异步/协程)全家桶html
废话很少讲,直接进入正题,我会按照正常的Web应用程序架构来说Sanic的用法python
pip install sanic
redis
from sanic import Sanic
app = Sanic(__name__)
复制代码
服务启动以前数据库
@app.listener('before_server_start')
async def start_connection(app, loop):
# 执行一些初始化任务
# 例如初始化 Redis 链接池
await RedisPool.init_redis_conn_pool(loop)
复制代码
服务中止以前json
@app.listener('after_server_stop')
async def start_connection(app, loop):
# 执行一些备份、应急、关闭任务
# 例如关闭链接池
await RedisPool.close_redis_conn_pool()
await close_connection(app, loop)
复制代码
请求(Request)中间件api
@app.middleware('request')
async def add_tokrn_to_request(request):
# 每次请求会通过此方法,能够作一些对request的处理
# 例如添加token,secret,token
await session_interface.open(request)
复制代码
响应(Response)中间件浏览器
@app.middleware('response')
async def save_session(request, response):
logger = logging.getLogger('response')
# 每次服务器响应会通过此方法,能够作一些异常,cookie,logger等的处理
# 例如写入cookie,记录用户日志
await session_interface.save(request, response)
复制代码
相似Flask,用来组织应用程序,也就是大多数咱们mvc模式中的controller,服务器
order_bp = Blueprint('orders', url_prefix='v1/api/order')
# url_prefix:定义路由修正,
# 例如当前蓝图下你定义了一个 query/id 的路由,那么你应该这样访问它 v1/api/order/query/id
复制代码
from controller.order_controller import order_bp
app.blueprint(order_bp)
# 这样order_bp就被注册到sanic中,能够经过浏览器 http://example.com/v1/api/order/query/id 访问
复制代码
@bp.exception(NotFound)
def ignore_404(request, exception):
return text("Yep, I totally found the page: {}".format(request.url))
复制代码
# GET 路由参数的方式
@order_bp.route('/delete/<oid:int>', methods=['GET'])
async def delete_order(request, oid):
result = await OrderModel().del_order_by_id(oid)
if result:
return json({'status': 'ok', 'result': result})
return json({'status': 'fail', 'errmsg': '获取数据失败'})
复制代码
# Get params的方式
@service_bp.route('/message/send', methods=['GET'])
async def send_message(request):
uuid = request.args['uuid'][0]
page = request.args['page'][0]
result = await MessageService().send_message_2_user(uuid,page)
if result:
return json({'status': 'ok', 'result': result})
return json({'status': 'fail', 'errmsg': '获取数据失败'})
return raw(result)
复制代码
# 修改价格
@order_bp.route('/price/modify', methods=['POST'])
async def price_modify(request):
order_id = request.json['order_id']
price = request.json['price']
postage = request.json['postage']
show_price = request.json['show_price']
is_shipping = request.json['is_shipping']
result = await OrderModel().modify_price(order_id, price, postage, show_price, is_shipping)
if result:
return json({'status': 'ok', 'result': result})
return json({'status': 'fail', 'errmsg': '获取数据失败'})
复制代码
from sanic.response import json
# text
response.text('hello world')
# html
response.html('<p>hello world</p>')
# json
response.json({'hello': 'world'})
# file
response.file('/srv/www/hello.txt')
# stream
response.stream(stream_ctx, content_type='text/plain')
复制代码
若是我想在Sanic启动以后额外运行任务怎么办?cookie
app.add_task(notify_server_started())
app.add_task(notify_html_spider())
复制代码
if __name__ == "__main__":
app.add_task(notify_server_started())
app.add_task(notify_html_spider())
app.run(host="0.0.0.0", port=settings.PORT, workers=settings.workers, debug=settings.DEBUG, access_log=True)
复制代码
在启动时能够传入一些参数,其余的都是字面意思,很好理解,这里讲一下 Workerssession
workers
接受integer
类型,默认为1,传入4意味着Sanic会为你复制四份,建立四个进程来运行你的Sanic App
如图
多进程状态下,路由会进行自动分配,从而增长吞吐量,
workers
的个数依据自身服务器性能而定,若是建立太多会出现占用状况,一样多进程模式下,你的数据库链接或者数据库链接池的数量也要适当调大,不然会出现链接数过多而拒绝链接的状况
Sanic的介绍就这么多,只是一个基本入门,至于其余相似订阅发布监听等等功能你们能够移步 Sanic官网 进行学习和查阅
下期我可能会联合Sanic讲解关于异步Redis(aioredis)的使用,例子打算用相似订单倒计时的功能,结合redis的订阅发布通知来说