2013-03-01 5 views
6

Próbuję zaimplementować zasób Tastypie, który pozwala na wykonywanie operacji POST GET & zgodnie z zasadą uprawnień użytkownika, model jest dość prosty (podobny do modelu Note w dokumentacji Tastypie) i sam zasób jest również całkiem proste, po prostu mam dodatkową metodę override_urls do implementacji wyszukiwania z Haystack.Django Tastypie powolna odpowiedź POST

Moim głównym problemem jest to, że chociaż uruchomienie projektu lokalnie wydaje się działać dobrze, żądania są szybkie i wszystko. Po wdrożeniu projektu (On Linode, używając Nginx, Gunicorn, Runit) odkryłem, że żądania POST są zbyt powolne, trwają około 1,1 minuty, aby powrócić ze statusem 201. Z drugiej strony żądania GET działają poprawnie i zgodnie z oczekiwaniami.

Uruchomiłem profiler Python Hotshot na żądanie i pokazuje, że całe żądanie POST trwa 0.127 sekund CPU. Nie jestem do końca pewien, co się tutaj dzieje.

Należy wspomnieć, że używam ApiKeyAuthentication i DjangoAuthorization dla mojego zasobu Tastypie.

Oto zrzut ekranu z Chrome Inspektora wniosek: http://d.pr/i/CvCS

Byłoby wspaniale, gdyby ktoś może skierować mnie w odpowiednim kierunku, aby szukać odpowiedzi na ten problem.

Dzięki!

Edit:

Niektóre kodu:

modele & zasobów:

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 Conf:

bind = "0.0.0.0:1330" 
workers = 1 

Nginx Conf (wliczone w głównej 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/; 
     } 
} 
+0

Pokaż nam teh codez –

+0

@Hedde edytował post –

+0

Dzięki uprzejmości ogólnie powinieneś wskazać, że zostało to również zakomunikowane w grupie google. Czy masz jakieś reguły przetwarzania sygnału ustawione w Modelu? W szczególności post_save? –

Odpowiedz

3

OP: Zorientowałem to. W głównym pliku nginx.conf (/etc/nginx/nginx.conf) okazało się, że mam ustawiony keepalive_timeout na 65, który jest uważany za zbyt duży. Zmieniłem go na 0 i wszystko działało dobrze.

Przykro mi spędzić kilka minut na to pytanie, a następnie realizowane było więcej komentarzy i wtedy zrozumiał, że PO nie znaleźć rozwiązanie :(i nie oznaczyć jako odpowiedział.

0

Podczas wymiany keepalive_timeout będzie . praca, to nie rozwiąże nginx, na których opierają Content-Length nagłówka błąd, który go powoduje ten błąd był fixed in version 0.8.32 of nginx, ale jeśli masz starszą wersję można:

  1. Zmiana keepalive_timeout = 0 na serwerze
  2. Uaktualnij nginx na swoim serwerze do wersji> = 0.8.32
  3. naprawić ten problem w swoim serwerze kodu po stronie jak wyjaśniono here

Mam nadzieję, że to pomoże ktoś inny, kto natknie się na ten błąd.