Django REST framework, снижение производительности сериализатора - PullRequest
1 голос
/ 29 апреля 2020

У меня есть простое представление списка API, которое использует сериализатор:

class ListCreateDeploymentView(
    generics.ListCreateAPIView
):
    permission_classes = (IsAuthenticated,)
    renderer_classes = [JSONRenderer]
    content_negotiation_class = IgnoreClientContentNegotiation

    def get_queryset(self):
        queryset = Deployment.objects.all()
        return queryset

    def list(self, request, version):
        queryset = self.get_queryset()
        serializer = DeploymentListSerializer(queryset, many=True)
        data = serializer.data
        return Response(data)

Сериализатор прост:

class DeploymentListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Deployment
        fields = (
            'id',
            'query',
            'config',
            'started_at',
            'finished_at',
            'status',
            'project',
        )
        read_only_fields = (
            'id',
            'query',
            'config',
            'started_at',
            'finished_at',
            'status',
            'project',
        )

Затем я делаю локальный нагрузочный тест с 10 пользователями и задержкой 1 с Каждое выполнение, поэтому целевое число оборотов в секунду составляет 10 req / s, и через несколько минут вы видите это изображение с явным снижением производительности

enter image description here Что означает Если я открою 10 вкладок в браузере с ajax запрашивать каждую секунду к этой конечной точке, что сервер перестанет отвечать на запросы в течение минуты :

enter image description here

Затем я использовал рекомендации от здесь и используется обычный сериализатор только для чтения:

class DeploymentListSerializer(serializers.ModelSerializer):
    # commands = CommandListSerializer(read_only=True, many=True)
    # clients = ClientSimpleSerializer(read_only=True, many=True)
    id = serializers.IntegerField(read_only=True)
    query = serializers.CharField(read_only=True)
    config = serializers.CharField(read_only=True)
    started_at = serializers.DateTimeField(read_only=True)
    finished_at = serializers.DateTimeField(read_only=True)
    status = serializers.IntegerField(read_only=True)
    project = serializers.CharField(read_only=True)
    class Meta:
        model = Deployment
        fields = (
            'id',
            'query',
            'config',
            'started_at',
            'finished_at',
            'status',
            'project',
        )

Ситуация стала еще хуже: enter image description here Наконец, если я удалю сериализацию:

    def list(self, request, version):
        queryset = self.get_queryset()
        data = queryset.values(
            'id', 'query', 'config', 'started_at', 'finished_at',
            'status', 'project'
        )
        return Response(data)

И снова проведите тот же тест, производительность становится намного лучше (ожидаемой), но также стабильной: enter image description here

Проблема в том, что мне нужна сериализация, потому что задача немного сложнее и Мне нужно вернуть вложенные объекты, но это уже падает на такой Простой пример.

Что я не так делаю?

UPD: та же плохая картинка, если я использую функциональный вид:

@api_view(['GET'])
def get_deployments(request, version):
    queryset = Deployment.objects.all()
    serializer = DeploymentCreateSerializer(queryset, many=True)
    data = serializer.data
    return Response(data)
...