首页 > 解决方案 > Python Flask 服务器重用 HTTP 连接池来调用另一个 API 端点

问题描述

我有一个使用 Python Flask 编写的 Web 服务器。我将包含简化的代码来帮助描述我的问题。

# main.py

@app.before_first_request
def init():
    # pool for multi processing thread
    app.config.thread = ThreadPoolExecutor()

    # pool http client with session, so connection can reused
    app.config.rest_client = requests.session()
# routes.py

product_routes = Blueprint('product', __name__)


@product_routes.route('/api/internal/products', methods=['POST'])
def create_product():
    resp = Controller()
    return jsonify({'status': HTTPStatus.OK, 'message': resp.create()})
controller.py

class ProductController:

    def __init__(self):
        self.__request = request
        self.__http_cl = RestClient()
        self.__b2c_url = "localhost:1234/api/internal/products"

    @property
    def prepare_payload(self):
        payload = Product(
            name=self.__request.json["name"],
            product_id=self.__request.json["product_id"],
            price=self.__request.json["price"]
        )
        return payload.to_json()

    @auto_close_session
    def create(self):
        payload = self.prepare_payload
        return self.__http_cl.http_post(self.__b2c_url, payload).json()
# rest_client.py

import requests
from flask import current_app


class RestClient:

    def __init__(self):
        self.__poll = current_app.config.rest_client
        self.__default_header = {'Content-type': 'application/json'}

    def http_post(self, url: str, payload: dict, header: dict = None):
        return self.__poll.post(url, json=payload, headers=self.__default_header if not header else header)
# utils.py

from functools import wraps

from flask import current_app


def auto_close_session(func):
    @wraps(func)
    def decorated_function(*args, **kwargs):
        # doing request first
        resp = func(*args, **kwargs)
        # then close connection
        current_app.config.rest_client.close()
        # return value
        return resp

    return decorated_function

因此,该 Web 服务器接收到一个 http 请求并调用另一个 Web 服务,例如localhost:1234/api/internal/products. 如果您想知道,请注意这是一个充当接口的“中间件”服务,这就是您看到 URL 相同的原因。

现在,每次这个 web 服务器有一个异常,例如localhost:1234/api/internal/products服务器返回一个错误,这个 web 服务器就死掉了。请注意,我在 kubernetes pod 中运行此 Web 服务器。它“死亡”是指 pod 内的容器计数为 0。

我在这里错过了什么吗?我的有什么问题auto_close_session吗?

谢谢!

标签: pythonpython-3.xflaskpython-requests

解决方案


推荐阅读