簡體   English   中英

使用Python(Sanic)開發REST API

[英]Developing REST APIs using Python (Sanic)

from sanic import Sanic
from sanic import response


app = Sanic(__name__)

@app.route('/v1/ok', methods=['GET'])
async def post_handler(request):
    return response.text("hey all good")

if __name__ == '__main__':
        app.run(host="0.0.0.0", port=8001, debug=True)

我正在嘗試使用sanic在python中編寫REST API

這是我的結論:

我嘗試使用wrk和運行30s測試的50個線程對這個GET API進行基准測試。 使用機器的AWS EC2 t2.medium具有4GB RAM和2個CPU命令

wrk -t50 -c4000 -d30s http://XXX.XX.XXX.XXX:8001/v1/ok

標桿結果

Running 30s test @ http://XXX.XX.XXX.XXX:8001/v1/ok
 50 threads and 4000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   559.30ms  117.86ms   1.99s    94.47%
    Req/Sec    41.92     44.33   361.00     86.14%
  53260 requests in 30.10s, 6.70MB read
  Socket errors: connect 1493, read 15631, write 0, timeout 4
Requests/sec:   1769.21
Transfer/sec:    228.06KB

我的疑問是,我該如何改善

  1. 超時的請求數。 當前為4。應為零。
  2. 平均延遲時間,約550ms(太多)

在POST請求的情況下,這非常糟糕,其中我試圖加載keras模型並進行預測。

代碼編寫方式有問題嗎?

要么

這是Sanic的局限性嗎?

我應該嘗試其他REST框架嗎?

PS:就延遲和超時請求而言,我對flask的體驗甚至更糟。

import sys
import os
import json
import pandas
import numpy
import optparse
from keras.models import Sequential, load_model
from keras.preprocessing import sequence
from keras.preprocessing.text import Tokenizer
from collections import OrderedDict
from sanic import Sanic
from sanic import response
import time

app = Sanic(__name__)

@app.route('/v1/mal/prediction', methods=['POST'])
async def post_handler(request):
    csv_file = 'alerts.csv'
    log_entry = request.json
    dataframe = pandas.read_csv(csv_file, engine='python', quotechar='|', header=None)
    dataset = dataframe.values
    X = dataset[:,0]
    for index, item in enumerate(X):
        reqJson = json.loads(item, object_pairs_hook=OrderedDict)
        del reqJson['timestamp']
        del reqJson['headers']
        del reqJson['source']
        del reqJson['route']
        del reqJson['responsePayload']
        X[index] = json.dumps(reqJson, separators=(',', ':'))

    tokenizer = Tokenizer(filters='\t\n', char_level=True)
    tokenizer.fit_on_texts(X)
    seq = tokenizer.texts_to_sequences([log_entry])
    max_log_length = 1024
    log_entry_processed = sequence.pad_sequences(seq, maxlen=max_log_length)
    model = load_model('model.h5')
    model.load_weights('weights.h5')
    model.compile(loss = 'binary_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
    prediction = model.predict(log_entry_processed)
    return response.text(prediction[0])

if __name__ == '__main__':
        app.run(host="0.0.0.0", port=8000, debug=True)

請提出更好的方法來改善API響應時間並減少超時請求?

禁用debug並將workers設置為您實例中的CPU數量(t2.med為2):

app.run(host="0.0.0.0", port=8001, workers=2)

這里的游戲有點晚了,但是我相信為了使其真正異步,您需要添加await調用。 否則,您只是在調用阻塞函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM