Explorando o Hyperf: Um guia básico sobre SQLCommenter

Reinan Gabriel
26 min readJul 14, 2024

--

Um guia básico sobre SQLCommenter — Fonte do autor

Com a chegada do modelo DevOps, os desenvolvedores passaram a realizar implantações semanalmente, ou até mesmo várias vezes ao dia. Além disso, novos projetos estão sendo construídos utilizando arquiteturas modernas, como MVC e microsserviços, o que resulta em cargas de trabalho continuamente impulsionadas.

Com esse novo ciclo de desenvolvimento, a responsabilidade pelo desempenho dos aplicativos foi transferida para os desenvolvedores de software. Agora, além de desenvolverem novas funcionalidades, eles também são responsáveis pela análise de desempenho de seus aplicativos.

No entanto, as arquiteturas baseadas em microsserviços tornam os projetos distribuídos em uma malha interconectada por serviços. A imagem abaixo exemplifica esse cenário:

Fonte: Sqlcommenter merges with OpenTelemetry | Google Cloud Blog

Nesse cenário, os desenvolvedores podem encontrar várias dificuldades para identificar a origem dos problemas de desempenho do sistema. Quando um banco de dados está envolvido, torna-se ainda mais desafiador correlacionar o código do aplicativo com o desempenho do banco de dados.

Em muitos casos, quando surgem problemas de desempenho, o banco de dados é frequentemente a causa raiz. Separei uma citação de Alois Reitbauer, vice-presidente e estrategista-chefe de tecnologia da Dynatrace, que aborda esse tópico:

“Observando conjuntos de dados em milhares de empresas, identificamos padrões de acesso a banco de dados e desempenho como uma das principais razões para aplicativos de baixo desempenho.”

No entanto, os desenvolvedores podem não ter as habilidades ou ferramentas necessárias para resolver os problemas de desempenho do banco de dados por conta própria. Se buscarem ajuda do time de infraestrutura ou DevOps, é provável que descubram que essas equipes já estão sobrecarregadas com outras atividades, fazendo com que os desenvolvedores tenham que esperar sua vez para receber ajuda na análise dos problemas de performance no banco de dados.

Como resultado, problemas urgentes de desempenho em aplicativos em produção podem ficar sem solução, deixando os clientes com uma experiência ruim.

Diante desse cenário, resolvi escrever esta publicação para divulgar minha biblioteca sqlcommenter-hyperf, que tem como objetivo aumentar a observabilidade e a identificação de problemas de desempenho no banco de dados no contexto do Hyperf.

Panorama das ferramentas de Observabilidade para bancos de dados SQL

Atualmente, o mercado oferece uma variedade de soluções que ajudam as equipes de desenvolvimento e operações a manterem seus sistemas funcionando de maneira eficiente e a resolverem rapidamente quaisquer problemas de desempenho que possam surgir.

Neste tópico, vamos explorar algumas das principais ferramentas de observabilidade de bancos de dados SQL disponíveis, destacando suas funcionalidades e como elas podem ajudar a garantir a saúde e o desempenho dos seus sistemas de banco de dados.

DB Marlin

Essa é uma poderosa ferramenta de observabilidade de banco de dados projetada para simplificar a identificação e resolução de problemas de desempenho. Com uma interface intuitiva e recursos avançados, o DB Marlin permite que equipes de desenvolvimento e operações monitorem e analisem o desempenho de seus bancos de dados SQL de maneira eficiente.

Painel do DB Marlin — Fonte do autor

Esta é uma ferramenta para quem busca melhorar a observabilidade e o desempenho de seus bancos de dados SQL, proporcionando uma solução robusta e fácil de usar para monitoramento e análise de desempenho. Se você quiser visualizar essa ferramenta através de uma demonstração online, pode acessar o link abaixo:

PlanetScale Insights

Essa é uma ferramenta poderosa que oferece uma visão detalhada de todas as consultas ativas sendo executadas no seu banco de dados. Com esta ferramenta no painel, você pode identificar facilmente as consultas que estão sendo executadas com muita frequência, levando muito tempo, retornando grandes volumes de dados, gerando erros e muito mais. Você pode navegar pelo gráfico de desempenho para detectar quando uma consulta foi afetada e, se aplicável, o merge request que a impactou.

Além disso, o PlanetScale Insights permite que você veja uma lista de todas as consultas realizadas no seu banco de dados nas últimas 24 horas. Para uma análise mais aprofundada, é possível classificar essas consultas por várias métricas, como quantidade de linhas lidas, tempo por consulta e outras.

Exemplo do painel — Fonte: Site do Planetscale

Com esta ferramenta integrada, diagnosticar problemas nas suas consultas torna-se uma tarefa simples, permitindo que você otimize consultas individuais de maneira eficiente. O PlanetScale Insights também alerta sobre quaisquer problemas ativos na guia Anomalias, sinalizando consultas que estão sendo executadas significativamente mais lentamente do que o esperado.

Releem

Essa é uma ferramenta que oferece uma solução automatizada que elimina o fardo dos desenvolvedores, permitindo um ajuste de desempenho do MySQL eficiente e sem esforço. Com a Releem, você pode otimizar automaticamente as configurações do MySQL para maximizar o desempenho do banco de dados, sem a necessidade de intervenção manual constante.

A plataforma analisa as métricas de desempenho do seu banco de dados e aplica as melhores práticas de otimização, ajustando parâmetros críticos para garantir uma operação suave e eficiente. Isso não só melhora o tempo de resposta das consultas, mas também ajuda a reduzir a carga do servidor e a evitar problemas de desempenho no futuro.

Painel do Releem — Fonte: Documentação do Releem

Além disso, a Releem fornece relatórios detalhados e insights sobre o estado do seu banco de dados, permitindo que você acompanhe as melhorias e entenda melhor como as mudanças afetam o desempenho. Com sua interface intuitiva e fácil de usar, a Releem torna o ajuste de desempenho do MySQL acessível a todos, desde desenvolvedores iniciantes até DBAs experientes.

Cloud SQL Insights

Essa é uma ferramenta eficaz que permite aos desenvolvedores identificar e resolver rapidamente problemas de desempenho de banco de dados no Cloud SQL. Desenvolvida com base em padrões abertos e arquiteturas modernas, como microsserviços, essa ferramenta facilita a compreensão do desempenho do banco de dados.

O Insights se integra perfeitamente às suas ferramentas de APM e observabilidade já existentes, fornecendo métricas e rastreamentos de banco de dados através das APIs OpenTelemetry, Cloud Monitoring e Cloud Trace. Isso possibilita um rastreamento completo em suas ferramentas atuais, oferecendo uma visão abrangente de toda a pilha, desde o aplicativo até o banco de dados.

Painel do Cloud SQL Insights — Fonte: Documentação da GCP

Ao contrário das ferramentas de monitoramento tradicionais, que muitas vezes fornecem uma visão centrada em consultas, o Insights elimina a desconexão entre o desempenho do banco de dados e o código do aplicativo, especialmente em arquiteturas modernas como MVC e microsserviços.

Com o Cloud SQL Insights, os desenvolvedores podem monitorar o desempenho do banco de dados a partir da perspectiva do aplicativo. Isso permite uma rápida avaliação da carga do banco de dados gerada por microsserviços específicos ou fluxos de usuário, tornando a solução de problemas de desempenho mais eficiente e direcionada.

Integração com o MVC no Cloud SQL Insights — Fonte: Documentação da GCP

Um ponto interessante que vale ser mencionado é que o Cloud SQL Insights utiliza uma biblioteca de código aberto chamada Sqlcommenter. Essa biblioteca permite que informações do aplicativo relacionadas à sua estrutura MVC sejam enviadas ao banco de dados junto com as consultas, na forma de comentários SQL. Dessa maneira, a ferramenta consegue mapear a consulta executada com o aplicativo que a gerou.

Introdução ao sqlcommenter

Agora que exploramos várias ferramentas de observabilidade disponíveis no mercado para SQL, vamos focar no Sqlcommenter. Essa biblioteca é fundamental para que nosso projeto em Hyperf possa ser mapeado, permitindo que as ferramentas associem as consultas SQL ao respectivo código no Hyperf.

Visão geral do Sqlcommenter

Sqlcommenter é uma biblioteca de código aberto que facilita a adição de comentários em suas consultas SQL. Esses comentários contêm metadados úteis que descrevem a origem da consulta, como o framework utilizado, o controlador e a ação que geraram a consulta, a rota utilizada e outras informações pertinentes. Isso melhora significativamente a capacidade de rastreamento e depuração de consultas SQL, especialmente em arquiteturas modernas como microsserviços e MVC.

Atualmente, diversas ferramentas suportam o Sqlcommenter, incluindo algumas que mencionamos anteriormente. No entanto, nesta publicação, vamos nos concentrar na configuração e utilização do Cloud SQL Insights. Isso não impede que você aplique os mesmos conceitos em outras ferramentas de observabilidade que também oferecem suporte ao Sqlcommenter.

Exemplos de SQL com Sqlcommenter

Para ilustrar como o Sqlcommenter funciona na prática, vejamos alguns exemplos de consultas SQL:

select *
from users

Usando a biblioteca do Sqlcommenter, a consulta ficará assim:

select *
from users /*framework='Hyperf',
application='hyperf-skeleton',
controller='UserController',
action='index',
route='%%2Fapi%%2Ftest',
db_driver='mysql',
traceparent='00-1cd60708968a61e942b5dacc2d4a5473-7534abe7ed36ce35-01'*/

Ao examinar a instrução SQL acima e seu comentário em /*...*/, podemos visualizar comentários ricos em metadados, permitindo uma melhor rastreabilidade e facilitando a análise de desempenho e depuração. Com essas informações, é possível correlacionar facilmente uma consulta específica com a parte do código que a gerou no Hyperf, proporcionando uma visão completa do fluxo de dados e ajudando a identificar problemas de desempenho.

Veja abaixo uma explicação a respeito de cada um dos campos:

  • framework=’Hyperf’: A palavra “Hyperf” representa o framework que gerou a consulta.
  • application=’hyperf-skeleton’: O nome do projeto onde o código foi executado.
  • controller=’UserController’: Nome do controlador em app/Controller.
  • action=’index’: Nome do método chamado pelo controlador.
  • route=’%%2Fapi%%2Ftest’: A rota usada durante a chamada da consulta.
  • db_driver=’mysql’: O nome do motor de banco de dados Hyperf.
  • traceparent=’00–1cd60708968a61e942b5dacc2d4a5473–7534abe7ed36ce35–01': O campo W3C TraceContext Traceparent do trace OpenTelemetry.

O futuro do Sqlcommenter

Em setembro de 2021, o Google doou o Sqlcommenter para a comunidade OpenTelemetry. Atualmente, o OpenTelemetry é o segundo projeto de código aberto mais ativo da Cloud Native Computing Foundation (CNCF), ficando atrás apenas do Kubernetes.

As bibliotecas do SQL Commenter já dependiam da implementação do OpenTelemetry para o contexto de rastreamento, então essa doação foi recebida de forma muito positiva pela comunidade. Ao integrar a especificação do Sqlcommenter às especificações do OpenTelemetry, a colaboração entre fornecedores interessados foi fortalecida, promovendo uma adoção mais ampla dessas técnicas de rastreamento distribuído.

Bogdan Drutu, cofundador do OpenCensus e engenheiro de software principal sênior da Splunk, comentou sobre a importância dessa contribuição:

“Com a contribuição do Sqlcommenter do Google Cloud para o OpenTelemetry, um padrão aberto e uma biblioteca neutra em relação ao fornecedor permitirão que um rico ecossistema de ferramentas de monitoramento de desempenho de aplicativos se integre facilmente a bancos de dados, desbloqueando uma rica variedade de ferramentas para observabilidade de banco de dados para os desenvolvedores.”

Você pode acompanhar a discussão sobre essa doação através de uma issue no GitHub no link abaixo:

Sqlcommenter com o Hyperf

Dentro da comunidade do Hyperf, não havia nenhuma solução ou biblioteca que proporcionasse a integração do Sqlcommenter com o Hyperf. Diante dessa necessidade, decidi criar uma implementação desses conceitos para o ecossistema do Hyperf, resultando na biblioteca sqlcommenter-hyperf.

O Sqlcommenter Hyperf é uma biblioteca projetada para adicionar automaticamente comentários às consultas SQL executadas pelo framework Hyperf. Esses comentários utilizam o formato sqlcommenter.

A partir deste ponto do artigo, irei abordar minha biblioteca e os principais benefícios que você pode obter ao implementá-la em seu código. Além disso, comentarei sobre alguns testes de performance que foram realizados para submeter a biblioteca a situações de estresse e avaliar seu comportamento em diferentes cenários.

Como fazer a instalação da biblioteca?

Você pode instalar a biblioteca via Composer:

composer require reinanhs/sqlcommenter-hyperf

Ao executar o comando acima, a biblioteca será baixada e começará a funcionar automaticamente no seu código com as configurações padrão. Um ponto importante a ser mencionado são as versões do Hyperf que são suportadas. Veja a lista abaixo:

  • Para o Hyperf 3.1, é recomendado usar a versão ^1.0.
  • Para o Hyperf 3.0, é recomendado usar a versão ^0.2.

Como customizar as configurações padrões?

Para personalizar as configurações padrão, você pode adicionar variáveis de ambiente relacionadas a cada configuração ou sobrescrever o arquivo de configuração usando o comando abaixo:

php bin/hyperf.php vendor:publish reinanhs/sqlcommenter-hyperf

Após a execução do comando acima, você encontrará a configuração no arquivo config/autoload/sqlcommenter.php:

'enable' => env('SQLCOMMENTER_ENABLE', true),
'include' => [
'framework' => env('SQLCOMMENTER_ENABLE_FRAMEWORK', true),
'controller' => env('SQLCOMMENTER_ENABLE_CONTROLLER', true),
'action' => env('SQLCOMMENTER_ENABLE_ACTION', true),
'route' => env('SQLCOMMENTER_ENABLE_ROUTE', true),
'application' => env('SQLCOMMENTER_ENABLE_APPLICATION', true),
'db_driver' => env('SQLCOMMENTER_ENABLE_DB_DRIVER', true),
],

Para entender cada uma dessas configurações, é recomendado que você leia a documentação oficial da biblioteca, onde encontrará uma tabela explicando cada uma delas.

Como a biblioteca funciona?

Como mencionado anteriormente, a biblioteca adiciona comentários a todas as consultas SQL realizadas através do Hyperf. Essa configuração é feita por meio de um proxy com a classe Hyperf\Database\Connection, que é a principal responsável pela execução das consultas. Veja abaixo um exemplo do código responsável por fazer esse mapeamento e adicionar automaticamente os comentários às consultas SQL:

public array $classes = [
'Hyperf\Database\Connection::runQueryCallback',
];

public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
if (!$this->config->get('sqlcommenter.enable', true)) {
return $proceedingJoinPoint->process();
}

$query = $proceedingJoinPoint->arguments['keys']['query'];
$dbInstance = $proceedingJoinPoint->getInstance();

$proceedingJoinPoint->arguments['keys']['query'] = $this->appendSqlComments(
query: $query,
dbDriver: $dbInstance->getDriverName()
);

return $proceedingJoinPoint->process();
}

A biblioteca monitora o método runQueryCallback, que é acionado sempre que uma consulta SQL é executada pelo Hyperf. É através desse método que a manipulação do SQL para adicionar as informações é realizada.

Se você já utilizou o framework Hyperf, provavelmente está familiarizado com Aspects. De maneira resumida, essa técnica permite a criação de um proxy com uma determinada classe ou método. Ao utilizar essa abordagem, você perceberá que uma nova classe baseada na que você está mapeando será criada no diretório runtime/container/proxy. Essa estratégia permite a criação de um proxy sem muita perda de performance. Veja abaixo uma ilustração do Connection:

Exemplo do resultado da classe com o proxy — Fonte do autor

Exemplo de utilização da biblioteca

Neste tópico, vou abordar um exemplo de uso da biblioteca sqlcommenter-hyperf no ambiente da Google Cloud. Este cenário está disponível no GitHub, onde você pode encontrar uma documentação detalhada que ensina como replicar todo o processo na Google Cloud.

Assim que a biblioteca é instalada no projeto e o projeto é implantado no ambiente da Google Cloud, o mapeamento das consultas SQL com o nosso projeto Hyperf começa a ser feito automaticamente. Isso é possível graças aos comentários adicionados pelo sqlcommenter nas consultas SQL. Veja o exemplo na imagem abaixo:

Painel do Cloud SQL Insights — Fonte do autor

A imagem acima ilustra como as informações do sqlcommenter são mapeadas dentro do Google Cloud. Nesse contexto, o sqlcommenter é utilizado para adicionar tags no Query Insights, facilitando a identificação de qual parte do código da aplicação está causando problemas de desempenho. Isso torna a telemetria do banco de dados facilmente acessível e perfeitamente integrada com suas ferramentas de escolha, proporcionando observabilidade de ponta a ponta.

