cx_Oracle SessionPool корень всех проблем Flask

#python #cx-oracle

#python #cx-oracle

Вопрос:

Я создал веб-сервис в Flask поверх uwsgi. Я думал, что буду следовать хорошей практике и создам SessionPool с 20 подключениями, чтобы быть в безопасности. При каждом вызове конечной точки веб-службы я получаю соединение из пула и в конце освобождаю его.

При использовании Locust для роевого тестирования API я получал сотни сбоев, почти 100% для некоторых более длинных ответов (ответ JSON размером 30 МБ). Меньшие полезные нагрузки были намного лучше, но с периодическими сбоями.

В ту минуту, когда я вернулся к плохой практике и создал совершенно новое соединение и курсор в самом методе, все мои проблемы исчезли. 100% успех при 1000 вызовах стресс-тестов.

Мои ошибки были разными. Неверный пакет TNS, неверное количество подключений из пула, запрос, отмененный пользователем …. вы называете это, оно было там.

Кажется, я не могу использовать пул подключений Oracle с помощью flask или иметь одно соединение на уровне приложения Flask (это породило ошибки, не знаю почему, поэтому я переключился на пул подключений).

Любые советы по созданию масштабируемых приложений с использованием cx_Oracle в flask.

Мой исходный код был:

 pool = cx_Oracle.SessionPool("user", "password", "myserver.company.net:1521/myservice", min=10, max=10, increment=0, getmode=cx_Oracle.SPOOL_ATTRVAL_WAIT, encoding="UTF-8")







def read_products_search(search=None):
    """
    This function responds to a request for /api/products
    with the complete lists of people

    :return:        json string of list of people
    """
    conn_ariel = pool.acquire()   
    cursor_ariel = conn_ariel.cursor()


    search=search.lower()
    print("product search term is: ", search)
    # Create the list of products from our data
    sql = """
        SELECT DRUG_PRODUCT_ID, PREFERRED_TRADE_NAME, PRODUCT_LINE, PRODUCT_TYPE, FLAG_PASSIVE, PRODUCT_NUMBER
        FROM DIM_DRUG_PRODUCT 
        WHERE lower(PREFERRED_TRADE_NAME) LIKE '%' || :search1 || '%' or lower(PRODUCT_LINE) LIKE '%' || :search2 || '%'  or lower(PRODUCT_NUMBER) LIKE '%' || :search3 || '%' 
        ORDER BY PREFERRED_TRADE_NAME ASC
        """
    cursor_ariel.execute(sql, {"search1":search,"search2":search, "search3":search })
    products = []




    for row in cursor_ariel.fetchall():

        r = reg(cursor_ariel, row, False)

        product = {
            "drug_product_id"           :   r.DRUG_PRODUCT_ID,
            "preferred_trade_name"      :   r.PREFERRED_TRADE_NAME,
            "product_line"              :   r.PRODUCT_LINE,
            "product_type"              :   r.PRODUCT_TYPE,
            "flag_passive"              :   r.FLAG_PASSIVE,
            "product_number"            :   r.PRODUCT_NUMBER

        }
        # logging.info("Adding Product: %r", product)
        products.append(product)

    if len(products) == 0:
        products = None

    pool.release(conn_ariel)
    return products
  

Ответ №1:

При создании пула используйте threaded=True .

Смотрите, как использовать Python Flask с базой данных Oracle.