python - 高山 docker 容器内存泄漏中的 Flask REST-API
问题描述
几天来,我试图在我的烧瓶 REST-API 中找到一种内存泄漏,但没有任何相关进展。
我有一个使用 mysql 数据库(如 SQLAlchemy、connexion 和 marshmallow 等软件包)的烧瓶 REST-API。它可以通过 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 容器的内存使用量)。
任何人都可以解释发生了什么,或者知道我如何解决缓存问题。
解决方案
问题已解决。其实没问题。由于 python 的实现,docker stats 内存使用量增加。如果 rest-api 请求是数 GB 大,那么 python 会分配一定比例的已用内存,并且不会立即释放它。因此,500 GB 的峰值是在一个非常好的答案之后。我向 API 端点添加了一个固定限制,并提示用户如果超过此限制,他应该将整个数据库下载为 zip fornat 并在本地使用它。
推荐阅读
- pug - Thymeleaf:将字符串参数传递给 mixins 函数
- kotlin - launch 仅从 Kotlin 1.3 开始可用,不能在 Kotlin 1.2 中使用
- modx - MODX无法保存
- r - 如何在 R lattice::wireframe 图中添加背景网格?
- jenkins - 代码推送到 github 后触发 Jenkins 管道作业
- r - 如何在 R 中自动删除时间序列数据中的噪声(伪影)
- mysql - 如何将三个 SQL 与具有相同字段 ne 的两个表连接起来
- dart - 在颤动中获取设备IMEI
- azure-devops - 将公共包推送到 azure devops feed
- python - python中的process_time()和连续调用