我使用具有 2 个主要工作负载的 Django 后端:
- Angular UI 前端和 Django 管理屏幕的 API 服务器
- 调度程序,启动大约 8 种不同的预定服务
- 指标收集:针对一组服务器的 API 调用以进行定期状态更新,然后将响应存储在 PostgreSQL 数据库中。
- Runner:针对我们的服务器群运行 Ansible 作业
一切都与同一个 PostgreSQL 数据库相关联,并且经常交叉引用。所以不要认为这些是合乎逻辑的不同应用程序,它不是。
问题都源于 Gunicorn 网络服务器和超时。Gunicorn 有 6 名工人。默认情况下,Gunicorn 喜欢杀死在过去约 30 秒内未使用的进程。如果您的工作负载只是 HTTP 调用而不是后台进程,那么这非常有用。但是,由于我显然两者都有,所以我在杀死 gunicorn 或不杀死我的进程时遇到了问题。
多年来,我的 gunicorn 超时时间非常高,为 21600 秒(6 小时)。使用此设置,它将让我的 Ansible 作业完成并且我的调度程序作业完成。但是数据库会有大量的非活动(2000~4000)和活动(1~20)会话。数据库会很慢,连接会很慢地消失。
最近我将它降低了 60 秒,我的所有调度程序和 Ansible 作业都会失败。然后我去了800秒。大多数调度程序作业都会完成,但如果我的 HTTP 调用进入缓慢,Ansible 作业将在 800 秒左右时终止。
现在我清楚地看到我有两个工作量问题。1) API 调用和 2) 后端处理
目前的 Gunicorn 服务
[Unit]
Description = RocketDBaaS_runner
Requires=runner.socket cntlm.service
After=network.target cntlm.service
[Service]
PIDFile=/run/runner.pid
User=root
Group=dbaas
RuntimeDirectory=runner
Environment=http_proxy=http://localhost:3128
Environment=https_proxy=http://localhost:3128
LimitNOFILE=131072
LimitNPROC=64000
LimitMEMLOCK=infinity
ExecStart=/opt/dbaas/RocketDBaaS_api/venv/bin/gunicorn \
--pid /run/runner.pid \
--access-logfile None \
--workers 6 \
--bind unix:/run/runner.socket \
--pythonpath /opt/dbaas/RocketDBaaS_api \
--timeout 300 \
--graceful-timeout 30 \
RocketDBaaS_api.wsgi
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true
KillMode=mixed
KillSignal=SIGKILL
那么该怎么办???
我的首要想法是创建三个调用相同代码库的服务。但是传入一个名为 service_function='Scheduler|API|Runner' 的变量
- API:基本上使用我上面的内容,但传入 service_function='API' 并将我的超时时间降低到 60 秒
- 调度程序:我被撕裂
了 A) 创建直接调用 Django 并传递 service_function='Scheduler' 的服务。但是我听说以这种方式运行 Django 是不明智的,因为它不安全。但我不会接受 HTTP 请求。仅供参考:调度程序启动并处理它自己的线程。
B) 只需设置一个没有工人或线程且超时 = 0 的新 Gunicorn 服务器 - Runner:像#2一样创建服务并传递 service_function='Runner'
我可以将 #2 和 #3 结合起来,但认为使用 3 个不同的服务搜索 journalctl 可能会更容易。但是我的日志文件已经分开了,所以它不是一个显示停止器。
在 wsgi.py 文件中,我计划读取该输入参数并将其用作全局变量。然后,这个变量会告诉 Django 什么时候它应该充当 API、调度程序或 Runner 服务器。
目前,我的调度程序使用先到先服务器锁定机制,直到该进程终止。这是当前设计的一种失败,因为所有必须通过所有逻辑来查看调度启动过程是否只是为了找到锁定文件并且锁定文件中的进程是否处于活动状态。该解决方案将通过一个简单的 If 语句解决该问题。
请我是一个 1 人的团队。在走这条路之前,我需要其他观点。我用谷歌搜索了一堆,但从未真正找到这样的问题。
堆:
UI: Angular
API: Django
Automation: Ansible
Database: PostgreSQL ~1TB
Interacting with: ~600 VMs
提前致谢。