0Pricing
PHP Academy · Aula

Servidores de alto desempenho com Swoole

Atenda milhares de conexões com o Swoole baseado em corrotinas.

Servidores de alto desempenho com Swoole é uma aula grátis de PHP Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de PHP Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de PHP Academy inclui 4 aulas no total.

O que é o Swoole

O Swoole (e seu fork, o OpenSwoole) é uma extensão em C que transforma o PHP em um ambiente de execução de alto desempenho, baseado em corrotinas e orientado a eventos. Em vez de o PHP-FPM criar um processo por solicitação, um servidor Swoole inicializa sua aplicação uma vez e a mantém residente na memória, atendendo às solicitações por meio de um conjunto de processos de trabalho de longa duração com corrotinas integradas. O resultado: ganhos de vazão de várias ordens de grandeza e concorrência nativa em uma única solicitação.

O servidor HTTP persistente

O exemplo clássico: um servidor HTTP completo em um script. Ele escuta, encaminha cada solicitação para um trabalhador e nunca reinicializa o framework. Observe que isso requer ext-swoole — não é executado no PHP CLI padrão.

<?php
$server = new Swoole\Http\Server('0.0.0.0', 9501);
$server->set(['worker_num' => 4]);

$server->on('request', function ($request, $response) {
    $response->header('Content-Type', 'application/json');
    $response->end(json_encode(['hello' => $request->server['request_uri']]));
});

echo "listening on :9501\n";
$server->start();

Corrotinas, não funções de retorno

O grande diferencial do Swoole são as corrotinas: escreva código sequencial no estilo bloqueante, que o ambiente de execução agenda de forma cooperativa. Coroutine\run() abre um contexto de corrotina; go() inicia uma nova corrotina. Cada corrotina tem sua própria pilha, como uma fibra, mas o Swoole as agenda automaticamente nos pontos de E/S.

<?php
use Swoole\Coroutine as Co;

Co\run(function () {
    go(function () { Co::sleep(1); echo "A done\n"; });
    go(function () { Co::sleep(1); echo "B done\n"; });
    // Both sleep concurrently -> total ~1s, not 2s
});

Funções bloqueantes interceptadas

A mágica que torna as corrotinas práticas: os ganchos do ambiente de execução. O Swoole reescreve de forma transparente chamadas bloqueantes — PDO, Redis, curl, sleep, file_get_contents — em versões não bloqueantes compatíveis com corrotinas. Seu $pdo->query() comum cede o controle à corrotina em vez de congelar o trabalhador.

<?php
use Swoole\Runtime;
use Swoole\Coroutine as Co;

Runtime::enableCoroutine(SWOOLE_HOOK_ALL); // hook PDO, curl, sleep, etc.

Co\run(function () {
    go(function () { sleep(1); echo "task 1\n"; }); // sleep() is now async!
    go(function () { sleep(1); echo "task 2\n"; });
}); // finishes in ~1s because sleep was hooked

E/S concorrente com WaitGroup

Para distribuir o trabalho e aguardar a conclusão, o Swoole oferece um WaitGroup (como o sync.WaitGroup do Go). Inicie corrotinas, chame add() para cada tarefa, done() ao concluir e wait() para bloquear até que todas terminem — em concorrência.

<?php
use Swoole\Coroutine as Co;
use Swoole\Coroutine\WaitGroup;

Co\run(function () {
    $wg = new WaitGroup();
    $results = [];
    foreach (['eu', 'us', 'asia'] as $region) {
        $wg->add();
        go(function () use ($wg, $region, &$results) {
            Co::sleep(0.5);              // simulated API call
            $results[$region] = "ok-$region";
            $wg->done();
        });
    }
    $wg->wait();                         // all three ran in parallel (~0.5s)
    var_dump($results);
});

Canais para comunicação

As corrotinas se coordenam por meio de canais — filas tipadas e limitadas que suspendem o produtor quando estão cheias e o consumidor quando estão vazias. Trata-se de comunicação no estilo CSP, que evita completamente travas sobre estado compartilhado.

<?php
use Swoole\Coroutine as Co;
use Swoole\Coroutine\Channel;

Co\run(function () {
    $chan = new Channel(2);
    go(function () use ($chan) {
        foreach (range(1, 3) as $n) $chan->push($n);
        $chan->push(null); // sentinel
    });
    go(function () use ($chan) {
        while (($v = $chan->pop()) !== null) echo "got $v\n";
    });
});

Agrupamento de conexões

Um servidor persistente não deve abrir uma conexão com o banco de dados por solicitação. O Swoole fornece agrupamentos de conexões seguros para corrotinas, para que os trabalhadores reutilizem um conjunto fixo de conexões entre milhares de corrotinas concorrentes, eliminando a constante abertura e fechamento de conexões.

