请求 timeout/delay 问题
Request timeout/delay Issue
我的应用程序 posts 使用 Django rest-framework 到 Instagram。发布到 Instagram 是一个两步过程。首先,您必须将内容发送到媒体容器。然后你必须等到 Instagram 处理完 photo/video。媒体处理完成后,您将创建 ID 发送到 Instagram 以制作 post public。为了确保 Instagram 在发送创建 ID 之前有足够的时间处理媒体,我使用 Django 的 time.sleep 函数将请求暂停 60 秒。问题是这在我的桌面上有效,但在我的 ec2 实例上,当我暂停请求超过 10 秒时,相同的代码失败。对于 运行 我的应用程序,我正在使用 amazon EC2、Gunicorn 和 nginx。
我的 Django 代码是这样的
```#print('posting photo to facebook')
video_url = data.get('video_url')
container_url = "https://graph.facebook.com/" + page_id + "/media?media_type=VIDEO&\
video_url=" + video_url + "&caption=" + text + "&access_token=" + access_token
res = requests.post(container_url)
data = res.json()
time.sleep(60)
publish_url = "https://graph.facebook.com/" + page_id + "/media_publish?\
creation_id=" + data['id'] + "&access_token=" + access_token
res = requests.post(publish_url)
data = res.json()
print('result of video posting attempt')
print(json.dumps(data));
a = res.status_code
b = 200
#print(res.text)
if a != b:
return Response(data = {"data": {"id":"" , "post_id":"" }})
return Response(data = data, status = res.status_code)```
我的gunicorn.service文件
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/xxxxx-xxxxxx-xxxxxx
ExecStart=/home/ubuntu/xxxxx-xxxxxx-xxxxxx/xxxxxxx/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
xxxxxxxxxx.wsgi:application
TimeoutStopSec=120
[Install]
WantedBy=multi-user.target
我的 nginx 配置文件
listen 80;
listen [::]:80;
server_name xxxxxxxxx.com *.xxxxxxxxx.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name xxxxxxxxx.com *.xxxxxxxxx.com;
#SSL/TLS settings
ssl_certificate /etc/letsencrypt/live/xxxxxxxxx.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxxxxxxxx.com/privkey.pem;
client_max_body_size 100M;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
location = /favicon.ico {
access_log off;
log_not_found off;
}
location /static/ {
root /home/ubuntu/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}```
我建议对延迟任务使用 celery。例如:
@shared_task
def task_make_public(publish_url):
res = requests.post(publish_url)
...
res = requests.post(container_url)
data = res.json()
publish_url = ...
task_make_public.apply_async((publish_url,), eta=now + timedelta(seconds=60))
django-background-tasks 的设置更简单。它不像 celery 那样需要 celeworker、celerybeat 和 reddis 来完成 运行 任务。
从 PyPI 安装
pip install django-background-tasks
添加到INSTALLED_APPS:
INSTALLED_APPS = (
# ...
'background_task',
# ...
)
迁移数据库
python manage.py migrate
代码示例
from background_task import background
from django.contrib.auth.models import User
@background
def task_make_public(publish_url):
res = requests.post(publish_url)
...
res = requests.post(container_url)
data = res.json()
publish_url = ...
task_make_public(publish_url, schedule=timedelta(seconds=60)) # 60 seconds from now
我的应用程序 posts 使用 Django rest-framework 到 Instagram。发布到 Instagram 是一个两步过程。首先,您必须将内容发送到媒体容器。然后你必须等到 Instagram 处理完 photo/video。媒体处理完成后,您将创建 ID 发送到 Instagram 以制作 post public。为了确保 Instagram 在发送创建 ID 之前有足够的时间处理媒体,我使用 Django 的 time.sleep 函数将请求暂停 60 秒。问题是这在我的桌面上有效,但在我的 ec2 实例上,当我暂停请求超过 10 秒时,相同的代码失败。对于 运行 我的应用程序,我正在使用 amazon EC2、Gunicorn 和 nginx。
我的 Django 代码是这样的
```#print('posting photo to facebook')
video_url = data.get('video_url')
container_url = "https://graph.facebook.com/" + page_id + "/media?media_type=VIDEO&\
video_url=" + video_url + "&caption=" + text + "&access_token=" + access_token
res = requests.post(container_url)
data = res.json()
time.sleep(60)
publish_url = "https://graph.facebook.com/" + page_id + "/media_publish?\
creation_id=" + data['id'] + "&access_token=" + access_token
res = requests.post(publish_url)
data = res.json()
print('result of video posting attempt')
print(json.dumps(data));
a = res.status_code
b = 200
#print(res.text)
if a != b:
return Response(data = {"data": {"id":"" , "post_id":"" }})
return Response(data = data, status = res.status_code)```
我的gunicorn.service文件
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/xxxxx-xxxxxx-xxxxxx
ExecStart=/home/ubuntu/xxxxx-xxxxxx-xxxxxx/xxxxxxx/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
xxxxxxxxxx.wsgi:application
TimeoutStopSec=120
[Install]
WantedBy=multi-user.target
我的 nginx 配置文件
listen 80;
listen [::]:80;
server_name xxxxxxxxx.com *.xxxxxxxxx.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name xxxxxxxxx.com *.xxxxxxxxx.com;
#SSL/TLS settings
ssl_certificate /etc/letsencrypt/live/xxxxxxxxx.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxxxxxxxx.com/privkey.pem;
client_max_body_size 100M;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
location = /favicon.ico {
access_log off;
log_not_found off;
}
location /static/ {
root /home/ubuntu/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}```
我建议对延迟任务使用 celery。例如:
@shared_task
def task_make_public(publish_url):
res = requests.post(publish_url)
...
res = requests.post(container_url)
data = res.json()
publish_url = ...
task_make_public.apply_async((publish_url,), eta=now + timedelta(seconds=60))
django-background-tasks 的设置更简单。它不像 celery 那样需要 celeworker、celerybeat 和 reddis 来完成 运行 任务。
从 PyPI 安装
pip install django-background-tasks
添加到INSTALLED_APPS:
INSTALLED_APPS = (
# ...
'background_task',
# ...
)
迁移数据库
python manage.py migrate
代码示例
from background_task import background
from django.contrib.auth.models import User
@background
def task_make_public(publish_url):
res = requests.post(publish_url)
...
res = requests.post(container_url)
data = res.json()
publish_url = ...
task_make_public(publish_url, schedule=timedelta(seconds=60)) # 60 seconds from now