Com isso, os desenvolvedores conseguem analisar em detalhes seus microsserviços e entender por que certas consultas estão causando alta latência nas requisições.

Painel do Cloud SQL Insights — Fonte do autor

Uma vantagem adicional é a capacidade de identificar facilmente qual serviço está gerando uma consulta lenta, permitindo direcionar a atenção necessária para a equipe responsável realizar as correções necessárias. Sem essa correlação no banco de dados, podemos perder tempo tentando entender onde está o problema e qual código está gerando a consulta.

Cenário hipotético

Imagine uma situação em que uma nova versão de um serviço é implantada e começa a consumir muita CPU do banco de dados, fazendo com que a instância do banco atinja 100% de utilização de CPU.

Esse problema pode desencadear um efeito dominó, onde os microserviços conectados ao banco de dados começam a ficar lentos devido à alta utilização da CPU do banco de dados. Isso torna a identificação do serviço causador mais difícil, pois você começará a receber alertas de lentidão de vários serviços, todos decorrentes da lentidão causada por um serviço específico ainda não identificado.

Atualmente, quando enfrentamos problemas de desempenho, não somos tão eficientes quanto gostaríamos. Detectamos o problema através da lentidão em uma determinada requisição e em seguida, iniciamos uma série de investigações para identificar a causa raiz.

No entanto, com a associação entre a consulta SQL e o serviço, podemos identificar rapidamente qual serviço está causando o aumento do consumo de CPU. Assim, podemos concentrar nossos esforços na correção do problema nesse serviço específico, sabendo que ele é o principal responsável pelo problema.

Fonte: Antecipe-se aos problemas de desempenho do banco de dados com o Cloud SQL Insights | Google Cloud Blog

Além dessa correlação, os desenvolvedores também passam a entender melhor como suas consultas funcionam, pois terão acesso a informações mais detalhadas através dos painéis do Cloud SQL Insights e Cloud Trace.

Fonte: Antecipe-se aos problemas de desempenho do banco de dados com o Cloud SQL Insights | Google Cloud Blog

Por padrão, o Hyperf gera informações de trace para as consultas SQL realizadas. Com essas informações, podemos ver qual consulta foi executada e o tempo que levou para ser concluída. Veja o exemplo na imagem abaixo:

Hyperf/Trace DB — Fonte do autor

No entanto, essas informações por si só podem não ser suficientes, exigindo uma investigação mais detalhada para identificar o problema real que está causando a lentidão.

Ao usar a biblioteca sqlcommenter-hyperf, você pode vincular as informações de trace do Cloud SQL Query com seu projeto Hyperf. Ao correlacionar essas informações, você alcançará um nível de rastreabilidade muito mais detalhado do que o fornecido pelo Hyperf por padrão. Isso permitirá entender exatamente o que está acontecendo em cada operação interna da sua consulta. Veja o exemplo abaixo:

Associação do trace da request do Hyperf com o Cloud SQL Query — Fonte do autor

Ao observar a imagem abaixo, podemos perceber que a biblioteca substituiu o trace padrão gerado pelo Hyperf para as consultas SQL e associou os traces gerados pelo Cloud SQL Query com o trace da requisição que originou a consulta. Além disso, agora podemos identificar com mais detalhes o que realmente está causando a lentidão da nossa consulta.

Um ponto importante a ser mencionado é que o trace do Cloud SQL Query não tem servidor. Ele gerencia a coleta de telemetria para diagnósticos com o mínimo impacto no desempenho, reduzindo o tempo gasto no gerenciamento da infraestrutura de monitoramento. Todas as métricas de desempenho são protegidas pela segurança, privacidade e conformidade do Google Cloud.

Verificação do desempenho da biblioteca

Ao usar a biblioteca do Sqlcommenter Hyperf pode introduzir um pequeno impacto de desempenho devido à adição de comentários às consultas SQL. No entanto, os benefícios em termos de rastreabilidade, facilidade de depuração e integração com ferramentas de monitoramento geralmente superam esse impacto.

Para demonstrar a eficácia da biblioteca Sqlcommenter Hyperf, realizaremos dois testes distintos. A medição será realizada em um ambiente controlado do Google Cloud Run com as seguintes configurações:

  • CPU sempre alocada
  • Número mínimo de instâncias: 1
  • Número máximo de instâncias: 1
  • Memória por instância: 1GB
  • Número de vCPUs por instância: 1vCPU
  • Máximo de requisições concorrentes por instância: 1000

Veja abaixo o projeto que foi usado como experimento:

Há documentação completa sobre como recriar o ambiente usado para os testes. Nele, você encontrará um guia passo a passo detalhado, desde a configuração do banco de dados até a configuração do Cloud Run. Seguir essa documentação é fundamental para entender como o aplicativo foi configurado e como ele se comportou durante os testes.

Análise de desempenho do bloco de código responsável pelos comentários

No contexto de nosso aplicativo, um ponto crítico de desempenho é o segmento de código responsável por adicionar comentários SQL às consultas antes de sua execução. Esse processo é essencial para a rastreabilidade e análise de desempenho das consultas SQL, permitindo que as consultas sejam monitoradas e analisadas de forma mais eficaz.

Para medir o desempenho desta operação, utilizamos a função para capturar os tempos de início e término do processo. A diferença entre esses tempos, multiplicada por 1000, nos dá o tempo de execução em milissegundos. Aqui está o trecho de código usado para essa medição:microtime(true)

$start = microtime(true);
$query = $proceedingJoinPoint->arguments['keys']['query'];

/** @var Connection $dbInstance */
$dbInstance = $proceedingJoinPoint->getInstance();

