Faça o download da versão mais recente para o Mac OS X Baixe a versão mais recente do download Baixe a versão mais recente para o Windows Baixe as últimas versões do Python OpenPGP Public Keys Fonte e os executáveis binários são assinados pelo gerenciador de versão usando sua chave OpenPGP. Os gerentes de lançamento e construtores binários desde o Python 2.3 foram: Nota: O ID da chave Barrys A74B06BF é usado para assinar os lançamentos do Python 2.6.8 e 2.6.9. Seu identificador de chave EA5BBD71 foi usado para assinar todas as outras versões do Python 2.6 e 3.0. Sua chave ID ED9D77D5 é uma chave v3 e foi usada para assinar versões anteriores. Você pode importar as chaves públicas do gerenciador de lançamento baixando o arquivo de chave pública daqui e depois executando ou agarrando as chaves individuais diretamente da rede do servidor de chaves executando este comando: nas páginas de download específicas da versão, você deve ver um link para Tanto o arquivo para download quanto um arquivo de assinatura separado. Para verificar a autenticidade do download, pegue os dois arquivos e, em seguida, execute este comando: Observe que você deve usar o nome do arquivo de assinatura, e você deve usar o que for apropriado para o download que você está verificando. (Estas instruções são orientadas para os usuários de linha de comando GnuPG e Unix. Contribuições de instruções para outras plataformas e aplicativos OpenPGP são bem-vindos.) Outros itens úteis Procurando por módulos Python de terceiros. O índice do pacote tem muitos deles. Você pode visualizar a documentação padrão on-line, ou pode fazer o download em HTML, PostScript, PDF e outros formatos. Veja a página principal da Documentação. Informações sobre ferramentas para descompactar arquivos de arquivo fornecidos no python. org estão disponíveis. Gorjeta . Mesmo se você baixar um binário pronto para sua plataforma, faz sentido baixar a fonte. Isso permite que você navegue na biblioteca padrão (o subdiretório Lib) e as coleções padrão de demonstrações (Demo) e ferramentas (Ferramentas) que acompanham. Há muito que você pode aprender com a fonte. Existe também uma coleção de pacotes Emacs que o Emacsing Pythoneer pode achar útil. Isso inclui modos principais para edição Python, C, C, Java, etc. Python debugger interfaces e muito mais. A maioria dos pacotes é compatível com Emacs e XEmacs. Deseja contribuir Quer contribuir Veja o Guia do Desenvolvedor Python para saber como o desenvolvimento do Python é gerenciado. Nicholas Pil Benchmark dos Servidores WSGI do Python Faz um tempo desde o Socket Benchmark of Asynchronous server. Esse benchmark analisou especificamente o desempenho do soquete bruto de vários frameworks, que estava sendo comparado ao fazer uma solicitação HTTP regular contra o servidor TCP. O servidor em si era burro e na verdade não entendia os cabeçalhos serem enviados para ele. Neste benchmark, vou analisar a forma como os diferentes servidores WSGI executam exatamente essa tarefa o tratamento de uma solicitação HTTP completa. Devo começar imediatamente com uma palavra de cautela. Provei o meu melhor para apresentar um benchmark objetivo dos diferentes servidores WSGI. E eu realmente acredito que um benchmark é um dos melhores métodos para apresentar uma comparação imparcial. No entanto, um benchmark mede o desempenho em um domínio muito específico e pode muito bem ser que este domínio esteja inclinado para certas estruturas. Mas, se mantivermos isso em mente, podemos realmente colocar algumas medidas por trás de todas essas reclamações que 8216 maiores que 8217 ou 8216 maiores do que 8217, você encontrará em todos os lugares. É minha opinião que essa comparação afirma sem uma descrição detalhada de como eles são medidos é pior do que um benchmark tendencioso, mas detalhado. O domínio específico deste benchmark é, mais uma vez, o benchmark PingPong usado anteriormente no My Async Socket Benchmark. No entanto, existem algumas diferenças: vamos disparar vários pedidos através de uma única conexão, quando possível, usando uma conexão HTTP 3.1 keepalive. É um benchmark distribuído com vários clientes. Usaremos um aplicativo WSGI idêntico para todos os servidores em vez do código especialmente criado Para retornar a resposta Esperamos que o servidor compreenda nossa solicitação HTTP e responda com os códigos de erro corretos. Esse benchmark é conceitualmente simples e você pode afirmar que isso não é representável para a aplicação web mais comum que depende muito do bloqueio de conexões de banco de dados. Eu concordo com isso, até certo ponto, porque este é principalmente o caso. No entanto, o impulso para os websockets do HTML58217 e aplicações web altamente interativas exigirá servidores que sejam capazes de atender muitas conexões concorrentes com baixa latência. O benchmark Executaremos o seguinte aplicativo WSGI 8216pong. py8217 em todos os servidores. Também ajustaremos o cliente e o servidor executando os seguintes comandos. Isso basicamente habilita o servidor a abrir lotes de conexões simultâneas. Echo 822010152 655358243 gt procsysnetipv4iplocalportrange sysctl - w fs. file-max128000 sysctl - w net. ipv4.tcpkeepalivetime300 sysctl - w net. core. somaxconn250000 sysctl - w net. ipv4.tcpmaxsynbacklog2500 sysctl - w net. core. netdevmaxbacklog2500 ulimit - n 10240 O O servidor é uma máquina virtual com apenas um processador atribuído. Limitei explicitamente a quantidade de processadores disponíveis para garantir que seja uma comparação justa. Seja ou não o servidor escalar múltiplos processadores é uma característica interessante e útil, mas isso não é algo que eu avaliarei nesse benchmark. A razão para isso é que não é difícil escalar seu aplicativo para vários processadores usando um proxy reverso e vários processos do servidor (isso pode até ser gerenciado para você por aplicativos especiais, como spawning ou Grainbows). O servidor e os clientes executam o Debian Lenny com o Python 2.6.4 na arquitetura amd64. Certifiquei-me de que todos os servidores WSGI tenham um conjunto de backlog de pelo menos 500 e que o log de conexão (connectionerror) esteja desativado, quando isso não foi diretamente possível do Callable, eu modifiquei a biblioteca. O servidor e os clientes têm 1GB de ram. Eu avaliei a taxa de solicitação HTTP1.0 de todo o servidor e a taxa de solicitação HTTP1.1 no subconjunto de servidores que suportam pipelining múltiplas solicitações em uma única conexão. Embora a falta de compatibilidade HTTP 1.1 suporte seja provavelmente um problema em situações de implantação atual, espero que ele se torne uma característica importante em aplicativos que dependem fortemente de conexões de baixa latência. Você deve pensar em aplicativos ou aplicativos da Web estilo cometas que usam websockets HTML5. Eu categorizo um servidor como HTTP1.1 capaz por seu comportamento, não por suas especificações. Por exemplo, o servidor Paster diz que tem algum suporte para o HTTP 1.1 manter alives mas não consegui encaminhar vários pedidos. Este bug relatado pode ser relevante para esta situação e pode ser aplicado a alguns dos outros Servidores 8220HTTP 1.08221. O benchmark será executado executando um httperf recompilado (que ignora o limite de arquivo compilado estático no pacote debian) em 3 máquinas de cliente especialmente configuradas. Para inicializar as diferentes taxas de solicitação e agregar os resultados, usarei uma ferramenta chamada autobench. Nota: este não é ApacheBench (ab). O comando para benchmaratar servidores HTTP1.0 WSGI é: httperf 8211hog 8211timeout5 8211client01 8211servertsung1 8211port8000 8211uri 8211rate ltRATEgt 8211send-buffer4096 8211recv-buffer16384 8211num-conns400 8211num-calls1 E o comando para servidores HTTP1.1 WSGI é: httperf 8211hog 8211timeout5 8211client01 8211servertsung1 8211port8000 8211uri 8211rate ltRATEgt 8211send-buffer4096 8211recv-buffer16384 8211num-conns400 8211num-calls10 Os Concorrentes O Python é realmente rico em servidores WSGI, criei uma seleção de servidores diferentes que estão listados abaixo. A maioria das informações nesta tabela deve ser bastante direta, eu especifico a versão avaliada e se o servidor foi encontrado ou não capaz de HTTP 1.1. O sabor do servidor especifica o modelo de concorrência que o servidor usa e eu identifico 3 sabores diferentes: Processador Modelo do fio O modelo pt é o sabor mais comum. Cada solicitação é executada em seu próprio fio limpo. Uma solicitação de bloqueio (como uma chamada de banco de dados síncrono ou uma chamada de função em uma extensão C) não influenciará outros pedidos. Isso é conveniente, pois você não precisa se preocupar sobre como tudo está implementado, mas ele vem com um preço. A quantidade máxima de conexões concorrentes é limitada pelo seu número de trabalhadores ou threads e isso é conhecido por escalar mal quando você tem a necessidade de muitos usuários concorrentes. Modelo do Gerador de Callback O modelo do callbackgenerator lida com múltiplas conexões simultâneas em um único segmento, removendo assim a barreira do thread. Uma única chamada de bloqueio bloqueará todo o ciclo de eventos e deve ser prevenida. Os servidores que têm esse sabor geralmente fornecem um threadpool para integrar chamadas de bloqueio em sua estrutura assíncrona ou fornecem conectores de banco de dados alternativos não bloqueáveis. Para fornecer controle de fluxo, esse sabor usa retorno de chamada ou geradores. Alguns pensam que esta é uma ótima maneira de criar uma forma de programação dirigida por eventos que os outros pensam que é um poço de cobras que muda rapidamente seu código limpo para uma bagunça emaranhada de retorno de chamada ou declarações de rendimento. O sabor leve usa greenlets para fornecer simultaneidade. Isso também funciona fornecendo simultaneidade a partir de um único tópico, mas de uma maneira menos intrusiva, então com as devoluções de chamada ou a abordagem do gerador. Mas é claro que é preciso ter cuidado ao bloquear as conexões, pois isso irá parar o loop de eventos. Para evitar que isso aconteça, Eventlet e Gevent podem monitorizar o módulo de soquete para impedir que ele seja bloqueado, então, quando você estiver usando um conector de banco de dados python puro, isso nunca deve bloquear o loop. Concorrência fornece um adaptador de banco de dados assíncrono. Especificações de implementação para cada servidor WSGI Ruby pode estar cheio com todos os tipos de programadores de rockstar (o que quer que isso signifique), mas se eu tiver que nomear apenas um programador Python com algum tipo de 8216rockstar award8217, eu definitivamente nomearia o Chad Whitacre. Não são apenas as ótimas ferramentas que ele criou Testosterona, Aspen, Stephane. Mas, principalmente, como ele os promove com os mais impressionantes screencasts que já vi. De qualquer forma, o Aspen é um pequeno servidor Web que também é capaz de atender às aplicações WSGI. Ele pode ser facilmente instalado com a instalação 8216pip aspen8217 e usa uma estrutura de diretório especial para a configuração e, se você quiser mais informações, eu vou apontar você para seus screencasts. CherryPy é realmente um framework Python orientado a objetos, mas possui um excelente servidor WSGI. A instalação pode ser feita com uma simples instalação de 8216pip, cherrypy8217. Eu executei o seguinte script para testar o desempenho do servidor WSGI: O código para que o Cogen execute um aplicativo WSGI é o seguinte: Concorrência A Concorrência é uma estrutura assíncrona em desenvolvimento por Hyves (você pode chamá-lo do Facebook holandês) com base em Libevent (Usei a última versão estável 1.4.13), ativei o aplicativo pong da seguinte forma: Eventlet é uma estrutura assíncrona com todas as funcionalidades que também fornece a funcionalidade do servidor WSGI. Está em desenvolvimento pela Linden Labs (fabricantes do Second Life). Para executar o aplicativo, usei o seguinte código: FAPWS3 é uma compilação do servidor WSGI em torno da biblioteca LibEV (usei a versão 3.43-1.1). Quando o LibEV foi instalado, o FAPWS pode ser facilmente instalado com pip. A filosofia por trás do FAPWS3 é manter o servidor web mais simples e rápido. O script que eu usei para iniciar o aplicativo WSGI é o seguinte: Gevent é uma das estruturas Async de melhor desempenho no meu benchmark de soquete anterior. O Gevent estende o Libevent e usa sua funcionalidade de servidor HTTP extensivamente. Para instalar o Gevent, você precisa do Libevent instalado depois do qual você pode puxar o Gevent com o PIP. O código acima executará o aplicativo pong sem gerar um Greenlet em cada pedido. Se você deixar de lado o argumento 8217spawnNone8217, o Gevent gerará um Greenlet para cada novo pedido. Gunicorn significa 8216Green Unicorn8217, todos sabem que um unicórnio é uma mistura do narwhal incrível e o pônei magnífico que o verde não tem nada a ver com os grandes greenlets, pois realmente tem um sabor roscado. A instalação é fácil e pode ser feita com uma simples instalação de 8216pip. Gunicorn8217 Gunicorn fornece um comando simples para executar aplicativos do wsgi, tudo o que eu tinha que fazer era: gunicorn - b: 8000 - w 1 pong: atualização do aplicativo: eu tive algumas sugestões em A seção de comentários que usar um único trabalhador e ter um cliente se conectar ao servidor nu não é a maneira correta de trabalhar com o Gunicorn. Então tomei suas sugestões e movi Gunicorn atrás de NGINX e aumentou a contagem de trabalhadores para o número sugerido de trabalhadores, 2N1, onde N é 1, o que faz 3. O resultado disso está representado nos gráficos como gunicorn-3w. A correr Gunicorn com mais trabalhadores pode ser feito, como: gunicorn - b unix: varnginxuwsgi. sock - w 3 pong: aplicação MagnumPy deve ser o servidor com o nome mais incrível. Este ainda é um projeto muito jovem, mas sua página inicial está fazendo algumas declarações fortes sobre seu desempenho, por isso vale a pena testar. Não se sente tão polido como os outros concorrentes e a instalação basicamente está empurrando o diretório 8216magnum8217 em seu PYTHONPATH edite 8216.magnumconfig. py8217, após o qual você pode iniciar o servidor executando 8216.magnumserve. py start8217 ModWSGI é o sucessor do ModPython, ele Permite que você integre facilmente o código Python com o servidor Apache. Minha primeira experiência de aplicação web em python foi com modelos de modpython e PSP, WSGI e frameworks legais como Pylons realmente tornaram a vida muito mais fácil. ModWSGI é uma ótima maneira de obter seu aplicativo implantado rapidamente. Instalar 8216ModWSGI8217 é com a maioria das distribuições Linux muito fácil. Por exemplo: aptitude install libapache2-mod-wsgi É tudo o que você precisa fazer em uma distrofia Debian pristine para obter um servidor Apache (MPM-Worker) com ModWSGI ativado. Para apontar o Apache para o seu aplicativo WSGI, basta adicionar uma única linha para 8216etcapache2httpd. conf8217: o problema é que a maioria das pessoas já possui o Apache instalado e que o está usando para o shudder que serve o PHP. O PHP não é thread-safe, o que significa que você é forçado a usar um servidor Apache pré-bifurcação. Neste ponto de referência, estou usando a versão de Apache enfocada e uso modwsgi no modo incorporado (pois me deu o melhor desempenho). Desabilitei todos os módulos desnecessários e configurei o Apache para me fornecer um único trabalhador, muitos threads e logs desativados (nota: eu tentei várias configurações): O servidor Web Paster é o servidor web fornecido com Python Paste é o servidor web padrão do Pylons. Você pode executar um aplicativo WSGI da seguinte maneira: Tornado é o servidor web não-bloqueador que alimenta o FriendFeed. Ele fornece algumas funcionalidades do servidor WSGI que podem ser usadas conforme descrito abaixo. No benchmark anterior, mostrei que ele oferece excelente desempenho de soquete em bruto. Depois de instalar o Twisted com PIP, você obtém uma ferramenta 8216twistd8217 que permite que você possa facilmente usar as aplicações WSGI fe: wistd 8211pidfiletmptwisted. pid - no web 8211wsgipong. application 8211logfiledevnull Mas você também pode executar uma aplicação WSGI da seguinte maneira: uWSGI é um servidor escrito em C, Não se destina a ser executado autônomo, mas deve ser colocado atrás de um servidor web. Fornece módulos para Apache, NGINX, Cherokee e Lighttpd. Eu o coloquei atrás do NGINX, que eu configurei da seguinte maneira: Isso fez o NGINX ouvir em um soquete unix, agora tudo o que eu precisava fazer era uWSGI conectar-se a esse mesmo soquete unix, o que eu fiz com o seguinte comando: uwsgi - s varnginxuwsgi. Sock - i - H homenicholasbenchmarkwsgibench - M - p 1 - w pong - z 30 - l 500 - L WsgiRef é o servidor WSGI padrão incluído no Python desde a versão 2.5. Para que este servidor execute meu aplicativo, uso o código a seguir que desabilita o registro e aumenta o atraso. Abaixo você encontrará os resultados como plotados com Highcharts, a linha irá engrossar quando se deslocou e você pode facilmente ativar ou desativar os resultados traçados clicando na legenda. Resultados do servidor HTTP 1.0 A partir do gráfico acima, deve ficar claro que alguns dos servidores da Web estão faltando, o motivo é que não consegui tê-los completamente comparados, pois eles deixaram de responder quando a taxa de solicitação ultrapassou um determinado valor crítico. Os servidores que estão faltando são: MagnumPy, consegui obter uma taxa de resposta de 500 RPS, mas quando a taxa de solicitação passou na marca 700 RPS, MagnumPy caiu Concurrence, consegui obter uma taxa de resposta bem sucedida de 700 RPS, mas Parou de responder quando disparamos mais de 800 pedidos por segundo no servidor. No entanto, uma vez que a Concurrence suporta HTTP1.1 mantém conexões vivas e se comporta corretamente quando comparado com uma taxa de conexão mais baixa, mas uma taxa de solicitação mais alta, você pode encontrar seus resultados no Cogen de benchmark HTTP1.1, conseguiu obter uma taxa de resposta de 800 por segundo Mas parou de responder quando a taxa de solicitação foi superior a 1500 por segundo. No entanto, ele possui uma referência completa sob o teste HTTP1.1. WSGIRef, obtive uma taxa de resposta de 352, mas parou de reagir quando passamos a marca de 1900 RPS Paster, obteve uma taxa de resposta de 500, mas falhou quando passamos a marca RPS 2000. Dos servidores que passaram o benchmark podemos ver que eles Todos têm uma performance admirável. Na parte inferior, temos Twisted e Gunicorn, o desempenho de Twisted é um tanto esperado, e não está realmente ajustado para o desempenho do WSGI. Eu acho o desempenho de Gunicorn um pouco decepcionante, também porque, por exemplo, Aspen, que é um Python puro há alguns anos, mostra um desempenho melhor e significativo. No entanto, podemos ver que aumentar a contagem de trabalhadores, de fato, melhora o desempenho, pois é capaz de obter uma taxa de resposta competitiva com o Aspen. Os outros servidores python puros, CherryPy e Tornado parecem estar a par do ModWSGI. Parece que CherryPy tem uma ligeira vantagem de desempenho sobre o Tornado. Então, se você está pensando mudar de ModWSGI ou CherryPy para Tornado por causa de um aumento de desempenho, você deve pensar novamente. Não só esse benchmark mostra que não há muito a ganhar. Mas você também abandonará o modelo processthread, o que significa que você deve ser cauteloso com o código que bloqueia seu intérprete. Os melhores resultados são claramente FAPWS3, uWSGI e Gevent. O FAPWS3 foi projetado para ser rápido e reflete as expectativas, isso foi observado por outros, e parece que está sendo usado na produção no Ebay. O uWSGI é utilizado com sucesso na produção em (e em desenvolvimento por) o ISP Unbit italiano. O Gevent é um projeto relativamente jovem, mas já tem muito sucesso. Não só funcionou bem no benchmark de servidor assíncrono anterior, mas sua dependência do servidor Libevent HTTP oferece um desempenho além das outras estruturas assíncronas. Devo notar que a diferença entre esses top 3 é muito pequena para declarar um vencedor claro do concurso de taxa 8216reply8217. No entanto, quero enfatizar que, com quase todos os servidores, tive que ter cuidado para manter a quantidade de conexões simultâneas baixas, pois os servidores enxertados não gostavam de muitas conexões concorrentes. Os servidores assíncronos (Gevent, Eventlet e Tornado) ficaram felizes em trabalhar com o que foi lançado sobre eles. Isso realmente dá uma ótima sensação de estabilidade, pois você não precisa se preocupar com configurações, como pools, contagem de funcionários etc. A maioria dos servidores tem um tempo de resposta aceitável. Twisted e Eventlet são um pouco do lado lento, mas Gunicorn mostra, infelizmente, um aumento dramático de latência quando a taxa de solicitação ultrapassa a marca de 1000 RPS. Aumentar a contagem de trabalhadores de Gunicorn reduz esta latência por muito, mas ainda no lado alto, em comparação com, por exemplo, Aspen ou CherryPy. As baixas taxas de erro para CherryPy, ModWSGI, Tornado, uWSGI devem dar confiança a todos em sua adequação para um ambiente de produção. Resultados do servidor HTTP 1.1 No benchmark HTTP1.1, temos uma lista diferente de concorrentes, pois nem todos os servidores conseguiram encaminhar múltiplas solicitações em uma única conexão. Neste teste, a taxa de conexão é relativamente baixa, por exemplo, uma taxa de solicitação de 8000 por segundo é de cerca de 800 conexões por segundo com 10 solicitações por conexão. Isso significa que alguns servidores que não conseguiram completar o benchmark HTTP1.0 (com taxas de conexão de até 5000 por segundo) podem completar o benchmark HTTP1.1 (Cogen e Concurrence, por exemplo). Este gráfico mostra a taxa de solicitação alcançada dos servidores e podemos ver claramente que a taxa de solicitação alcançada é maior do que no teste HTTP1.0. Poderíamos aumentar ainda mais a taxa de solicitação total, aumentando o número de solicitações pipeline, mas isso diminuirá a taxa de conexão. Eu acho que 10 pedidos pipelined é uma boa generalização de um webbrowser que abre uma página média. O gráfico mostra uma enorme diferença na diferença de desempenho, com o servidor mais rápido Gevent podemos obter cerca de 9000 respostas por segundo, com Twisted, Concurrence e Cogen, chegamos a cerca de 1000. No meio, temos CherryPy e ModWSGI com eles, somos capazes Para obter uma taxa de resposta em torno dos 4000. É interessante que Tornado, ao estar perto de CherryPy e ModWSGI, parece ter uma vantagem neste benchmark em comparação com a vantagem que CherryPy teve no benchmark HTTP1.0. Isto é ao longo das linhas de nossas expectativas, como os pedidos pipelined em Tornado são mais baratos (já que é Async), então, em ModWSGI ou CherryPy. Esperamos que essa lacuna se alargue se aumentarmos o número de solicitações pipeline. No entanto, é difícil ver o quanto de um aumento de desempenho que isso proporcionaria em uma configuração de implantação, pois Tornado e CherryPy provavelmente estarão sentados atrás de um proxy reverso, por exemplo NGINX. Em tal configuração, o tipo de conexão entre o upstream eo proxy geralmente é limitado a HTTP1.0, o NGINX, por exemplo, nem suporta HTTP1.1 mantém conexões vivas com seus upstreams. Os melhores artistas são claramente uWSGI e Gevent. Eu benchmarked Gevent com a opção 8217spawnnone8217 para evitar que Gevent gerasse um Greenlet, isso parece justo em um benchmark como este. No entanto, quando você quer fazer algo interessante com muitas conexões concorrentes, você deseja que cada solicitação tenha seu próprio Greentlet, pois isso permite que você tenha um fio como controle de fluxo. Assim, eu também avaliei essa versão que pode ser vista no Gráfico sob o nome 8216Gevent-Spawn8217, a partir de seus resultados podemos ver que a penalidade de desempenho é pequena. Cogen está recebendo uma alta latência após cerca de 2000 pedidos por segundo, Eventlet e Twisted mostram uma latência aumentada bastante cedo também. A taxa de erro mostra que Twisted, Concurrence e Cogen têm algum problema para manter, acho que todas as outras taxas de erro são aceitáveis. Uso da memória Também monitorizei o uso da memória das diferentes estruturas durante o benchmark. A referência indicada abaixo é o uso máximo de memória de todos os processos acumulados. Como este benchmark realmente não se beneficia de processos adicionais (como existe apenas um processador disponível), eu limitava a quantidade de trabalhadores quando possível. A partir desses resultados, há uma coisa que realmente se destaca e esse é o uso de memória absolutamente baixa de uWSGI, Gevent e FAPWS3. Especialmente se considerarmos o desempenho deles. Parece que Cogen está perdendo memória, mas eu realmente não examinei isso. Gunicorn-3w mostra em comparação com Gunicorn um uso de memória relativamente alto. Mas deve-se notar que isso é causado principalmente pela mudança da implantação desnuda para a implantação após o NGINX, pois agora também precisamos adicionar o uso de memória do NGINX. Um único trabalhador de Gunicorn só leva cerca de 7.5Mb de memória. Let8217s Retroceda em um ponto inicial A primeira parte deste post focalizou-se puramente no desempenho RPS das diferentes estruturas sob uma carga elevada. Quando o servidor WSGI estava trabalhando bastante, poderia simplesmente responder a todos os pedidos de um determinado usuário e passar para o próximo usuário. Isso mantém a quantidade de conexões simultâneas relativamente baixas, tornando esse benchmark adequado para servidores web segmentados. No entanto, se vamos aumentar a quantidade de conexões simultâneas, nos encontraremos rapidamente nos limites do sistema, como explicado na introdução. Isso é comumente conhecido como o problema C10K. Servidores assíncronos usam um único segmento para lidar com múltiplas conexões e, quando efetivamente implementadas com, por exemplo, EPoll ou KQueue são perfeitamente capazes de lidar com uma grande quantidade de conexões simultâneas. Então, é isso o que vamos fazer, vamos levar os top-3 executando WSGI servidores, nomeadamente Tornado, Gevent e uWSGI (FAPWS3 falta de suporte HTTP1.1 tornou inadequado para este benchmark) e dar-lhes 5 minutos de ping - caos de omissão. Você vê, o ping-pong é um jogo simples e não é realmente a complexidade que o torna interessante, é a velocidade e a reação dos jogadores. Agora, o que é 5 minutos de caos de pingpong Imagine que por 5 minutos a cada segundo, um Airbus carregado com jogadores de ping-pong (500 clientes) e cada um desses jogadores vai bater-lhe exatamente 12 bolas (com um intervalo de 5 segundos) . Isso significaria que, após 5 segundos, você já devia retornar as voleas de 2000 jogadores diferentes ao mesmo tempo. Configuração do benchmark Tsung Para executar este benchmark, vou usar o Tsung. Que é uma ferramenta de teste de carga distribuída multi-protocolo escrita em Erlang. Teremos então 3 máquinas diferentes simulando o rampage do ping-pong. Usei o seguinte script de Tsung. Tsung Benchmark Results Deixe-me primeiro declarar que todos os três frameworks são perfeitamente capazes de lidar com esse tipo de carga, nenhum dos frameworks caiu a conexão ou pedidos ignorados. O que devo dizer já é uma conquista, considerando que eles tiveram que lidar com cerca de 2 milhões de solicitações cada. Abaixo do gráfico de conexão concorrente, podemos ver a carga do sistema, o uso da CPU e a memória livre no sistema durante o benchmark. Podemos ver claramente que o Gevent colocou menos pressão sobre o sistema conforme o gráfico da CPU e da carga indicam. No gráfico de memória, podemos ver que todas as estruturas usaram uma quantidade consistente de memória. Os leitores que ainda prestam muita atenção a este artigo devem ter em atenção que o gráfico da memória exibe 4 linhas em vez de 3. A quarta linha é Gevent compilada contra Libevent 2.0.4a. A nova versão do Libevent mostrou melhorias de desempenho consideráveis em seu servidor HTTP. Mas ainda é uma versão alfa eo gráfico de memória mostra que esta versão está vazando memória. Não é algo que você deseja no seu site de produção. O gráfico final mostra a latência dos 3 quadros que podemos ver uma clara diferença entre Tornado e seus competidores, já que o tempo de resposta de Tornado8217s paira em torno de 100ms, uWSGI em torno de 5ms e gevent em torno de 3ms. Esta é uma grande diferença e estou realmente impressionado com a baixa latência de Gevent e uWSGI durante esta investida. Resumo e Comentários Os resultados acima mostram que, como desenvolvedor web Python, temos muitos métodos diferentes para implantar nossos aplicativos. Alguns deles parecem funcionar melhor do que outros, mas ao focar apenas no desempenho do servidor, não justificarei a maioria dos servidores testados, pois eles diferem muito em funcionalidades. Além disso, se você vai levar algum estoque de estrutura da web e won8217t fazer otimizações ou cache, o desempenho do seu servidor web não vai importar, pois isso não será o gargalo. Se há uma coisa que tornou este ponto de referência claro, é que a maioria dos servidores da Web Python oferecem ótimos desempenhos e se você sente que as coisas estão lentas, a primeira coisa a ser realmente é sua própria aplicação. Quando você está apenas interessado em hospedar rapidamente sua aplicação threadada, você realmente pode dar errado com o Apache ModWSGI. Mesmo que o Apache ModWSGI possa colocar um pouco mais de tensão em seus requisitos de memória, há muito a ser utilizado em termos de funcionalidade. Por exemplo, proteger uma parte do seu site usando um servidor LDAP é tão fácil como habilitar um módulo. CherryPy autônomo também mostra um ótimo desempenho e funcionalidade e é realmente uma alternativa viável (totalmente Python) que pode reduzir os requisitos de memória. Quando você é um pouco mais aventureiro, você pode olhar para uWSGI e FAPWS3, eles são relativamente novos em comparação com CherryPy e ModWSGI, mas eles mostram um aumento significativo de desempenho e têm requisitos de memória mais baixos. Quanto ao Tornado e ao desempenho, não acho que Tornado seja uma alternativa para CherryPy ou mesmo ModWSGI. Não só dificilmente mostra qualquer aumento no desempenho, mas também exige que você repensue seu código. Mas Tornado pode ser uma ótima opção se você não tiver nenhum código usando conexões de bloqueio ou apenas quiser ver algo novo. E então há Gevent. Ele realmente mostrou desempenho incrível em uma pegada de memória baixa, pode precisar de alguns ajustes no seu código legado, mas, novamente, o patch de macaco do módulo de soquete poderia ajudar e eu realmente adoro a limpeza de Greenlets. Já houve alguns relatórios de implantação do Gevent com sucesso, mesmo com SQLAlchemy. E se você quer mergulhar em webs de alto desempenho com muitas conexões concorrentes, você realmente precisa seguir uma estrutura assíncrona. Gevent parece ser o companheiro perfeito para isso, pelo menos é o que vamos usar. 114 Respostas a 8220Benchmark de Python WSGI Servers8221 I8217m curioso se você verificou que os tópicos utilizados em cada servidor eram do mesmo tamanho (para aqueles servidores que utilizam threadpools. Isso poderia fazer uma diferença significativa nos resultados. Também pode ser interessante aprender além O ponto que aumenta o tamanho do threadpool não ajuda mais o desempenho. It8217s também vale a pena notar que vários dos melhores artistas, ao não usar threads, não estão realmente implementando um servidor WSGI de propósito geral e escalável. Eles tomam um atalho valioso que auxilia o desempenho, mas isso Deve ser considerado ao selecionar um servidor, uma vez que pode levar a um desempenho desastroso para determinadas aplicações. I8217m também curioso se você fez alguma análise dos erros que alguns dos servidores encontraram. De minhas investigações, I8217ve descobriu que isso está intimamente ligado ao pedido Taxa de transferência quando um servidor começa a atrasar a taxa de solicitação, se não continuar a aceitar novas conexões, muitos T As pilhas de CPIP começarão a rejeitar as próprias conexões TCP recebidas. Isso é um tanto útil para saber, mas acho que é preciso separar-se de uma falha que realmente ocorre dentro do software que está sendo testado, particularmente porque, neste caso, it8217s são principalmente redundantes com a informação sobre o número de solicitações em segundo lugar para cada servidor pode responder. Uma última coisa. Pergunto-me se você tem alguma informação sobre a distribuição dos tempos de resposta. Os gráficos dos tempos médios (eu suponho) são interessantes, mas saber como os dados brutos se parecem também é importante (e, na verdade, é necessário para interpretar corretamente o resto dos dados que você apresentou aqui). Grande trabalho até agora. Espero que você continue assim. Eu também espero que, em algum momento, algo seja descartável que as pessoas possam usar para reproduzir seus resultados, além de ampliar a análise feita sobre eles. I tried to maximize the performance of the various frameworks by optimizing the threadpool, but this is kinda painful to perform because when a pool gets too big it can crash the server. So i assume that some gains are possible, but i suspect that those gains will be relatively small though. Concerning the errors, you can see a difference in the kind of errors between the servers that are able to complete the benchmark and those who aren8217t. But yes i could have specified wether it was a connection reset or a timeout, but the article was getting really long already. The mean values are indeed depicted in the graph, while I agree that the STD would be interesting to show as well the graphs are already very crowded and i find that the curve can give me some indication of the stability of the mean. For example compare uWSGI against FAPWS3 after the 6000 RPS mark with each other. I checked, and increasing thread pool size does have significant impact on Twisted (YMMV), so I suspect the same would be true for other thread pool-based frameworks. Very interesting benchmark it confirms my personal experience with the WSGI webserver i have tested modwsgi cherrypy and uwsgi. I would be interesting to know which version for each web server you have used. Just a note on the gunicorn numbers. Running the server with a single worker process is constraining any ability for concurrency in its responses. Its meant to run with 2-4x the number of processors you have on the machine. There8217s also a slight gotchya in the motivation for implementing HTTP1.1. Nginx8217s proxy is only HTTP1.0, so if you need to use it to scale out multiple python server processes there8217s no benefit from HTTP1.1 which is why gunicorn didn8217t bother to implement it. (As its designed to be proxied by nginx). If I get some time later I8217ll try and rerun some of these numbers on bigger hardware. I8217ve personally seen gunicorn run that HTTP1.0 benchmark 10K reqs faster than gevent does. Thanks for the writeup, Paul Davis I understand these gotcha and i mentioned it in the article. If i could be of any help please let me know. I could rerun the bench somewhere in the future with more assigned processors and workers to specifically test out that case, if you want. Remember that gunicorn isn8217t like the rest of web servers in terms of its process utilization. Even when its only got a single core allocated for use it will still benefit from an increase in the number of workers allocated. Configuring gunicorn with a single worker is like configuring all the threaded servers to use a single thread, its just not how it was intended to be run. Also, in your httperf invocation, did you keep the number of connections a constant for every test Ie, were the 4K rs tests taking 110th of a second That might explain some of the noise in the graphs. I am running Gunicorn right now with 3 workers, thus i have a master processes and 3 workers (and ofcourse the NGINX processes). I8217ll add it to the benchmark when its done, the main reason why i did not try multiple workers was because this would have a negative influence on the memory statistics and I did not expect any performance increase. From the initial results i8217m getting back from the current benchmark it does seem to improve the results for Gunicorn moving it to a more respectable position. Feel free to report the sum of the process memory. There are some oddities with copy-on-write semantics but I8217ve never heard of a good way to tease those apart for proper usage reports. You mentioned putting uWSGI behind nginx but didn8217t say anything about doing the same for gunicorn. Does that mean you ran the benchmarks without nginx proxying for gunicorn Gunicorn isn8217t designed to be used like that 8212 it8217s supposed to live behind nginx (or something similar) just like uWSGI. gunicorn. orgdeployment. html describes the way you8217re supposed to deploy gunicorn. Thats correct, however, i did try to put it behind NGINX (via a Unix socket) and that did not give me any performance increase. I am also having a difficult time how that would improve performance as I only use a single worker. In this specific case it doesn8217t matter whether you run gunicorn behind nginx as the wsgi app and the clients are both super duper fast. Gunicorn depends on having a buffering proxy to deal with client load as described at 1. Slowloris is obviously an extreme example of slow client behavior but a public facing server will obviously be exposed to the entire spectrum of client speed between super fast and super slow. Using 8216ThreadsPerChild 160008242 for Apachemodwsgi is just plain stupid. It is directly because of that that it had such a large memory footprint. If you drop that value down to below 100 you will probably find the same performance and yet a lot less memory being used. If your test program is merely a hello world application that returns a few bytes, you could possibly get away with a lot less threads than 100. Some high performance sites with a lot of requests, but where Apache and the application has been tuned properly, get away with 2 or 3 threads in single daemon mode process. When using Apachemodwsgi, forcing use of a single process is also going to make performance suffer due to limitations of the GIL. The strength of Apachemodwsgi is that you can fire up multiple processes and avoid these GIL issues, especially where using a multi processorcore system. I suggest you go back and redo your Apachemodwsgi tests starting with the Apache default of 25 threads in one process for embedded. If you see it start to suffer under high number of concurrent requests, then add more processes as well and not just threads, with more processes and dropping threads actually better. Thanks, for your remarks Graham. I obviously did not have the amount of threads set to that insane amount of 16k as this will invoke the OOM killer on my machine. The 16k setting is a left over from when i tried to have Apache competing in the Tsung benchmark, that didn8217t work. As noted i experimented with some of the settings to obtain an optimal balance of not increasing the error rate (in the HTTP 1.1 benchmark which can force a lot of concurrent connections). For the benchmark i used a thread setting of 1000, lowering this number would raise the error rate. With this setting the memory usage starts at a relatively low of 21Mb but as the benchmark progresses it reaches 64Mb. I could try splitting the amount of threads over multiple processes because indeed the issues you mention could indeed hold back ModWSGI its performance. But I suppose that this would increase the memory usage, at least this was the main reason why I decided to limit it to one process. I will see, when and if I re-benchmark it. Btw, your other comment just popped in. I did not find out how to disable logging on Apache, can you give me a pointer Really interesting benchmark, but i think it could be really interesting to turn it in a challenge and make it more 8216real world usage8217 by only providing apps: - a simple pingpong app - a simple django app - a django app template - django app sqlite reads and or memcache readwrite and ask each server8217s community to tune and provide the optium setup for its specific server to achieve best performance. Also using hardware that is more uptodate, because i don8217t know any serious job getting done on a single core anymore I think that quad core and 24Go or ram is a better view of the server market. this challenge could be run on EC2 instances for example. And it should be noted that even the worse server in your benchmark with (1000 rs on a single core) would provide enought performance for 99 of current website needs. So feature and ease of use should be taken into account to choose a wsgi server. Great article, can8217t wait to read the next one First of all: nice benchmarks I must admit however that for choosing a Python WSGI server, I8217d base my choice for at least 50 on benchmarks with basic POST data handling to see what it8217s capable of8230 Maybe a follow up Very very useful test. Thanks for sharing it. Tornado looks great if all your communications are short bursts, but I8217m looking at gevent because some of our responses can be quite large. As a result, we would be unable to use the 8220normal8221 gevent. wsgi server (which is really the libevent server if I understand correctly) because we can8217t afford to buffer the messages in RAM for all those connections. I was wondering whether you have timing for gevent using the pywsgi server, which supports SSL and chunked response. I imagine that it would have very different characteristics. Yes, I8217d be very interested in seeing how gevent8217s pywsgi server compares. I8217m surprised Nicholas didn8217t mention the lack of keep-alive support in the libevent-http based one. At the time I tested gevent, the libevent server still had keep-alives enabled by default. The change to disable it is more recent than this benchmark and you can still enable it if you want. But I agree, it will be very interesting to test the PyWSGI server
OS RESULTADOS DE NEGOCIAÇÃO SUSCRICAM-SE aos PLANOS DE SINAIS DE NEGOCIAÇÃO (NOVO) NOTAS IMPORTANTES TESTEMUNHAS OS RESULTADOS DE NEGOCIAÇÃO para as Opções do Índice de Valores de Stock (8220SIO8221) Sinais de Negociação Os resultados de negociação abaixo são por Tamanho de Lote Padrão e a Conta de Margem Padrão de 15.000. Para o comércio de contas maiores, o tamanho do lote padrão deve aumentar de acordo, conforme ensinado no seminário 8220Managing Your Portfolio Portfolio8221, isso faz parte do Programa de Opções de Negociação de 10 Lucros por Mês. As maiores contas (75.000) comerciantes são aconselhados a se inscrever no Plano de Sinais de Negociação de Opções de Amostras de Mercadorias Futures. Estratégia e detalhes completos para cada comércio são revelados na página de Sinais de Negociação. DEC 2016: férias de inverno. Desejando-lhe um Feliz Natal e um feliz ano novo 2017 JUL 2016: Férias de verão AGO 8211 OCT 2015: Férias de verão Nordic SOCAP 2015, San Francisco, CA Estratégia ...
Comments
Post a Comment