首页 > 编程问答 >Gunicorn Flask 服务器终止最后一个请求,并显示“连接关闭但没有响应”

Gunicorn Flask 服务器终止最后一个请求,并显示“连接关闭但没有响应”

时间:2024-07-23 15:15:16浏览次数:9  
标签:python flask heroku gunicorn

Heroku 上的 Gunicorn Flask 服务器在重新启动 Worker 之前终止了最后一个请求,导致出现 503 错误:“连接关闭而没有响应。”

我已经分析了数百个这样的请求,每当服务器遇到“连接关闭而没有响应”时, “错误,它总是发生在特定工作程序重新启动之前的最后一次调用上。

我在 Gunicorn 服务器上设置了以下设置:

web: gunicorn main:app --threads=3 --max-requests=1200

每个 dyno 中有 4 个工作程序。

gunicorn==22.0.0|| |值得注意的是,最后一次出错的调用始终是零服务时间。

我已更新到最新的gunicorn版本,但没有效果 也尝试增加和减少线程+工作人员 数据库的延迟也减少了

enter image description here

I have updated to latest gunicorn version but it had not effect tried increasing and decreasing the threads + workers as well reduced latency of database too


你的问题很可能与 Gunicorn 的 --max-requests 设置和 Heroku 的路由机制有关。

问题根源:

  1. --max-requests : 你设置了 --max-requests=1200 ,这意味着每个 Gunicorn 工作进程在处理 1200 个请求后会自动重启。这是为了防止内存泄漏等问题。
  2. Heroku 路由器和连接保持: Heroku 的路由器可能会将请求随机分配给任何可用的 Gunicorn 工作进程,即使该进程即将重启。如果一个请求被路由到一个即将关闭的进程,该请求可能会在没有得到任何响应的情况下被终止,从而导致“连接关闭而没有响应”错误。

解决方法:

你有几个选择可以解决这个问题:

1. 使用 pre_request 钩子优雅地关闭工作进程:

  • 在你的 Flask 应用中,你可以使用 Gunicorn 的 pre_request 钩子来检查当前工作进程是否已接近 max_requests 限制。
  • 如果接近限制,你可以使用 werkzeug.exceptions.ServiceUnavailable 异常来拒绝新请求,并返回 503 服务不可用错误。这将允许当前工作进程完成处理中的请求,然后优雅地关闭。

```python from flask import Flask, g from werkzeug.exceptions import ServiceUnavailable

app = Flask( name )

@app.before_request def check_max_requests(): if g.worker.requests_count >= g.worker.max_requests - 10: raise ServiceUnavailable('Server is restarting soon')

@app.teardown_appcontext def close_db(error): db = getattr(g, '_database', None) if db is not None: db.close() ```

2. 增加 --max-requests 的值:

  • 你可以尝试增加 --max-requests 的值,例如将其设置为 --max-requests=2400 或更高。
  • 这可能会减少工作进程重启的频率,但并不能完全解决问题。

3. 禁用 --max-requests :

  • 你可以完全删除 --max-requests 选项,但这意味着 Gunicorn 工作进程将不会自动重启。
  • 你需要确保你的应用程序没有内存泄漏或其他可能导致问题的问题。

4. 使用其他 WSGI 服务器:

  • 你可以考虑使用其他 WSGI 服务器,例如 uWSGI 或 Waitress,它们可能具有不同的工作进程管理机制。

建议:

我建议你首先尝试方法 1,因为它提供了最优雅和最可靠的解决方案。 如果你发现方法 1 对你的应用程序来说太复杂,你可以尝试方法 2 或 3,但请注意它们的潜在缺点。

其他建议:

  • 确保你的数据库连接池配置正确,并且连接在使用后被正确释放。
  • 监控你的应用程序的内存使用情况,以确保没有内存泄漏。

希望这些信息能帮到你!

标签:python,flask,heroku,gunicorn
From: 78782064

相关文章

  • 尝试从图像 url 中抓取图像(使用 python urllib ),但获取 html
    我尝试从以下网址获取图像。http://upic.me/i/fj/the_wonderful_mist_once_again_01.jpg我可以右键单击并另存为,但是当我尝试使用urlretrievelikeimporturllibimg_url='http://upic.me/i/fj/the_wonderful_mist_once_again_01.jpg'urllib.urlretriev......
  • Python-深度学习算法实用指南-全-
    Python深度学习算法实用指南(全)原文:zh.annas-archive.org/md5/844a6ce45a119d3197c33a6b5db2d7b1译者:飞龙协议:CCBY-NC-SA4.0前言深度学习是人工智能领域最受欢迎的领域之一,允许你开发复杂程度各异的多层模型。本书介绍了从基础到高级的流行深度学习算法,并展示了如何使用......
  • 三种语言实现归并排序(C++/Python/Java)
    题目给定你一个长度为......
  • Python中如何实现字符串的查询和替换?
    在Python中,字符串的查询和替换是编程中常见的任务,它们可以通过Python的内置方法和库来高效实现。这些操作对于文本处理、数据清洗、日志分析等场景尤为重要。下面,我将详细阐述如何在Python中实现字符串的查询和替换,包括基础方法、高级技巧以及在实际应用中的注意事项。字符......
  • Python中的`range()`函数及其用法
    range()函数是Python中的一个内置函数,它用于生成一个数字序列。这个函数在循环结构中尤其有用,因为它允许我们迭代一系列的数字,而无需显式地创建这些数字的列表。range()函数通过指定起始值、结束值(不包括)和步长(可选)来工作,返回一个可迭代对象,通常用于for循环中。下面将......
  • python 的注释(例如数据类)可以扩展到它生成的代码中吗?
    能看出python的注释扩展成​​什么吗?例如,对于与数据类相关的错误,有时试图找出它实际生成的代码有点棘手。例如:@dataclass(order=True)classPerson:name:strage:int=0classPerson:def__init__(self,name:str,age=0):self.name=name......
  • Docker:无法在 docker 映像中使用 pythonnet 和 |无法创建默认的 .NET 运行时,该运行时
    我正在尝试使用clrfromPythonnet使用.DLL引用将一种文件类型转换为另一种文件类型。这就是我的代码的样子-importclrclr.AddReference(dll_path)importRxLibrary#ConverttoASCFormat-----------input_file=f"./{filename}.rxd"......
  • 在 Python 中以非常高的质量保存图像
    如何以非常高的质量保存Python绘图?也就是说,当我不断放大PDF文件中保存的对象时,为什么没有任何模糊?另外,什么是最好的模式将其保存在?png,eps?或者其他的?我不能pdf,因为有一个隐藏的数字会扰乱Latexmk编译。要以非常高的质量保存Py......
  • Python字符串:提取重复和随机合并的子字符串
    重复和合并字符串的示例:16.01068.0%08p%.a.p.a.要提取的所需子字符串:16.008%p.a.完整示例:CCoonnttiinnggeennttCCoouuppoonn16.01068.0%08p%.a.p(.Ma.o(nMtholyn)thly)所需子字符串:ContingentCoupon16.008%p.a.(Monthly)我的问题是当原始......
  • Python Pandas 从使用第 3 部分 API 自动生成的 Excel 文件中读取不一致的日期格式
    我正在使用PDF4meAPI将PDF发票转换为Excel文件。API可以正确读取日期。但是,当我打开Excel文件时,日期显示不一致:某些日期以正确的格式(dd/mm/yyyy)显示,而其他日期以错误的mm/dd/yyyy格式显示。当该月的某天小于或等于12时,似乎会出现这种不一致。......