Guia de atualização 1.5
Faça backup antes de atualizar e execute o seguinte comando para atualizar
composer require workerman/webman-framework ^1.5 -W && composer require webman/console ^1.2.12 && php webman install
Características e Alterações
Suporta workerman v5 fibras
Dica
workerman v5 requere PHP>=8.1
Comando de atualização do workermancomposer require workerman/workerman ^5.0.0 -W
As fibras requerem a instalação decomposer require revolt/event-loop ^1.0.0
Exemplos
Resposta atrasada
<?php
namespace app\controller;
use support\Request;
use Workerman\Timer;
class TestController
{
public function index(Request $request)
{
// Aguarda 1,5 segundos
Timer::sleep(1.5);
return $request->getRemoteIp();
}
}
Timer::sleep()
é semelhante à função sleep()
nativa do PHP, a diferença é que Timer::sleep()
não bloqueia o processo.
Enviar uma requisição HTTP
Atenção
É necessário instalar composer require workerman/http-client ^2.0.0
<?php
namespace app\controller;
use support\Request;
use Workerman\Http\Client;
class TestController
{
public function index(Request $request)
{
static $client;
$client = $client ?: new Client();
$response = $client->get('http://example.com'); // Inicia uma solicitação assíncrona de forma síncrona
return $response->getBody()->getContents();
}
}
Da mesma forma, a solicitação $client->get()
não é bloqueante, isso pode ser usado para manipular solicitações http de forma não bloqueante no webman, melhorando o desempenho.
Para mais informações, consulte workerman/http-client
Adicionando a classe support\Context
A classe support\Context é usada para armazenar dados relacionados à solicitação. Quando a solicitação é concluída, os dados de contexto correspondentes são excluídos automaticamente. Ou seja, o ciclo de vida dos dados de contexto segue o ciclo de vida da solicitação.
Poluição de variáveis globais
No ambiente de fibra, é proibido armazenar informações de estado relacionadas à solicitação em variáveis globais ou estáticas, pois isso pode causar poluição de variáveis globais, por exemplo:
<?php
namespace app\controller;
use support\Request;
use Workerman\Timer;
class TestController
{
protected static $name = '';
public function index(Request $request)
{
static::$name = $request->get('name');
Timer::sleep(5);
return static::$name;
}
}
Quando o número de processos é configurado como 1, ao enviar duas solicitações consecutivas:
http://127.0.0.1:8787/test?name=lilei
http://127.0.0.1:8787/test?name=hanmeimei
Esperamos que os resultados das duas solicitações retornem respectivamente lilei
e hanmeimei
, mas na verdade ambos retornam hanmeimei
.
Isso ocorre porque a segunda solicitação sobrescreve a variável estática $name
, e quando a primeira solicitação conclui a espera, a variável estática $name
já se tornou hanmeimei
.
O método correto é usar o contexto para armazenar dados de estado da solicitação
<?php
namespace app\controller;
use support\Request;
use support\Context;
use Workerman\Timer;
class TestController
{
public function index(Request $request)
{
Context::set('name', $request->get('name'));
Timer::sleep(5);
return Context::get('name');
}
}
Variáveis locais não causam poluição de dados
<?php
namespace app\controller;
use support\Request;
use support\Context;
use Workerman\Timer;
class TestController
{
public function index(Request $request)
{
$name = $request->get('name');
Timer::sleep(5);
return $name;
}
}
Porque $name
é uma variável local, as fibras não podem acessar as variáveis locais umas das outras, portanto o uso de variáveis locais é seguro em ambiente de fibra.
Sobre as Fibras
As fibras não são a solução para todos os problemas. A introdução de fibras significa que é necessário estar atento à poluição de variáveis globais/estáticas e configurar o contexto. Além disso, depurar bugs em um ambiente de fibra é mais complicado do que a programação de bloqueio.
Na verdade, a programação de bloqueio do webman já é rápida o suficiente. De acordo com os dados dos testes techempower.com dos últimos três anos, o webman com operações de banco de dados supera em quase 1 vez o desempenho dos frameworks web do Go, como gin e echo, e é quase 40 vezes mais rápido do que frameworks tradicionais como Laravel.
Quando o banco de dados e o Redis estão na intranet, a programação de bloqueio de vários processos pode ter um desempenho melhor do que as fibras. Isso ocorre porque, quando o banco de dados e o Redis são rápidos o suficiente, o custo de criação, programação e destruição de fibras pode ser maior do que o custo de troca de processos, portanto, a introdução de fibras pode não melhorar significativamente o desempenho.
Quando usar as Fibras
Quando ocorrem acessos lentos durante a operação, como a necessidade de acessar uma API de terceiros, é possível usar workerman/http-client para fazer chamadas HTTP assíncronas usando fibras, aumentando a capacidade de concorrência do aplicativo.