5. Aplicando teste de carga na plataforma Dojot

Neste tutorial será demonstrado como rodar um teste de carga usando a implementação do Locust feita para a dojot.

Atenção

A implementação do Locust foi feita para realizar testes com o VerneMQ. Testes com o Mosca não têm garantia de funcionamento.

5.1. Preparando o ambiente

Primeiramente, você precisa de um ambiente dojot rodando. Verifique o Guia de instalação para mais informações.

To access the Locust implementation, download the dojot repository on your machine and switch to the same version as your current environment:

git clone https://github.com/dojot/dojot.git
cd dojot
git checkout v0.6.0

Entre na pasta do Locust:

cd connector/mqtt/locust

5.2. Rodando um teste simples

Nesta seção, será demonstrado como configurar e rodar o Locust, além de como gerar certificados com o script generate_certs que serão utilizados para executar o teste de carga. Este é um teste simples, onde serão criados 100 clientes que irão enviar mensagens à dojot. Antes de rodar os testes

5.2.1. Configuração

Nota

Verifique o README incluído no diretório do Locust para aprender mais sobre a arquitetura e configurações. Neste tutorial serão cobertas somente as configurações mais importantes.

Antes de rodar os testes, algumas configurações nos arquivos de docker compose do Locust precisam ser alteradas.

Abra o arquivo Docker/docker-compose-master.yml e mude as seguintes variáveis de ambiente:

# The location of your dojot installation
DOJOT_URL: "http://1.2.3.4"
# Usually it's the dojot address too (if you don't know for sure, keep the same address as dojot)
DOJOT_MQTT_HOST: "1.2.3.4"
# The default MQTTS port
DOJOT_MQTT_PORT: "8883"

Abra o arquivo Docker/docker-compose-slave.yml e mude as seguintes variáveis de ambiente:

# The location of your dojot installation
DOJOT_URL: "http://1.2.3.4"
# Usually it's the dojot address too (if you don't know for sure, keep the same address as dojot)
DOJOT_MQTT_HOST: "1.2.3.4"
# The default MQTTS port
DOJOT_MQTT_PORT: "8883"

Nota

Estamos assumindo que você está rodando o master e o slave na mesma máquina, i.e. no modo não distribuído. Mais à frente será mostrado como distribuir os slaves em múltiplas máquinas.

Abra o arquivo Docker/scripts/generate_certs/docker-compose.yml e mude as seguintes variáveis de ambiente:

# The location of your dojot installation
DOJOT_URL: "http://1.2.3.4"

5.2.2. Gerando os certificados

Como dito anteriormente, a comunicação entre Locust e dojot é segura, portanto é necessário o uso de certificados.

Existem duas maneiras de se simular os dispositivos: você pode criar dispositivos falsos (que não aparecerão na GUI da dojot) ou dispositivos reais. Nesta parte do tutorial serão criados os dispositivos reais para que você possa verificar a chegada das mensagens na GUI.

Antes de rodar o script, é necessário inicializar o Locust master. Dentro do repositório do Locust, rode:

docker-compose -f Docker/docker-compose-master.yml up

Após sua inicialização, rode o contêiner do script generate_certs e entre nele:

docker-compose -f Docker/scripts/generate_certs/docker-compose.yml up -d
docker-compose -f Docker/scripts/generate_certs/docker-compose.yml exec generate-certs bash

Crie os dispositivos na dojot:

generate_certs dojot create --devices 100

Agora é possível verificar que os dispositivos foram criados na dojot.

_images/img1.png

Fig. 5.12 : Alguns dos dispositivos que o generate_certs criou na dojot.

_images/img2.png

Fig. 5.13 : O template usado pelo generate_certs para criar os dispositivos.

Gere os certificados para eles:

generate_certs cert --dojot

Os certificados são exportados para a pasta cert. Agora o teste pode ser inicializado!

5.2.3. Inicializando os slaves

O Locust master não faz nada por si só. Quem realmente faz todo o trabalho de enviar as requisições é o contêiner do Locust slave. Para inicializá-lo, rode:

docker-compose -f Docker/docker-compose-slave.yml up

Você deve ver no Locust master uma mensagem dizendo que há um slave conectado a ele.

5.2.4. Rodando o teste

Está tudo pronto para inicializar o teste. Para rodá-lo, é preciso acessar a interface do Locust em seu navegador no endereço localhost:8089 (supondo que você está rodando o Locust master no localhost).

Digite 100 em Number of users to simulate, 10 em Hatch rate e clique em Start swarming. Isso dirá ao Locust para rodar 100 clientes, criando 10 deles por segundo.

_images/img3.png

Fig. 5.14 : Configurando o Locust para rodar os clientes.

A configuração padrão dita que cada cliente mande uma mensagem a cada 30 segundos, então você deverá aguardar um pouco para ver as mensagens chegando na dojot.

_images/img4.png

Fig. 5.15 : As estatísticas do Locust após rodar os testes por alguns minutos.

Você pode ir até a dojot e ver as mensagens chegando por lá.