$proceedingJoinPoint->arguments['keys']['query'] = $this->appendSqlComments($query, $dbInstance->getDriverName());

$end = microtime(true);
$time_elapsed_ms = ($end - $start) * 1000;

$this->logger->debug(sprintf("Execution time Sqlcommenter code: %.2f ms", $time_elapsed_ms), [
'execution_time' => $time_elapsed_ms,
]);

Você pode encontrar a biblioteca com a versão do código acima, criada especificamente para teste de desempenho, através do seguinte comando:

composer require reinanhs/sqlcommenter-hyperf:dev-test/benchmarking

Nota: Esta versão destina-se a ser usada apenas para testes de desempenho.

Após a coleta de 10.000 registros de tempo de execução para essa operação, calculamos o tempo médio de execução, que foi de aproximadamente 0,103 milissegundos (ms). Esse valor indica que inserir comentários SQL em consultas é uma operação extremamente rápida, adicionando sobrecarga insignificante ao tempo total de execução da consulta.

Para obter esse valor, criamos um ambiente Cloud Run conforme mencionado nos tópicos iniciais, detalhando as especificações do ambiente de execução de teste. Usamos a ferramenta K6 para fazer várias solicitações ao nosso código de teste. Após várias chamadas, analisamos os logs gerados. Veja abaixo um exemplo do filtro usado para analisar essas informações dentro do Google Cloud:

Fonte do autor

Usando a ferramenta do Cloud Logging para análise, baixamos os últimos 10.000 registros emitidos pela biblioteca relacionados ao tempo de execução.

Fonte do autor

Com essas informações baixadas, pudemos analisar e realizar algumas operações para calcular o tempo médio de execução. Para o cálculo da média, utilizou-se o código abaixo:

<?php

// Reads the content of the JSON log file
$logContent = file_get_contents('./downloaded-logs-20240712-220042.json');

// Decodes the JSON content into an associative array
$logArray = json_decode($logContent, true);

// Gets the total number of items in the log array
$totalLogs = count($logArray);

// Initializes the variable for the sum of execution times
$totalExecutionTime = 0;

// Iterates over each log to sum the execution times
foreach ($logArray as $logEntry) {
// Gets the execution time of the current log and converts it to float
$executionTime = (float) $logEntry['jsonPayload']['context']['execution_time'];
// Adds the execution time to the total sum
$totalExecutionTime += $executionTime;
}

// Calculates the average execution time
$averageExecutionTime = $totalExecutionTime / $totalLogs;

// Displays the average execution time
var_dump($averageExecutionTime); // float(0.10319230556488038)

?>

A análise dos resultados demonstra que a eficiência do código de inserção de comentários SQL é essencial para garantir que nosso sistema mantenha alto desempenho mesmo com a adição de rastreamento detalhado. Com uma média de apenas 0,103 ms por operação, podemos afirmar que esse segmento de código é otimizado e não afeta negativamente o desempenho geral do sistema.

Teste de desempenho da latência por requisições

O objetivo deste teste é avaliar o impacto da biblioteca Sqlcommenter Hyperf nos tempos de resposta da solicitação em um cenário de uso do mundo real. Ao contrário do teste de bloco de código isolado, esse teste analisa o desempenho geral do sistema sob carga medindo com a biblioteca habilitada e desabilitada.

Para este teste, usaremos as mesmas configurações do Cloud Run especificadas anteriormente e a ferramenta K6 para simular vários usuários virtuais (VUs).

Script K6 para medir solicitações por segundo

O script a seguir será usado para calcular o número de solicitações por segundo, variando o número de usuários virtuais a cada minuto. A duração do teste será de 1 minuto por etapa, e o número de usuários virtuais aumentará gradualmente:

import http from 'k6/http';
import { check } from 'k6';

export const options = {
stages: [
{ duration: '1m', target: 50 },
{ duration: '1m', target: 100 },
{ duration: '1m', target: 200 },
{ duration: '1m', target: 300 },
{ duration: '1m', target: 400 },
{ duration: '1m', target: 500 },
],
thresholds: {
http_req_duration: ['p(95)<3000'], // 95% of requests must complete within 3 seconds
},
};

export default function () {
const result = http.get(`${__ENV.APP_HOSTNAME}/departments`);

check(result, {
'http response status code is 200': (r) => r.status === 200,
});
}

Cenários de teste

Veja abaixo os cenários que vão ser utilizados no teste:

Cenário com a biblioteca habilitada:

  • Executamos o script K6 com a variável de ambiente definida como .SQLCOMMENTER_ENABLE=1
  • Monitoramos o número de solicitações por segundo em cada estágio de carregamento.

Cenário com a biblioteca desativada:

  • Reimplantamos o aplicativo com a variável de ambiente definida como .SQLCOMMENTER_ENABLE=0
  • Executamos o mesmo script K6 e monitoramos os resultados.

Após a execução dos testes, geramos o seguinte gráfico comparativo:

Fonte do autor

Análise dos resultados

Analisando o gráfico acima, podemos ver que, inicialmente, os tempos de resposta são muito semelhantes para ambas as configurações. No entanto, à medida que o consumo de CPU aumenta e nos aproximamos do limite de 1vCPU, com isso a configuração desativada começa a ter um desempenho ligeiramente melhor.

Examinando os gráficos de utilização da CPU, observamos que em torno de 400 VUs, o uso da CPU foi de aproximadamente 98% para ambas as configurações. Quando a biblioteca não está competindo intensamente pelo uso da CPU, ela mantém um desempenho muito bom, próximo à configuração desativada.

Isso sugere que em condições de alta demanda, a configuração desativada pode lidar com a carga um pouco melhor, resultando em um aumento marginal no número de solicitações atendidas por segundo.

O futuro da biblioteca sqlcommenter-hyperf

