簡體   English   中英

Sanic Web 框架性能

[英]Sanic web framework performance

我有一個關於 sanic/asyncpg 性能的問題要問。

在測試期間,奇怪的事情不斷發生(也許是設計使然)。

首先讓我解釋一下測試過程。 很簡單。

我使用 locust 通過設置最大用戶數來盡可能多地推送服務器。

測試腳本為:

from locust import HttpLocust, TaskSet, task, between


class UserActions(TaskSet):
    @task(1)
    def test_point_1(self):
        self.client.get(
            '/json_1',
            headers={'Content-Type': 'application/json'}
        )

    @task(2)
    def test_point_2(self):
        self.client.get(
            '/json_2',
            headers={'Content-Type': 'application/json'}
        )


class ApplicationUser(HttpLocust):
    task_set = UserActions
    wait_time = between(0, 0)

它用於測試以下代碼。 注意 asyncpg 正在調用 potgresql sleep 函數來模擬負載:

import asyncio
import uvloop
from asyncpg import create_pool
from sanic import Sanic, response
from sanic.log import logger
import aiotask_context as context

app = Sanic(__name__)

DATABASE = {
    'type': 'postgresql',
    'host': '127.0.0.1',
    'user': 'test_user',
    'port': '5432',
    'password': 'test_password',
    'database': 'test_database'
}

conn_uri = '{0}://{1}:{2}@{3}:{4}/{5}'.format(
            'postgres',
            DATABASE['user'], DATABASE['password'], DATABASE['host'],
            DATABASE['port'], DATABASE['database'])


@app.route("/json_1")
async def handler_json_1(request):
    async with request.app.pg.acquire() as connection:
        await connection.fetchrow('SELECT pg_sleep(0.85);')
    return response.json({"foo": "bar"})


@app.route("/json_2")
async def handler_json_2(request):
    async with request.app.pg.acquire() as connection:
        await connection.fetchrow('SELECT pg_sleep(0.2);')
    return response.json({"foo": "bar"})


@app.listener("before_server_start")
async def listener_before_server_start(*args, **kwargs):
    try:

        pg_pool = await create_pool(
            conn_uri, min_size=2, max_size=10,
            server_settings={'application_name': 'test_backend'})
        app.pg = pg_pool

    except Exception as bss_error:
        logger.error('before_server_start_test erred with :{}'.format(bss_error))
        app.pg = None


@app.listener("after_server_start")
async def listener_after_server_start(*args, **kwargs):
    # print("after_server_start")
    pass


@app.listener("before_server_stop")
async def listener_before_server_stop(*args, **kwargs):
    # print("before_server_stop")
    pass


@app.listener("after_server_stop")
async def listener_after_server_stop(*args, **kwargs):
    # print("after_server_stop")
    pass


if __name__ == '__main__':
    asyncio.set_event_loop(uvloop.new_event_loop())
    server = app.create_server(host="0.0.0.0", port=8282, return_asyncio_server=True)
    loop = asyncio.get_event_loop()
    loop.set_task_factory(context.task_factory)
    task = asyncio.ensure_future(server)
    try:
        loop.run_forever()
    except Exception as lerr:
        logger.error('Loop run error: {}'.format(lerr))
        loop.stop()

問題是,在隨機時間后,服務器對 cca 無響應(不返回 503 或任何其他代碼)。 60 秒。 進程也掛起(我可以用ps aux看到它,而 CTRL+C 無法殺死它。)

這可能是有問題的,因為它很難被檢測到,並且很難確定我們可以向服務器發送請求的速率。

這可能是配置(sanic/asyncpg)的問題嗎?

是否可以設置 nginx/sanic 請求超時是規避此問題的唯一選擇?

您的 aiopg 池限制為 10 個連接。 所以一次最多 10 個請求,每個需要 0.2 秒,您的最大可能負載為 1 秒/0.2 秒 * 10 池大小 = 50 RPS。 之后,所有傳入的請求只會等待連接,並且要服務的請求隊列的增長速度將比您的服務能力快得多,並且您的服務器將變得無響應。

暫無
暫無

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

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