_images/img5.png

Fig. 5.16 : Um dispositivo de exemplo recebendo mensagens.

5.3. Rodando um teste distribuído

Para testes pequenos, o procedimento supracitado deve ser o suficiente, mas se você deseja realmente forçar a dojot, barreiras serão encontradas ao usar somente um slave e/ou uma máquina. Para solucionar este problema, o Locust provê o modo distribuído, permitindo a inicialização de múltiplos slaves em múltiplas máquinas, limitando o desempenho do Locust ao montante de poder de processamento (e orçamento!) que você tem.

Serão utilizadas duas máquinas virtuais rodando 4 slaves (2 em cada VM) e 1 master (em uma das VMs) para criar os 1.000 dispositivos falsos. Vamos nos referir à máquina com o master como primária e à outra como secundária.

Atenção

Não há uma correlação entre os números escolhidos: o número de clientes que cada slave suporta é dependente de diversas variáveis, como o número de núcleos de CPU disponíveis.

Dica

Recomendamos que você rode 1 slave por núcleo da CPU de sua máquina, i.e. se você tem uma VM com 4 CPUs, rode 4 slaves.

5.3.1. Configuração para o modo distribuído

Antes de rodar os testes, há mudanças a serem feitas nos docker compose do Locust. Note que você deve clonar o repositório da dojot em cada máquina em que o Locust rodará.

Dica

Como as configurações podem ser as mesmas para os slaves e para o script generate_certs, você pode os compartilhar entre máquinas usando o sshfs. Assumindo que você esteja na pasta do Locust na máquina secundária, rode o comando:

sshfs -o allow_other -o nonempty <user>@<ip>:/path/to/dojot/connector/mqtt/locust/Docker Docker

Verifique a documentação do sshfs para mais detalhes.

Abra o arquivo Docker/docker-compose-master.yml na máquina primária e mude as seguintes variáveis de ambiente:

# The location of your dojot installation
DOJOT_URL: "http://1.2.3.4"
# Usually it's the dojot address too (if you don't know for sure, keep the same address as dojot)
DOJOT_MQTT_HOST: "1.2.3.4"
# The default MQTTS port
DOJOT_MQTT_PORT: "8883"

Abra o arquivo Docker/docker-compose-slave.yml e mude as seguintes variáveis de ambiente:

# The location of your dojot installation
DOJOT_URL: "http://1.2.3.4"
# Usually it's the dojot address too (if you don't know for sure, keep the same address as dojot)
DOJOT_MQTT_HOST: "1.2.3.4"
# The default MQTTS port
DOJOT_MQTT_PORT: "8883"

# If it's in the same machine as the master, you can leave as it is
LOCUST_MASTER_HOST: "locust-master"

# If it's in the same machine as the master, you can leave as it is
REDIS_HOST: "redis"
# Change to 6380 if the master is in another machine
REDIS_PORT: "6379"

Abra o arquivo Docker/scripts/generate_certs/docker-compose.yml e mude as seguintes variáveis de ambiente:

# The location of your dojot installation
DOJOT_URL: "http://1.2.3.4"

# If it's in the same machine as the master, you can leave as it is
REDIS_HOST: "redis"
# Change to 6380 if the master is in another machine
REDIS_PORT: "6379"

Como pode-se ver, as configurações mudaram pouco, sendo que as principais mudanças são somente na localização do Redis e do master.

5.3.2. Gerando os certificados

Nesta parte do tutorial, serão criados dispositivos falsos que, ao contrário do teste simples, não aparecerão na GUI da dojot.

Antes de rodar o script, precismos inicializar o Locust master. Dentro da pasta do Locust na máquina primária, rode:

docker-compose -f Docker/docker-compose-master.yml up

Após a inicialização, rode o docker compose do generate_certs na máquina primária e entre nela:

docker-compose -f Docker/scripts/generate_certs/docker-compose.yml up -d
docker-compose -f Docker/scripts/generate_certs/docker-compose.yml exec generate-certs bash

Crie os certificados:

generate_certs cert --devices 1000

Nota

Os dispositivos falsos são simulados como certificados.

Agora entre em sua máquina secundária, inicialize o generate_certs e, dentro dele, rode:

generate_certs redis --export

Como os certificados são armazenados no Redis, você pode simplesmente exportá-los com o comando mostrado em qualquer máquina, prevenindo o trabalho tedioso de copiar em cada VM a pasta cert com os certificados.

5.3.3. Inicialização do slave

Rode em suas máquinas primária e secundária:

docker-compose -f Docker/docker-compose-slave.yml up --scale locust-slave=2

Este comando criará dois contêineres do Locust slave em cada máquina. Você deverá notar no Locust master mensagens confirmando a conexão de cada slave.

5.3.4. Rodando o teste distribuído

Está tudo pronto para a realização do teste. Para iniciá-lo, você deve acessar a interface do Locust no seu navegador através do domínio do Locust master, e.g. localhost:8089.