<?php
use Swoole\Database\PDOConfig;
use Swoole\Database\PDOPool;
use Swoole\Coroutine as Co;

Co\run(function () {
    $pool = new PDOPool((new PDOConfig())
        ->withHost('127.0.0.1')->withDbname('app')
        ->withUsername('u')->withPassword('p'), 8);

    go(function () use ($pool) {
        $pdo = $pool->get();           // borrow
        $row = $pdo->query('SELECT NOW()')->fetch();
        $pool->put($pdo);              // return to pool
        var_dump($row);
    });
});

Vazamentos de estado: a armadilha da memória persistente

Como o processo permanece ativo entre as solicitações, o estado global e estático persiste. Um cache estático que cresce sem limite, um objeto único que mantém dados específicos da solicitação ou uma transação de banco de dados vazada corromperá solicitações posteriores e esgotará a memória. Regras: evite dados específicos da solicitação em estáticos e objetos únicos, redefina o contexto a cada solicitação e defina max_request para que os trabalhadores sejam reciclados periodicamente.

<?php
$server = new Swoole\Http\Server('0.0.0.0', 9501);
$server->set([
    'worker_num'  => 8,
    'max_request' => 10000, // recycle a worker after N requests to bound leaks
]);
// Never store $request data in a static property between requests!

Contexto local da corrotina

Como um único trabalhador intercala muitas corrotinas, você não pode usar estáticos comuns para dados específicos da solicitação. O Swoole fornece a cada corrotina um contexto (Coroutine::getContext()) — um objeto cujo tempo de vida é o da corrotina, perfeito para o usuário atual, o ID da solicitação ou o identificador da transação.

<?php
use Swoole\Coroutine as Co;

Co\run(function () {
    go(function () {
        $ctx = Co::getContext();
        $ctx['request_id'] = 'req-123';
        // ... deep call chain can read Co::getContext()['request_id']
        echo Co::getContext()['request_id'], PHP_EOL;
    });
});

Modelo de processos e trabalhadores de tarefas

O Swoole executa um processo principal (que gerencia as linhas de execução do ciclo de eventos), um gerenciador (que cria e monitora os trabalhadores), processos de trabalho (que executam seus manipuladores de solicitações e corrotinas) e processos de tarefas opcionais para trabalhos pesados, bloqueantes ou limitados pela CPU, descarregados por meio de $server->task(). Use processos de tarefas para processamento de imagens ou trabalhos longos limitados pela CPU, para que não interrompam as corrotinas das solicitações — assim você obtém concorrência e paralelismo.

Adiamento e temporizadores

O Swoole permite agendar trabalho para depois que a corrotina atual terminar com Coroutine::defer() — ideal para liberar recursos de agrupamentos de forma confiável, mesmo quando uma exceção é lançada. Os temporizadores de todo o servidor (Timer::tick) executam trabalhos periódicos, como a atualização do cache, dentro de um trabalhador, sem um agendador cron externo.

<?php
use Swoole\Coroutine as Co;

Co\run(function () {
    go(function () {
        $conn = 'borrowed-connection';
        Co::defer(function () use ($conn) {
            echo "released $conn\n"; // runs when coroutine exits, even on error
        });
        echo "using $conn\n";
    });
});

Verificação rápida

Por que você deve evitar armazenar dados da solicitação em propriedades estáticas em um servidor Swoole?

Recapitulação

O Swoole transforma o PHP em um servidor residente orientado por corrotinas:

  • A aplicação é inicializada uma vez; um conjunto de trabalhadores atende às solicitações com corrotinas integradas (Co\run/go()).
  • Os ganchos do ambiente de execução tornam chamadas comuns a PDO/curl/sleep não bloqueantes; WaitGroup e canais coordenam trabalhos concorrentes.
  • Os agrupamentos de conexões reutilizam conexões com o banco de dados entre corrotinas.
  • A memória persistente exige que você evite vazamentos de estado: use Coroutine::getContext() para dados específicos da solicitação, defina max_request e descarregue trabalhos pesados para processos de tarefas.

Perguntas Frequentes

A aula “Servidores de alto desempenho com Swoole” é grátis?

Sim — o texto completo de “Servidores de alto desempenho com Swoole” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de PHP Academy, atualize para CoddyKit PRO. O curso de PHP Academy inclui 4 aulas no total.

O que vou aprender em “Servidores de alto desempenho com Swoole”?

Atenda milhares de conexões com o Swoole baseado em corrotinas. Você pratica PHP Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar PHP Academy?

Nenhuma experiência prévia é necessária. PHP Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Servidores de alto desempenho com Swoole”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de PHP Academy?

Sim. Cada aula de PHP Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. O modelo de concorrência do PHP
  2. Fibers do PHP 8.1
  3. Loops de eventos com ReactPHP
  4. Servidores de alto desempenho com Swoole
← Voltar para PHP Academy