Meu objetivo é continuar atualizando a biblioteca e corrigir quaisquer erros que sejam reportados pela comunidade no GitHub. À medida que a biblioteca ganha mais usuários, minha intenção é submetê-la ao repositório do opentelemetry-sqlcommenter para que ela seja incluída nos exemplos em PHP.

Se você chegou até esta parte do artigo e gostou da ideia da biblioteca para o Hyperf, peço que colabore no GitHub, dando uma estrela para o projeto. Isso ajudará a aumentar a visibilidade e o reconhecimento da biblioteca dentro da comunidade.

Configuração do projeto na Google Cloud

Nessa parte da documentação, será abordado como replicar um ambiente de teste para utilizar essas configurações na Google Cloud.

Siga as instruções abaixo para testar esse projeto dentro da Google Cloud. Recomenda-se a execução dos comandos utilizando o Cloud Shell. O Cloud Shell é um ambiente de linha de comando baseado em navegador que permite que você gerencie seus recursos do Google Cloud diretamente do console do GCP.

Passo 1: Configurar o ID do projeto

Primeiro, defina a variável de ambiente com o ID do seu projeto na Google Cloud:

export DEVSHELL_PROJECT_ID=id-do-projeto

Passo 2: Criar a instância do Cloud SQL

Crie uma instância do Cloud SQL com as seguintes configurações:

gcloud sql instances create sample-sqlcommenter-database \
--project=$DEVSHELL_PROJECT_ID \
--database-version=MYSQL_8_0_31 \
--tier=db-custom-1-3840 \
--region=us-central1 \
--activation-policy=ALWAYS \
--availability-type=ZONAL \
--storage-size=10GB \
--storage-type=SSD \
--storage-auto-increase \
--no-backup \
--maintenance-window-day=SUN \
--maintenance-window-hour=13 \
--maintenance-release-channel=preview \
--network=projects/$DEVSHELL_PROJECT_ID/global/networks/default \
--no-assign-ip \
--insights-config-query-insights-enabled \
--insights-config-record-application-tags \
--insights-config-record-client-address \
--insights-config-query-string-length=1024 \
--no-deletion-protection \
--edition=ENTERPRISE

O comando acima criará um banco de dados de teste para realizarmos os experimentos com o Sqlcommenter. Um ponto importante a ser observado são os parâmetros do query-insights, pois é através deles que conseguiremos ativar essa funcionalidade no banco de dados. O parâmetro mais importante é o insights-config-record-application-tags, que armazena as tags do sqlcommenter.

Se você estiver executando o comando em um projeto que ainda não possui uma rede criada, pode encontrar um pequeno erro na primeira execução. Nessa situação, é recomendável criar uma rede para o SQL e, em seguida, executar o comando novamente.

Passo 3: Importar banco de dados

Copie as configurações da conta de serviço da instância do SQL para uma variável de ambiente:

CLOUD_SQL_SA_NAME=$(gcloud sql instances describe sample-sqlcommenter-database --project=$DEVSHELL_PROJECT_ID --format="value(serviceAccountEmailAddress)")

Faça a configuração do IAM para o Cloud SQL no Bucket:

gsutil iam ch serviceAccount:${CLOUD_SQL_SA_NAME}:roles/storage.objectAdmin gs://$DEVSHELL_PROJECT_ID

Nesse cenário, é necessário ter um bucket para que possamos importar um arquivo SQL e popular o nosso banco de dados pela primeira vez. Se você não tiver um, crie um bucket e envie os arquivos que serão solicitados nas próximas etapas.

O banco de dados completo utilizado para a realização dos testes pode ser encontrado no site oficial do MySQL:

Importe o banco de dados para a instância criada:

gcloud sql import sql sample-sqlcommenter-database gs://$DEVSHELL_PROJECT_ID/sample-sqlcommenter-database.sql

Passo 4: Criar usuário para o banco de dados

Crie um usuário para o banco de dados:

gcloud sql users create demo \
--instance=sample-sqlcommenter-database \
--password=secret

Passo 5: Definir variáveis de ambiente para conexão com o banco de dados

Obtenha o endereço privado da instância do banco de dados e defina as variáveis de ambiente necessárias:

export DB_HOST=$(gcloud sql instances list --filter=name:sample-sqlcommenter-database --format="value(PRIVATE_ADDRESS)") 
export DB_DATABASE=employees
export DB_USERNAME=demo
export DB_PASSWORD=secret

Passo 6: Implantar a aplicação no Cloud Run

Implante sua aplicação no Cloud Run com as seguintes configurações:

gcloud run deploy sample-sqlcommenter-hyperf-poc \
--image=reinanhs/sample-sqlcommenter-hyperf-poc:benchmarking \
--allow-unauthenticated \
--memory=1Gi \
--concurrency=1000 \
--min-instances=1 \
--max-instances=1 \
--set-env-vars=DB_HOST=$DB_HOST \
--set-env-vars=DB_DATABASE=$DB_DATABASE \
--set-env-vars=DB_USERNAME=$DB_USERNAME \
--set-env-vars=DB_PASSWORD=$DB_PASSWORD \
--set-env-vars=SQLCOMMENTER_ENABLE=1 \
--set-env-vars=GCP_PROJECT_ID=$DEVSHELL_PROJECT_ID \
--no-cpu-throttling \
--region=us-central1 \
--network=default \
--subnet=default \
--vpc-egress=private-ranges-only \
--project=$DEVSHELL_PROJECT_ID

O comando acima é responsável por criar uma Cloud Run utilizando uma imagem com a estrutura padrão para usar o Hyperf com o Sqlcommenter. Para mais detalhes sobre a imagem utilizada na implantação, é recomendável consultar o site do Docker Hub onde a imagem está disponível.

Passo 7: Testar a aplicação

