Qualquer otimização da prática é muito mais difícil

Adotamos um projeto da web python órfão esta semana, que foi mantido por vários desenvolvedores uma vez. Os antigos mantenedores não pararam com o mau cheiro do projeto. ~ 5s, que terrível), os usuários reclamam, temos que enfrentar o problema e resolvê-lo.

Meu mentor percebeu que havia vários SELECT COUNTs na página do painel. Não fazia sentido torná-lo tão em tempo real:

class Car(model):
@classmethod
def count(cls, category):
# select count from db

A otimização estava apenas armazenando em cache o resultado da contagem :

class Car(model):
@classmethod
@cache('car:{category}:count', expire=30)
def count(cls, category):
# select count from db

Usei essa forma rápida e não suja. Então os usuários sentiram a melhora na velocidade na página do painel.

Mas você entrou em todas as páginas da lista de categorias, ainda lento. Myql explain mostrou que o tipo de consulta de categoria é all, o pior tipo possível. A consulta contém duas condições where e um pedido. Tentei adicionar índice a um de onde condição, tipo se tornou. rangeDepois de adicionar índices a outros campos, tornou-se ref, o que pode ser aceito.

Naquela época, o custo médio da solicitação era de 1.000 ms.

Graças à equipe do app engine, adicionando app_engine_profile=truea cada URL, podemos facilmente obter os detalhes para criação de perfil. Eu tentei, gzipforam chamados 60.000 vezes e custaram 400 ms no ambiente de produção, mas outros projetos não mostraram essas chamadas gzip anormais. Com a dica de meu mentor, examinei o ponto de entrada do aplicativo.

Quando comentei totalmente o middleware gzip, o tempo de solicitação diminuiu de 120ms para 20ms no ambiente de desenvolvimento. Estava convencido de que havia alguns pontos de acesso relacionados ao gzip, então percebi o valor de retorno do aplicativo:

class Publisher(object):

def __call__(self, env, start_response):
body
= 'string'
return body # Iterable object.

Uau, todo mundo sabe que é um objeto iterável e cada artigo sobre WSGI dirá a você não enviar a saída um byte por um byte , mas os desenvolvedores ainda fizeram isso . Isso fez com que o gzip fosse aplicado a cada byte. Alterando ou resolvendo este problema.return [body]yield body

Esta tarde, quando implantei o código modificado para o teste, o ambiente de produção gerou muitas exceções causadas pelo cache do mako. Verifiquei, o projeto salvou o cache do mako no mfs e os dois ambientes usaram o mesmo cache do mako. Depois de resolver esse bug, a velocidade pode ser um pouco melhor, porque mfs é um sistema de arquivos de rede distribuído.

No final, o desempenho do projeto teve uma melhora considerável, mas ainda havia muito trabalho a ser feito.