问题描述
我最近将我的Django API后端部署到了AWS EB的Linux 2系统上(确切的平台名称是在64位Amazon Linux 2上运行的Python 3.7
).
I've recently deployed my Django API backend to AWS EB to their Linux 2 system (exact platform name is Python 3.7 running on 64bit Amazon Linux 2
).
几乎所有功能都按预期运行,但是我的应用程序运行状况为 Severe
,并且经过数小时的调试,我不知道为什么.
Almost everything is working as expected, but my application health status is Severe
and after hours of debugging I've no idea why.
正在使用以下端点( django-health-check
模块)处理应用程序的运行状况检查.
The application's health check is being handled using the following endpoint (django-health-check
module).
url(r'^ht/', include('health_check.urls'))
100%的请求的状态码为 200
,但是我的总体健康状况如下:
100% of the requests have a status code of 200
but my overall health status is the following:
|--------------------|----------------|---------------------------------------------------|
| instance-id | status | cause |
|--------------------|----------------|---------------------------------------------------|
| Overall | Degraded | Impaired services on all instances. |
| i-0eb89f... | Severe | Following services are not running: release. |
|--------------------|----------------|---------------------------------------------------|
最奇怪的是,以下服务未运行:发布.
消息是Internet独有的(似乎以前没有人遇到过这样的问题).
The strangest thing is the fact that the message Following services are not running: release.
is unique to the internet (seems like no one has had such problem before).
另一个奇怪的事情是我的/var/log/healthd/daemon.log
文件的内容,它们类似于
The other weird thing are the contents of my /var/log/healthd/daemon.log
file which are lines similar to
W, [2020-07-21T09:00:01.209091 #3467] WARN -- : log file "/var/log/nginx/healthd/application.log.2020-07-21-09" does not exist
时间改变的地方.
最后一件可能相关的事情是我在 .ebextensions
目录中的单个文件的内容:
The last thing that may be relevant are the contents of my single file inside .ebextensions
directory:
option_settings:
"aws:elasticbeanstalk:application:environment":
DJANGO_SETTINGS_MODULE: "app.settings"
"PYTHONPATH": "/var/app/current:$PYTHONPATH"
"aws:elasticbeanstalk:container:python":
WSGIPath: app.wsgi:application
NumProcesses: 3
NumThreads: 20
aws:elasticbeanstalk:environment:proxy:staticfiles:
/static: static
/static_files: static_files
container_commands:
01_migrate:
command: "source /var/app/venv/staging-LQM1lest/bin/activate && python manage.py migrate --noinput"
leader_only: true
packages:
yum:
git: []
postgresql-devel: []
有人知道如何解决吗?最终目标是拥有绿色的OK健康.
Does anyone have any idea how can this be resolved? The ultimate goal is to have the green OK health.
编辑:最后,我切换到 Basic
健康系统,问题突然消失了.但是,我仍然有兴趣解决原始问题,因为 Enhanced
卫生系统提供了一些好处
In the end I switched to the Basic
health system and the problems suddenly went away. I am however still interested in solving the original problem as the Enhanced
health system provides some benefits
推荐答案
我相信您遇到的问题可能是由于文件settings.py中的ALLOWED_HOSTS设置所致.
I believe that the problem you have maybe due to the ALLOWED_HOSTS settings located in your file settings.py.
EB将HTTP请求发送到您的应用程序,以查看其是否正常运行,但是Django阻止了不是来自设置变量中指定主机的任何通信.但是这里有一个问题,EB将请求发送到ec2实例的私有ip.
EB sends an HTTP request to your application to see if its working but Django blocks any communication that is not from the specified hosts in the setting variable. But there is a problem here, EB sends the request to the private ip of the ec2 instance.
解决此问题的最简单方法是在 settings.py
文件中允许这样的所有主机:
The easiest way to solve this is to allow all HOSTS like this inside your settings.py
file:
ALLOWED_HOSTS=['*']
这可能会导致安全问题,但这是最快的方法.现在,为了使其能够动态工作,由于ec2实例可以随时启动,因此私有ip随实例的变化而变化.
This may lead to security issues but is the fastest way to do it. Now, to make it work dynamically, since ec2 instances can be spin-up at any time the private ip change from instance to instance.
要解决此问题,您必须在部署过程开始时获得专用IP.
To solve this you have to get the private IP at the beginning of the deployment process.
在 settings.py
的顶部放置以下功能:
At the top of your settings.py
place the following functions:
import os
import requests
# Other imports ...
def is_ec2_linux():
"""Detect if we are running on an EC2 Linux Instance
See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
"""
if os.path.isfile("/sys/hypervisor/uuid"):
with open("/sys/hypervisor/uuid") as f:
uuid = f.read()
return uuid.startswith("ec2")
return False
def get_token():
"""Set the autorization token to live for 6 hours (maximum)"""
headers = {
'X-aws-ec2-metadata-token-ttl-seconds': '21600',
}
response = requests.put('http://169.254.169.254/latest/api/token', headers=headers)
return response.text
def get_linux_ec2_private_ip():
"""Get the private IP Address of the machine if running on an EC2 linux server.
See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html"""
if not is_ec2_linux():
return None
try:
token = get_token()
headers = {
'X-aws-ec2-metadata-token': f"{token}",
}
response = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', headers=headers)
return response.text
except:
return None
finally:
if response:
response.close()
# Other settings
最重要的功能是 get_token()
和 get_linux_ec2_private_ip()
,第一个设置访问令牌并对其进行检索,第二个使用该访问令牌以使用它并获取当前的ec2实例IP.
The most important functions are get_token()
and get_linux_ec2_private_ip()
, the first one sets the access token and retrieves it for the second one to use it and get the current ec2 instance IP.
一旦检索到它,将其添加到您的ALLOWED_HOSTS
Once you have retrieved it, add it to your ALLOWED_HOSTS
ALLOWED_HOSTS = ['127.0.0.1', 'mywebsite.com']
private_ip = get_linux_ec2_private_ip()
if private_ip:
ALLOWED_HOSTS.append(private_ip)
此后,只需提交您的更改,并在设置了EB CLI的情况下使用 eb deploy
重新部署.
After that just commit your changes and redeploy it with eb deploy
if you have set the EB CLI.
这篇关于如何解决AWS Elastic Beanstalk Django运行状况检查问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!