Execute o comando abaixo para exportar o endereço do aplicativo de teste:

export APP_URL=$(gcloud run services describe sample-sqlcommenter-hyperf-poc --platform managed --region=us-central1 --format 'value(status.url)')

Para testar a aplicação, execute o comando abaixo e obtenha a URL do serviço:

curl "${APP_URL}/"
curl "${APP_URL}/employees"
curl "${APP_URL}/callable"

Veja o exemplo de algumas requisições feitas:

Fonte do autor

Depois de confirmar que a implantação e as configurações do banco de dados e do Cloud Run foram realizadas corretamente e estão funcionando, você deve acessar o painel de instâncias do SQL e abrir o Query Insights para visualizar os mapeamentos que estão sendo feitos através do sqlcommenter. Veja a imagem de ilustração abaixo:

Fonte do autor

Observe na imagem acima que todas as requisições de testes foram mapeadas, permitindo visualizar as três rotas que foram chamadas durante os testes realizados anteriormente.

K6 testes

Este script realiza um teste de carga simples, aumentando gradualmente o número de usuários, mantendo a carga por um tempo e depois reduzindo. Você pode ajustar os parâmetros conforme necessário para atender aos seus requisitos específicos.

k6 run -e APP_HOSTNAME=${APP_URL} .k6/try-script.js
k6 run -e APP_HOSTNAME=${APP_URL} .k6/performance-script.js

Configuração do OpenTelemetry Collector Contrib

Este guia fornece uma visão passo a passo para configurar o OpenTelemetry Collector no Google Cloud usando um ambiente de teste para esse projeto. Seguindo as instruções abaixo, você será capaz de configurar um cluster Kubernetes no GKE, criar uma conta de serviço, atribuir permissões necessárias e implantar o OpenTelemetry Collector.

Passo 8: Criar um Cluster Kubernetes no GKE

Use o comando abaixo para criar um cluster Kubernetes. Este cluster será utilizado para hospedar o OpenTelemetry Collector.

gcloud beta container --project ${DEVSHELL_PROJECT_ID} clusters create "poc-sqlcommenter-cluster-1" \
--region "us-central1" \
--no-enable-basic-auth \
--release-channel "regular" \
--machine-type "e2-custom-2-4096" \
--image-type "COS_CONTAINERD" \
--disk-type "pd-balanced" \
--disk-size "10" \
--metadata disable-legacy-endpoints=true \
--scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" \
--spot \
--num-nodes "1" \
--logging=SYSTEM,WORKLOAD \
--monitoring=SYSTEM \
--enable-ip-alias \
--network "projects/${DEVSHELL_PROJECT_ID}/global/networks/default" \
--subnetwork "projects/${DEVSHELL_PROJECT_ID}/regions/us-central1/subnetworks/default" \
--no-enable-intra-node-visibility \
--default-max-pods-per-node "110" \
--security-posture=standard \
--workload-vulnerability-scanning=disabled \
--no-enable-master-authorized-networks \
--addons HorizontalPodAutoscaling,HttpLoadBalancing,GcePersistentDiskCsiDriver \
--enable-autoupgrade \
--enable-autorepair \
--max-surge-upgrade 1 \
--max-unavailable-upgrade 0 \
--binauthz-evaluation-mode=DISABLED \
--enable-managed-prometheus \
--workload-pool "${DEVSHELL_PROJECT_ID}.svc.id.goog" \
--enable-shielded-nodes

Passo 9: Criar uma conta de serviço para o OpenTelemetry Collector

Crie uma conta de serviço no IAM que será usada pelo OpenTelemetry Collector para se autenticar com os serviços do Google Cloud.

gcloud iam service-accounts create opentelemetry-collector --display-name="OpenTelemetry Collector Service Account"

Passo 10: Atribuir papéis à conta de serviço

Atribua os papéis necessários à conta de serviço criada para permitir que ela envie dados de rastreamento e monitoração para o Google Cloud.

gcloud projects add-iam-policy-binding ${DEVSHELL_PROJECT_ID} \
--member=serviceAccount:opentelemetry-collector@$DEVSHELL_PROJECT_ID.iam.gserviceaccount.com \
--role=roles/cloudtrace.agent
gcloud projects add-iam-policy-binding ${DEVSHELL_PROJECT_ID} \
--member=serviceAccount:opentelemetry-collector@$DEVSHELL_PROJECT_ID.iam.gserviceaccount.com \
--role=roles/monitoring.viewer

Passo 11: Conexão com o cluster

Faça a conexão com o cluster:

gcloud container clusters get-credentials poc-sqlcommenter-cluster-1 --region us-central1 --project ${DEVSHELL_PROJECT_ID}

Passo 12: Configurar a política do IAM para a conta de serviço do Kubernetes

Crie uma política do IAM que permita que a ServiceAccount do Kubernetes personifique a conta de serviço do IAM.

gcloud iam service-accounts add-iam-policy-binding opentelemetry-collector@$DEVSHELL_PROJECT_ID.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:$DEVSHELL_PROJECT_ID.svc.id.goog[default/opentelemetry-collector-ksa]"

Passo 13: Anotar a ServiceAccount do Kubernetes

Faça a execução do comando abaixo para criar conta de serviço:

kubectl create serviceaccount opentelemetry-collector-ksa

Anote a ServiceAccount do Kubernetes para estabelecer a associação entre a conta de serviço do Kubernetes e a conta de serviço do IAM.

kubectl annotate serviceaccount opentelemetry-collector-ksa \
--namespace default \
iam.gke.io/gcp-service-account=opentelemetry-collector@$DEVSHELL_PROJECT_ID.iam.gserviceaccount.com

Passo 14: Implantar o OpenTelemetry Collector no Kubernetes

Faça a conexão com o cluster:

