爲何要用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的訂閱發佈通知來說