Servidor de aplicativos GraphQL
O Commerce GraphQL Application Server permite que o Adobe Commerce mantenha o estado entre as solicitações de API do Commerce GraphQL. O GraphQL Application Server, que é criado na extensão Swoole, opera como um processo com threads de trabalho que lidam com o processamento de solicitações. Ao preservar um estado de aplicativo inicializado entre as solicitações de API do GraphQL, o GraphQL Application Server aprimora o manuseio de solicitações e o desempenho geral do produto. As solicitações de API tornam-se significativamente mais eficientes.
O GraphQL Application Server está disponível somente para o Adobe Commerce. Não está disponível para o Magento Open Source. Para projetos do Cloud Pro, você deve enviar um tíquete de Suporte da Adobe Commerce para habilitar o Servidor de Aplicativos do GraphQL.
Arquitetura
O GraphQL Application Server mantém o estado entre as solicitações de API do Commerce GraphQL e elimina a necessidade de inicialização. Ao compartilhar o estado do aplicativo entre os processos, as solicitações do GraphQL tornam-se significativamente mais eficientes, reduzindo os tempos de resposta em até 30%.
O modelo de execução do PHP sem compartilhamento oferece um desafio da perspectiva de latência porque cada solicitação requer o bootstrapping da estrutura. Esse processo de inicialização inclui tarefas demoradas, como ler a configuração, configurar o processo de inicialização e criar objetos de classe de serviço.
A transição da lógica de manipulação de solicitações para um loop de eventos no nível do aplicativo parece solucionar o desafio de simplificar o processamento de solicitações em um nível corporativo. Essa abordagem elimina a necessidade de bootstrapping durante o ciclo de vida de execução da solicitação.
Vantagens
O GraphQL Application Server permite que o Adobe Commerce mantenha o estado entre solicitações consecutivas da API do Commerce GraphQL. O compartilhamento do estado do aplicativo entre solicitações melhora a eficiência da solicitação da API, minimizando a sobrecarga do processamento e otimizando o manuseio de solicitações. Como resultado, você pode reduzir o tempo de resposta de solicitações do GraphQL em até 30%.
Requisitos do sistema
A execução do GraphQL Application Server requer o seguinte:
- Commerce versão 2.4.7+
- PHP 8.2 ou superior
- RAM e CPU adequados com base na carga esperada
- Extensão PHP Swoole v5+ (consulte os requisitos específicos do projeto abaixo)
Projetos na nuvem
Os projetos de infraestrutura em nuvem do Adobe Commerce incluem a extensão Swoole por padrão. Você pode habilitar na propriedade runtime do arquivo .magento.app.yaml. Por exemplo:
runtime:
extensions:
- swoole
Projetos no local
Você deve instalar e configurar manualmente a extensão Swoole PHP para projetos locais.
Ativar e implantar na infraestrutura em nuvem
O módulo ApplicationServer (Magento/ApplicationServer/) habilita o Servidor de Aplicativos GraphQL.
Habilitar projetos Pro
Depois que o recurso Servidor de aplicativos for ativado em seu projeto Pro, conclua as seguintes etapas antes de implantar o Servidor de aplicativos GraphQL:
-
Implante o Adobe Commerce na infraestrutura de nuvem usando o modelo de nuvem da 2.4.7-ramificação appserver.
-
Verifique se todas as suas personalizações e extensões do Commerce são compatíveis com o GraphQL Application Server.
-
Clonar o projeto do Commerce Cloud.
-
Ajuste as configurações no arquivo 'application-server/nginx.conf.sample' se necessário.
-
Comente a seção 'web' ativa totalmente no arquivo
project_root/.magento.app.yaml. -
Remova o comentário da seguinte configuração da seção 'web' no arquivo
project_root/.magento.app.yamlque inclui o comandostartdo GraphQL Application Server.code language-yaml web: upstream: socket_family: tcp protocol: http commands: start: ./application-server/start.sh > var/log/application-server-status.log 2>&1 -
Verifique se
/application-server/start.shé executável executando o seguinte comando:code language-bash chmod +x application-server/start.sh -
Adicione arquivos atualizados ao índice Git com este comando:
code language-bash git add -f .magento.app.yaml application-server/* -
Confirme suas alterações com este comando:
code language-bash git commit -m "AppServer Enabled"
Implantar projetos Pro
Após concluir as etapas de ativação, envie as alterações para o repositório Git para implantar o GraphQL Application Server:
git push
Habilitar projetos iniciais
Conclua as seguintes etapas antes de implantar o GraphQL Application Server em projetos iniciais:
-
Implante o Adobe Commerce na infraestrutura de nuvem usando o modelo de nuvem da 2.4.7-ramificação appserver.
-
Verifique se todas as personalizações e extensões do Commerce são compatíveis com o GraphQL Application Server.
-
Confirme se a variável de ambiente
CRYPT_KEYestá definida para sua instância. Você pode verificar o status dessa variável no Cloud Console. -
Clonar o projeto do Commerce Cloud.
-
Renomeie
application-server/.magento/.magento.app.yaml.samplecomoapplication-server/.magento/.magento.app.yamle ajuste as configurações em .magento.app.yaml, se necessário. -
Descomente a configuração da rota a seguir no arquivo
project_root/.magento/routes.yamlpara redirecionar o tráfego/graphqlpara o GraphQL Application Server.code language-yaml "http://{all}/graphql": type: upstream upstream: "application-server:http" -
Descomente a seção
filesno arquivo.magento/services.yaml.code language-yaml files: type: network-storage:2.0 disk: 5120 -
Descomente a parte
TEMPORARY SHARED MOUNTSda configuração de montagens no arquivo.magento.app.yaml.code language-yaml "var_shared": source: "service" service: "files" source_path: "var" "app/etc_shared": source: "service" service: "files" source_path: "etc" "pub/media_shared": source: "service" service: "files" source_path: "media" "pub/static_shared": source: "service" service: "files" source_path: "static" -
Adicionar arquivos atualizados ao índice Git:
code language-bash git add -f .magento.app.yaml .magento/routes.yaml .magento/services.yaml application-server/.magento/* -
Confirme suas alterações e envie-as por push para acionar uma implantação:
code language-bash git commit -m "Enabling AppServer: initial changes" git push -
Usar SSH para fazer logon no ambiente de nuvem remoto (não o aplicativo
application-server):code language-bash magento-cloud ssh -p <project-ID> -e <environment-ID> -
Sincronize os dados das montagens locais com as montagens compartilhadas:
code language-bash rsync -avz var/* var_shared/ rsync -avz app/etc/* app/etc_shared/ rsync -avz pub/media/* pub/media_shared/ rsync -avz pub/static/* pub/static_shared/ -
Comente as partes
DEFAULT MOUNTSeTEMPORARY SHARED MOUNTSda configuração de montagens no arquivo.magento.app.yaml.code language-yaml #"var": "shared:files/var" #"app/etc": "shared:files/etc" #"pub/media": "shared:files/media" #"pub/static": "shared:files/static" #"var_shared": # source: "service" # service: "files" # source_path: "var" #"app/etc_shared": # source: "service" # service: "files" # source_path: "etc" #"pub/media_shared": # source: "service" # service: "files" # source_path: "media" #"pub/static_shared": # source: "service" # service: "files" # source_path: "static" -
Descomente as partes
OLD LOCAL MOUNTSeSHARED MOUNTSda configuração de montagens no arquivo.magento.app.yaml.code language-yaml "var_old": "shared:files/var" "app/etc_old": "shared:files/etc" "pub/media_old": "shared:files/media" "pub/static_old": "shared:files/static" "var": source: "service" service: "files" source_path: "var" "app/etc": source: "service" service: "files" source_path: "etc" "pub/media": source: "service" service: "files" source_path: "media" "pub/static": source: "service" service: "files" source_path: "static" -
Adicione o arquivo atualizado ao índice Git, confirme as alterações e envie por push para acionar uma implantação:
code language-bash git add -f .magento.app.yaml git commit -m "Enabling AppServer: switch mounts" git push -
Verifique se os arquivos de
*_olddiretórios estão presentes nos diretórios reais. -
Limpar montagens locais antigas:
code language-bash rm -rf var_old/* rm -rf app/etc_old/* rm -rf pub/media_old/* rm -rf pub/static_old/* -
Comente a parte
OLD LOCAL MOUNTSda configuração de montagens no arquivo.magento.app.yaml.code language-yaml #"var_old": "shared:files/var" #"app/etc_old": "shared:files/etc" #"pub/media_old": "shared:files/media" #"pub/static_old": "shared:files/static" -
Adicione o arquivo atualizado ao índice Git, confirme as alterações e envie por push para acionar uma implantação:
code language-bash git add -f .magento.app.yaml git commit -m "Enabling AppServer: finish" git push
.magento.app.yaml foram migradas adequadamente para o arquivo application-server/.magento/.magento.app.yaml. Depois que o arquivo application-server/.magento/.magento.app.yaml for adicionado ao seu projeto, você deverá mantê-lo além do arquivo .magento.app.yaml raiz. Por exemplo, se você precisar configurar o serviço RabbitMQ ou gerenciar propriedades da Web, adicione a mesma configuração ao application-server/.magento/.magento.app.yaml também.Verificar habilitação em projetos na nuvem
-
Execute uma consulta ou mutação do GraphQL na sua instância para confirmar se o ponto de extremidade
graphqlestá acessível. Por exemplo:code language-none mutation { createEmptyCart }A resposta esperada deve ser semelhante a este exemplo:
code language-json { "data": { "createEmptyCart": "HLATPzcLw5ylDf76IC92nxdO2hXSXOrv" } } -
Use SSH para acessar a instância da nuvem. O
project_root/var/log/application-server.logdeve conter um novo registro de log para cada solicitação GraphQL. -
Você também pode verificar se o GraphQL Application Server está em execução executando o seguinte comando:
code language-bash ps aux|grep phpVocê deve ver um processo
bin/magento server:runcom vários threads.
Se essas etapas de verificação forem bem-sucedidas, o GraphQL Application Server estará em execução e atendendo a /graphql solicitações.
Habilitar projetos locais
O módulo ApplicationServer (Magento/ApplicationServer/) habilita o GraphQL Application Server para APIs GraphQL.
A execução local do GraphQL Application Server requer a instalação da extensão Swoole e uma pequena alteração no arquivo de configuração Nginx da implantação.
Pré-requisitos
Conclua as seguintes etapas antes de habilitar o módulo ApplicationServer:
- Configurar Nginx
- Instalar e configurar a extensão Swoole v5+
Configurar Nginx
A implantação específica do Commerce determina como configurar o Nginx. Em geral, o arquivo de configuração Nginx é nomeado por padrão nginx.conf e é colocado em um destes diretórios: /usr/local/nginx/conf, /etc/nginx, ou /usr/local/etc/nginx. Consulte o Guia do Iniciante para obter mais informações sobre a configuração do Nginx.
Exemplo de configuração do Nginx:
location /graphql {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:9501/graphql;
}
Instalar e configurar Swoole
Para executar o GraphQL Application Server localmente, instale a extensão Swoole (v5.0 ou superior). Há várias maneiras de instalar essa extensão.
O procedimento seguinte descreve como instalar a extensão Swoole para PHP 8.2 em sistemas baseados em OSX. É uma das várias maneiras de instalar a extensão Swoole.
pecl install swoole
Durante a instalação, o Adobe Commerce exibe prompts para habilitar o suporte para openssl, mysqlnd, sockets, http2 e postgres. Digite yes para todas as opções, exceto postgres.
Verificar a instalação do Swoole
Confirme se a extensão foi ativada com sucesso:
php -m | grep swoole
Erros comuns na instalação do Swoole
Todos os erros que ocorrem durante a instalação do Swoole normalmente ocorrem durante a fase de instalação do pecl. Os erros típicos incluem arquivos openssl.h e pcre2.h ausentes. Para resolver esses erros, verifique se esses dois pacotes estão instalados no sistema local.
- Verifique o local de
opensslexecutando:
openssl version -d
Este comando mostra o caminho onde o openssl está instalado.
- Verifique o local de
pcre2executando:
pcre2-config --prefix
Use o Homebrew para instalar os pacotes ausentes se a saída do comando indicar que os arquivos estão ausentes:
brew install openssl
brew install pcre2
Resolver problemas com o openssl
Para resolver problemas relacionados a openssl, execute:
export LDFLAGS="-L/opt/homebrew/etc/openssl@3/lib" export CPPFLAGS="-I/opt/homebrew/etc/openssl@3/include"
Confirme se você está usando o caminho do ambiente dev local.
Confirmar resolução de problemas relacionados ao openssl
Você pode executar o comando a seguir novamente para verificar se os problemas relacionados ao openssl foram resolvidos:
pecl install swoole
Resolver problemas com pcre2.h
Para resolver problemas relacionados a pcre2.h, vincule o caminho pcre2.h ao diretório de extensão PHP instalado. Sua versão específica instalada do PHP e do pcr2.h determina a versão específica do comando que você deve usar.
Executar o GraphQL Application Server
Iniciar o GraphQL Application Server:
bin/magento server:run
Esse comando inicia uma porta HTTP em 9501. Depois que o GraphQL Application Server é iniciado, a porta 9501 se torna um servidor proxy HTTP para todas as consultas do GraphQL.
Para confirmar se o GraphQL Application Server está em execução na implantação:
ps aux | grep php
Outras maneiras de confirmar que o GraphQL Application Server está em execução incluem:
- Verifique o arquivo
/var/log/application-server.logpara entradas relacionadas a solicitações GraphQL processadas. - Tente se conectar à porta HTTP em que o GraphQL Application Server é executado. Por exemplo:
curl -g 'http://localhost:9501/graph.
Confirme se as solicitações do GraphQL estão sendo processadas
O GraphQL Application Server adiciona o cabeçalho de resposta X-Backend com o valor graphql_server a cada solicitação processada. Para verificar se o GraphQL Application Server tratou de uma solicitação, verifique esse cabeçalho de resposta.
Confirmar compatibilidade de extensão e personalização
Os desenvolvedores e comerciantes de extensões devem primeiro verificar se sua extensão e código de personalização seguem as diretrizes descritas em Diretrizes técnicas.
Considere estas diretrizes durante a avaliação do código:
- As classes de serviço (ou seja, classes que fornecem comportamento, mas não dados, como
EventManager) não devem ter estado mutável. - Evite o acoplamento temporal.
Desativar o servidor de aplicativos GraphQL
Os procedimentos para desabilitar o GraphQL Application Server variam dependendo se o servidor está sendo executado em uma implantação local ou na nuvem.
Desabilitar o GraphQL Application Server (nuvem)
-
Remova quaisquer novos arquivos e quaisquer outras alterações de código que tenham sido incluídas na confirmação
AppServer Enableddurante seus preparativos para a implantação. -
Confirme as alterações usando este comando:
code language-bash git commit -m "AppServer Disabled" -
Implante essas alterações usando este comando:
code language-bash git push
Desabilitar o GraphQL Application Server (local)
- Comente a seção
/graphqldo arquivonginx.confque você adicionou ao habilitar o GraphQL Application Server. - Reinicie o nginx.
Esse método de desativação do GraphQL Application Server pode ser útil para testar ou comparar o desempenho rapidamente.
Confirme se o GraphQL Application Server está desativado
Para confirmar se php-fpm está processando solicitações do GraphQL em vez do Servidor de Aplicativos GraphQL, digite este comando: ps aux | grep php.
Depois que o GraphQL Application Server for desativado:
bin/magento server:runestá inativo.var/log/application-server.lognão contém entradas após solicitações GraphQL.
Integração e testes funcionais do GraphQL Application Server
Os desenvolvedores de extensão podem executar dois testes de integração para verificar a compatibilidade da extensão com o GraphQL Application Server: GraphQlStateTest e ResetAfterRequestTest.
GraphQlStateTest
O GraphQlStateTest detecta um estado em objetos compartilhados que não deve ser reutilizado para várias solicitações.
Este teste foi projetado para detectar alterações de estado em objetos de serviço que o ObjectManager produz. O teste executa consultas GraphQL idênticas duas vezes e compara o estado do objeto de serviço antes e depois da segunda consulta.
Falhas de GraphQlStateTest e possível correção
-
Não é possível adicionar, ignorar ou filtrar uma lista. Se você receber esse erro, tente refatorar sua classe para usar fábricas para classes de serviço com estado mutável.
-
A classe exibe um estado mutável. Se a própria classe exibir um estado mutável, tente reescrever seu código para contornar esse estado. Se o estado mutável for necessário por motivos de desempenho, implemente
ResetAfterRequestInterfacee use_resetState()para redefinir o objeto para seu estado construído inicial. -
A propriedade digitada $x não deve ser acessada antes da mensagem de inicialização. Falhas com esse tipo de mensagem sugerem que a propriedade especificada não foi inicializada pelo construtor. Esta é uma forma de acoplamento temporal que ocorre porque o objeto não pode ser usado após ser construído inicialmente. Essa combinação ocorre mesmo se a propriedade for privada porque o Coletor que recupera os dados das propriedades está usando o recurso de reflexão do PHP. Nesse caso, tente refatorar a classe para evitar acoplamento temporal e evitar estado mutável. Se essa refatoração não resolver a falha, você poderá alterar o tipo de propriedade para um tipo anulável para que ele possa ser inicializado como nulo. Se a propriedade for uma matriz, tente inicializar a propriedade como uma matriz vazia.
Executar GraphQlStateTest executando vendor/bin/phpunit -c $(pwd)/dev/tests/integration/phpunit.xml dev/tests/integration/testsuite/Magento/GraphQl/App/GraphQlStateTest.php.
ResetAfterRequestTest
O ResetAfterRequestTest procura todas as classes que implementam ResetAfterRequestInterface e verifica se o método _resetState() retorna o estado de um objeto ao mesmo estado que ele manteve após ser construído por ObjectManager. Este teste cria um objeto de serviço com ObjectManager, clona esse objeto, chama _resetState() e compara ambos os objetos. O teste não chama nenhum método entre a instanciação de objeto e _resetState(), portanto, não confirma a redefinição de nenhum estado mutável. Ele não encontra problemas em que um erro ou erro de digitação em _resetState() possa definir o estado para algo diferente do que era originalmente.
Falhas de ResetAfterRequestTest e possível correção
-
A classe tem valores de propriedade inconsistentes. Se esse teste falhar, verifique se uma classe foi alterada com o resultado de que o objeto após a construção tem valores de propriedade diferentes dos que tem após a chamada do método
_resetState(). Se a classe em que você está trabalhando não contiver o método_resetState()em si, verifique a hierarquia de classe de uma superclasse que o implemente. -
A propriedade digitada $x não deve ser acessada antes da mensagem de inicialização. Esse problema também ocorre com
GraphQlStateTest.Executar
ResetAfterRequestTestexecutando:vendor/bin/phpunit -c $(pwd)/dev/tests/integration/phpunit.xml dev/tests/integration/testsuite/Magento/Framework/ObjectManager/ResetAfterRequestTest.php.
Teste funcional
Ao implantar o GraphQL Application Server, os desenvolvedores de extensão devem executar testes funcionais da WebAPI e quaisquer testes funcionais automatizados ou manuais personalizados para o GraphQL. Esses testes funcionais ajudam os desenvolvedores a identificar possíveis erros ou problemas de compatibilidade.
Modo de Monitor de Estado
Durante a execução de testes funcionais (ou testes manuais), o GraphQL Application Server pode ser executado com o --state-monitor mode habilitado para ajudar a encontrar classes em que o estado está sendo reutilizado involuntariamente. Inicie o Servidor de Aplicativos normalmente, exceto para adicionar o parâmetro --state-monitor.
bin/magento server:run --state-monitor
Após cada solicitação ser processada, um novo arquivo é adicionado ao diretório tmp, por exemplo: var/tmp/StateMonitor-thread-output-50-6nmxiK. Após concluir o teste, esses arquivos poderão ser mesclados com o comando bin/magento server:state-monitor:aggregate-output, que cria dois arquivos mesclados, um em XML e um em JSON.
Exemplos:
/var/workspace/var/tmp/StateMonitor-json-2024-04-10T18:50:39Z-hW0ucN.json
/var/workspace/var/tmp/StateMonitor-junit-2024-04-10T18:50:39Z-oreUco.xml
Esses arquivos podem ser inspecionados com qualquer ferramenta usada para exibir XML ou JSON que mostre as propriedades modificadas de objetos de serviço, como o GraphQlStateTest faz. O modo --state-monitor usa a mesma lista de salto e lista de filtro que GraphQlStateTest.
--state-monitor na produção. Ele é projetado apenas para desenvolvimento e teste. Ele cria muitos arquivos de saída e é executado mais lentamente do que o normal.--state-monitor não é compatível com as versões do PHP 8.3.0 - 8.3.4 devido a um erro no coletor de lixo do PHP. Se você estiver usando o PHP 8.3, é necessário atualizar para 8.3.5 ou mais recente para usar este recurso.Configurando cabeçalhos alternativos para detecção de IP de cliente
Por padrão, o GraphQL Application Server oferece suporte a uma configuração padrão para o cabeçalho x-forwarded-for definido no arquivo app/etc/di.xml, permitindo a recuperação precisa do endereço IP do cliente em ambientes típicos de proxy e CDN.
Se você precisar de suporte para cabeçalhos adicionais ou personalizados (como x-client-ip, fastly-client-ip ou x-real-ip), poderá estender ou substituir o argumento alternativeHeaders no arquivo app/etc/di.xml. Isso só será necessário se o ambiente usar cabeçalhos diferentes de x-forwarded-for para passar o endereço IP do cliente.
Por exemplo, para adicionar suporte a outros cabeçalhos, atualize seu app/etc/di.xml da seguinte maneira:
<type name="Magento\Framework\HTTP\PhpEnvironment\RemoteAddress">
<arguments>
<argument name="alternativeHeaders" xsi:type="array">
<item name="x-client-ip" xsi:type="string">HTTP_X_CLIENT_IP</item>
<item name="fastly-client-ip" xsi:type="string">HTTP_FASTLY_CLIENT_IP</item>
<item name="x-real-ip" xsi:type="string">HTTP_X_REAL_IP</item>
<item name="x-forwarded-for" xsi:type="string">HTTP_X_FORWARDED_FOR</item>
</argument>
</arguments>
</type>
Você pode adicionar, remover ou reordenar os cabeçalhos conforme necessário para garantir que o IP do cliente seja recuperado da origem correta para sua configuração.