gcloud container clusters get-credentials poc-sqlcommenter-cluster-1 --region us-central1 --project ${DEVSHELL_PROJECT_ID}

Aplique o arquivo de configuração do OpenTelemetry Collector no cluster Kubernetes.

kubectl apply -f https://raw.githubusercontent.com/ReinanHS/sample-sqlcommenter-hyperf-poc/main/.k8s/otel-collector.yaml

Seguindo esses passos, você terá configurado corretamente o OpenTelemetry Collector no Google Cloud, permitindo a coleta e monitoramento eficaz dos dados de observabilidade em seu ambiente de teste.

Passo 15: Validação da configuração do OpenTelemetry

Após a implantação das configurações, você deverá executar o comando abaixo para verificar se o balanceador de carga interno foi criado corretamente e se disponibilizou um endereço IP para que o Cloud Run consiga se comunicar e enviar as informações do tracer do Hyperf para o OpenTelemetry.

kubectl get services

Você também consegue visualizar essas informações através do painel na GCP:

Fonte do autor

Você deverá anotar o endereço de IP interno, pois utilizaremos esse endereço na próxima etapa.

Na próxima fase, reimplantaremos o nosso Cloud Run, desta vez passando as variáveis de ambiente TRACER_DRIVER e ZIPKIN_ENDPOINT_URL.

gcloud run deploy sample-sqlcommenter-hyperf-poc \
--image=reinanhs/sample-sqlcommenter-hyperf-poc:benchmarking \
--allow-unauthenticated \
--memory=1Gi \
--concurrency=1000 \
--min-instances=1 \
--max-instances=1 \
--set-env-vars=DB_HOST=$DB_HOST \
--set-env-vars=DB_DATABASE=$DB_DATABASE \
--set-env-vars=DB_USERNAME=$DB_USERNAME \
--set-env-vars=DB_PASSWORD=$DB_PASSWORD \
--set-env-vars=SQLCOMMENTER_ENABLE=1 \
--set-env-vars=GCP_PROJECT_ID=$DEVSHELL_PROJECT_ID \
--set-env-vars=TRACER_DRIVER=zipkin \
--set-env-vars=ZIPKIN_ENDPOINT_URL=http://10.128.0.45:9411/api/v2/spans \
--no-cpu-throttling \
--region=us-central1 \
--network=default \
--subnet=default \
--vpc-egress=private-ranges-only \
--project=$DEVSHELL_PROJECT_ID

Lembre-se de substituir o IP da variável ZIPKIN_ENDPOINT_URL pelo valor correspondente ao seu projeto. Em seguida faça mais algumas requisições para serem processadas:

curl "${APP_URL}/employees"

Depois de realizar as requisições, abra o Trace Explorer para verificar se essas informações estão sendo propagadas corretamente para o OpenTelemetry e se os dados de trace do Cloud SQL Query estão sendo associados às nossas requisições no Hyperf. Veja a imagem de ilustração abaixo:

Fonte do autor

Através da imagem acima, podemos verificar que a propagação está ocorrendo corretamente e que a associação das informações do trace também está sendo realizada de forma adequada.

Passo 16: Limpeza dos recursos

Para deletar os serviços e a instância do banco de dados criados, execute os seguintes comandos:

gcloud run services delete sample-sqlcommenter-hyperf-poc --region="us-central1"
gcloud sql instances delete sample-sqlcommenter-database
gcloud container clusters delete poc-sqlcommenter-cluster-1 --region="us-central1"
gsutil iam ch -d serviceAccount:${CLOUD_SQL_SA_NAME}:roles/storage.objectAdmin gs://$DEVSHELL_PROJECT_ID

Conclusão

Neste artigo, exploramos a importância da observabilidade no contexto de bancos de dados SQL, especialmente quando se utiliza o framework Hyperf. Com o advento do modelo DevOps, a responsabilidade pelo desempenho e pela análise das aplicações recai cada vez mais sobre os desenvolvedores, tornando essencial o uso de ferramentas eficazes para monitorar e solucionar problemas de performance.

Além disso, discutimos várias ferramentas de observabilidade disponíveis no mercado, como DB Marlin, PlanetScale Insights, Releem e Cloud SQL Insights, destacando suas funcionalidades e como podem ajudar as equipes de desenvolvimento a manter seus sistemas eficientes. Em particular, focamos no uso do Sqlcommenter, uma biblioteca que adiciona comentários às consultas SQL, melhorando a rastreabilidade e a capacidade de diagnóstico.

A integração do Sqlcommenter com o Hyperf foi apresentada como uma solução para aumentar a observabilidade e a identificação de problemas de desempenho em aplicações distribuídas. A biblioteca sqlcommenter-hyperf, foi criada para preencher essa lacuna, uma vez que permite que os desenvolvedores adicionem automaticamente comentários às consultas SQL executadas pelo Hyperf, facilitando a correlação entre o código da aplicação e o desempenho do banco de dados.

Exemplos práticos foram fornecidos, demonstrando como instalar e configurar a biblioteca. Testes de performance foram realizados para validar a eficiência da biblioteca, mostrando que a adição de comentários às consultas SQL é uma operação rápida e que a sobrecarga introduzida é mínima.

Se você gostou desta ideia e considera útil para o seu projeto, não deixe de apoiar no GitHub, ajudando a aumentar a visibilidade e o reconhecimento da biblioteca na comunidade.

Referências

Esta publicação foi embasada em algumas referências bibliográficas, que foram fundamentais para a construção do conteúdo apresentado. Recomendamos a leitura dessas referências, a fim de obter uma compreensão mais aprofundada do tema abordado neste artigo. Ao consultar essas fontes, você terá acesso a informações adicionais e poderá explorar aspectos específicos da observabilidade com mais detalhes.

--

--