Alpine docker 容器内存泄漏中的 Flask REST-API



我试图在我的烧瓶 REST-API 中找到一种内存泄漏几天了,没有任何相关进展。

我有一个使用mysql数据库的烧瓶REST-API(像SQLAlchemy,connexion和marshmallow这样的软件包(。它可以通过一个docker容器获得,该容器具有来自alpine:latest的基本映像。

我遇到的主要问题是:每次向 REST-API 发出请求时,docker 容器的内存使用量都会增加,并且内存不会释放。API 不会缓存结果。

以下是来自 server.py(RESt-API的主程序(的代码:

"""
Main module of the server file
"""
# 3rd party moudles
# local modules
import config
# Get the application instance
connex_app = config.connex_app
# Read the swagger.yml file to configure the endpoints
connex_app.add_api("swagger_2.0.yml")
# create a URL route in our application for "/"
@connex_app.route("/")
def home():
return None
if __name__ == "__main__":
connex_app.run(debug=True)

和配置文件:

import os
import connexion
from flask_cors import CORS
from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy
from memory_profiler import memory_usage

basedir = os.path.abspath(os.path.dirname(__file__))
# Create the Connexion application instance
connex_app = connexion.App(__name__, specification_dir=basedir)
# Get the underlying Flask app instance
app = connex_app.app
CORS(app)
# Configure the SQLAlchemy part of the app instance
app.config['SQLALCHEMY_ECHO'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://root:somepassword@someHostId/sponge"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

@app.after_request
def add_header(response):
#response.cache_control.no_store = True
if 'Cache-Control' not in response.headers:
response.headers['Cache-Control'] = 'max-age=0'
print(memory_usage(-1, interval=.2, timeout=1), "after request")
return response

# Create the SQLAlchemy db instance
db = SQLAlchemy(app)
# Initialize Marshmallow
ma = Marshmallow(app)

您可以在此处查看终端节点的示例:

from flask import abort
import models
def read(disease_name=None):
"""
This function responds to a request for /sponge/dataset/?disease_name={disease_name}
with one matching entry to the specifed diesease_name
:param disease_name:   name of the dataset to find (if not given, all available datasets will be shown)
:return:            dataset matching ID
"""
if disease_name is None:
# Create the list of people from our data
data = models.Dataset.query 
.all()
else:
# Get the dataset requested
data = models.Dataset.query 
.filter(models.Dataset.disease_name.like("%" + disease_name + "%")) 
.all()
# Did we find a dataset?
if len(data) > 0:
# Serialize the data for the response
return models.DatasetSchema(many=True).dump(data).data
else:
abort(404, 'No data found for name: {disease_name}'.format(disease_name=disease_name))

我尝试使用 memory_profiler 工具在代码中找到内存泄漏,但由于在每个 REST-API 端点上都可以观察到相同的行为(在每个请求中增加 docker 容器的内存使用量(。

任何人都可以解释正在发生的事情,或者知道我如何解决缓存问题。

问题已修复。其实没问题。docker 统计内存使用量由于 python 的实现而增加。如果 rest-api 请求大到几 GB,那么 python 会分配一定比例的已用内存,并且不会立即释放它。因此,500 GB的峰值是在很好的答案之后。我在 API 端点中添加了一个固定的限制,并提示用户如果超过此限制,他应该将整个数据库下载为 zip fornat 并在本地使用它。

最新更新