Digite 1000 em Number of users to simulate, 10 em Hatch rate e clique em Start swarming. Isso dirá ao Locust para rodar 1.000 clientes, criando 10 deles por segundo.

_images/img6.png

Fig. 5.17 : Configurando o Locust para rodar os clientes.

_images/img7.png

Fig. 5.18 : As estatísticas do Locust após rodar os testes por alguns minutos.

5.4. Usando o dashboard do Locust no Grafana

The Locust web interface is easy and simple to use, but there are some downsides. The major one is the persistence: The history data will be deleted as soon as you close or refresh the page.

Para resolver este problema, foi adicionada a imagem Locust Exporter no docker compose do Locust master, permitindo a exportação das métricas em um formato compatível com o Prometheus. Desta forma, é possível armazenar estas informações no Prometheus e centralizar todos os dashboards no Grafana. Infelizmente ainda é necessário acessar a interface web do Locust para começar o teste.

Atenção

Como a stack Grafana/Prometheus só está disponível na instalação por meio de Kubernetes, esta seção não é aplicável para a instalação por meio de docker compose. Nós o encorajamos a verificar o Guia de instalação para mais informações sobre os métodos de instalação da dojot.

5.4.1. Configuração do Ansible

Você deve decidir onde o seu Locust master estará de antemão antes de rodar o playbook do Ansible. As configurações do Ansible que você precisa modificar para conectar o Locust Exporter com o Prometheus são:

dojot_enable_locust_exporter: true
dojot_locust_exporter:
  ip: 1.2.3.4

Mude o IP para o do Locust master e rode o playbook. Agora você pode inicializar um teste (distribuído ou não) como mostrado nas seções anteriores e deverá ver os dados do Locust sendo enviados ao dashboard do Locust no Grafana.

_images/img8.png

Fig. 5.19 Estatísticas do Locust no Grafana - antes de começar o teste.

_images/img9.png

Fig. 5.20 Estatísticas do Locust no Grafana - depois da inicialização do teste.

5.5. Requisitos para um teste com 100.000 clientes

Agora que você sabe como rodar testes distribuídos utilizando o Locust, você consegue executar o teste com 100.000 clientes. Para tal, você precisará de bastante poder computacional e múltiplas máquinas, tanto para a dojot como para o Locust, O objectivo é chegar a 100.000 conexões MQTTS simultâneas com taxa de ~3.333 RPS (tanto para publicação quanto para recepção), i.e. uma mensagem a cada 30 segundos para cada cliente conectado.

Como este é somente um caso especial de teste distribuído, cobriremos somente as especificações e algumas dicas para o teste, já que o procedimento para configuração é o mesmo que nós já fizemos.

Nota

Como você já deve saber, este teste só é possível na instalação via Kubernetes da dojot.

5.5.1. Especificações de hardware

Para a plataforma dojot:

Nome da máquina

Serviços presentes

CPU

RAM

dojot-verne-1

VerneMQ, K2V e V2K

8

8GB

dojot-verne-2

VerneMQ, K2V e V2K

8

8GB

dojot-verne-3

VerneMQ, K2V e V2K

8

8GB

dojot-x509

x509 identity manager

4

4GB

dojot-kafka

Kafka e Zookeeper

6

6GB

dojot-dojot

O restante dos serviços

4

4GB

haproxy

Load balancer

4

4GB

Para o Locust, usaremos 5 réplicas da mesma máquina, com 14GB de RAM e 9 CPUs.

5.5.2. Dicas gerais para o teste

  • O Ansible tem a tag 100k para preparar o ambiente para um teste com 100.000 clientes. Isto roda uma versão minificada da dojot, excluindo alguns serviços; tal estratégia foi adotada pois nem todos os serviços da dojot suportam tamanha carga.

  • Ao compartilhar um volume persistente entre pods da EJBCA, é possível escalá-la para aumentar a velocidade de criação de certificados.

  • A criação de certificados pode ser distribuída entre todas as máquinas de Locust. Em nosso exemplo - com 5 máquinas para o Locust - nós conseguimos gerar 20.000 certificados em cada máquina. Isso aumenta substancialmente a velocidade de criação de certificados quando aliado ao aumento de instâncias da EJBCA rodando.

  • Após gerar os certificados, confirme que todas as máquinas estão com todos os certificados. Você pode os exportar rodando o comando generate_certs redis --export dentro do contêiner do generate_certs.

  • Para verificar o número de certificados, rode:

    ls cert | wc -l
    

    O valor retornado deve ser 200.003. Este número inclui a chave e o certificado de cada dispositivo, o certificado da CA e as pastas renew e revoke.

  • É altamente recomendado rodar um slave por núcleo, totalizando 45 slaves neste exemplo.

  • Como a interface web do Locust não persiste nenhum dado, use o dashboard do Locust no Grafana para monitorar o seu teste. Verifique a seção anterior para mais informações sobre como configurar o Locust Exporter.

  • Você também pode rodar o teste com revoke e renew. Verifique o README do repositório para mais detalhes de configuração.