Django Tastypie POST响应慢
我正在尝试实现一个Tastypie资源,这个资源允许根据每个用户的权限进行GET和POST操作。我的模型很简单(类似于Tastypie文档中的Note模型),资源本身也很简单,我只是多了一个override_urls的方法来实现使用Haystack进行搜索。
我现在面临的主要问题是,虽然在本地运行项目时一切正常,请求速度很快,但一旦我把项目部署到Linode上(使用Nginx、Gunicorn和Runit),我发现POST请求变得非常慢,返回201状态码大约需要1.1分钟。相比之下,GET请求则运行良好,表现如预期。
我在请求上运行了一个Python Hotshot分析工具,结果显示整个POST请求只消耗了0.127秒的CPU时间。我不太确定这里发生了什么。
我应该提到,我在我的Tastypie资源中使用了ApiKeyAuthentication和DjangoAuthorization。
这是来自Chrome检查器的请求截图:http://d.pr/i/CvCS
如果有人能给我指个方向,告诉我该往哪里找解决这个问题的答案,那就太好了。
谢谢!
编辑:
一些代码:
模型和资源:
class Note(models.Model):
timestamp = models.DateTimeField('Timestamp')
user = models.ForeignKey(User)
page_title = models.CharField("Page Title", max_length=200)
url = models.URLField('URL', verify_exists=False)
summary = models.TextField("Summary")
notes = models.TextField("Notes", null=True, blank=True)
def __unicode__(self):
return self.page_title
def get_absolute_url(self):
return self.url
class NoteResource(ModelResource):
user = fields.ForeignKey(UserResource, 'user')
class Meta:
queryset = Note.objects.all()
resource_name = 'note'
list_allowed_methods = ['get', 'post']
detail_allowed_methods = ['get']
always_return_data = True
authentication = ApiKeyAuthentication()
authorization = DjangoAuthorization()
# authentication = Authentication() #allows all access
# authorization = Authorization() #allows all access
ordering = [
'-timestamp'
]
def override_urls(self):
return [
url(r"^(?P<resource_name>%s)/search%s$" % (
self._meta.resource_name, trailing_slash()),
self.wrap_view('get_search'), name="api_get_search"),
]
def obj_create(self, bundle, request=None, **kwargs):
return super(NoteResource, self).obj_create(bundle,
request,
user=request.user)
def apply_authorization_limits(self, request, object_list):
return object_list.filter(user=request.user)
def get_search(self, request, **kwargs):
self.method_check(request, allowed=['get'])
self.is_authenticated(request)
sqs = SearchQuerySet().models(Note).filter(
user=request.user
).auto_query(
request.GET.get('q', '')
)
paginator = Paginator(sqs, 100)
try:
page = paginator.page(int(request.GET.get('page', 1)))
except InvalidPage:
raise Http404("Sorry, no results on that page.")
objects = []
for result in page.object_list:
bundle = self.build_bundle(obj=result.object, request=request)
bundle.data['score'] = result.score
bundle = self.full_dehydrate(bundle)
objects.append(bundle)
object_list = {
'objects': objects,
}
self.log_throttled_access(request)
return self.create_response(request, object_list)
Gunicorn配置:
bind = "0.0.0.0:1330"
workers = 1
Nginx配置(包含在主nginx.conf中):
server {
listen 80;
server_name domain.com example.com;
access_log /path/to/home/then/project/access.log;
error_log /path/to/home/then/project/error.log;
location / {
proxy_pass http://127.0.0.1:1330;
}
location /static/ {
autoindex on;
root /path/to/home/then/project/;
}
}
2 个回答
虽然调整keepalive_timeout可以解决一些问题,但它并不能修复nginx本身的一个关于Content-Length头部的bug。这个bug在nginx的0.8.32版本中已经被修复了。如果你使用的是旧版本,可以选择以下几种方法:
- 在你的服务器上将keepalive_timeout设置为0
- 把nginx升级到0.8.32或更高的版本
- 按照这里的说明,修复你服务器端代码中的问题
希望这些信息能帮助到遇到这个问题的其他人。
发帖者:我搞明白了。在主要的nginx配置文件(/etc/nginx/nginx.conf)里,我发现我把keepalive_timeout设置成了65,这个值太大了。我把它改成了0,一切就正常了。
抱歉,我花了几分钟在这个问题上,然后发现有更多的评论,最后才意识到发帖者已经找到了解决办法 :( 但没有标记为已解决。