Categoria Golang

porAndré Luis Pereira dos Santos

Introdução a Concorrência em GO – 1

Trabalhando em conjunto

Série de artigos:

Concorrência em Go é um tema dos mais interessantes e com aplicações de alto impacto hoje em dia.

E o que é concorrência? E o que é seu irmão, o paralelismo?

Todo processamento paralelo é concorrente, mas nem todo processamento concorrente é paralelo.

No processamento paralelo duas ou mais instruções são executadas ao mesmo tempo em núcleos diferentes.

No processamento concorrente, duas ou mais instruções são enviadas para execução, mas esta execução pode ser feita em um ou mais núcleos.

Quando o escalonador decide executar as instruções em um mesmo núcleo, elas o serão de maneira concorrente, já que concorrerão por uma fatia de tempo de execução neste núcleo. Lembrando que o núcleo de CPU executa uma instrução por vez. (uma simplificação que não leva em conta pipelines em múltiplos estágios etc)

Eventualmente o escalonador deverá migrar instruções para núcleos diferentes disponíveis, e nestes casos, código concorrente irá rodar em paralelo.

A utilização massiva de computadores com diversos núcleos/cpus foi o caminho para continuarmos à escalar o poder de processamento, já que velocidade bruta medida em GHz de clock de CPU estagnou.

Mas com a utilização de concorrência temos uma série de questões a serem resolvidas em nosso código, que se não forem corretamente endereçadas, levam a comportamentos erráticos, respostas incorretas e até mesmo, crashs.

Uma das grandes questões são as race conditions, em português “condições de corrida”.

Este termo vem do fato de que quando introduzimos concorrência e/ou paralelismo em nosso código, introduzimos muitas vezes uma “corrida” para saber quem terá acesso primeiro a determinado dado ou recurso, ou ainda, uma corrida por dados ou recursos em que se perdeu a sincronia que é capas de produzir resultados corretos ao fim do processamento.

Podem ser duas threads, ou no caso de Go, duas goroutines querendo acessar ao mesmo tempo um mesmo dado (data race) ou recurso.

O que acontece se uma goroutine acessa e muda um dado na memória enquanto outra goroutine estava lendo este dado?
E se o dado é apagado por uma goroutine enquanto outra estava lendo ele?

Estes são cenários que podem ser difíceis de debugar e para os quais deve-se prestar muita atenção.

Felizmente Go foi pensada desde o início para escrever código seguro nestas condições e evitar bugs terríveis e que muitas vezes, podem demorar anos para aparecerem.

Falei rapidamente de threads, instruções e goroutines. Agora vamos falar sobre, afinal de contas, O QUE É UMA GOROUTINE?

Uma goroutine é de certa maneira parecida em conceito com uma thread do sistema operacional.

Ela é uma unidade lógica de execução de seu código que roda de maneira independente do restante do software e que faz um trabalho específico.

Uma goroutine, assim que criada, é alocada pelo escalonador do runtime Go de seu software para rodar em algum dos núcleos de CPU disponíveis, incluindo o núcleo em que roda a goroutine principal de seu programa. (sim, em um programa feito em Go, tudo roda dentro de alguma Goroutine, inclusive seu código principal)

Pense em goroutines como uma “thread mais leve” e rápida para ser criada e destruída. Elas consomem pouca memória também.

Com isso, podemos criar goroutines aos milhares, facilmente, mesmo em computadores modestos, sem grandes penalidades de performance.

E isso com os bônus de um gerenciamento descomplicado e grande segurança de uso, com menores chances de bugs comuns em software multithread.

Criamos uma goroutine com a palavra reservada: go.

go func(a Type)

No próximo artigo vamos falar um pouco sobre alguns cuidados para evitar race conditions e outras coisas.

Por fim, se você gostou da iniciativa, e puder, com o QR Code abaixo, pode me pagar um café.

Com ele você me envia um PIX com o valor que você escolher.

Ou se preferir, envie usando minha chave PIX: [email protected]

pague-um-cafe Introdução a Concorrência em GO - 1
porAndré Luis Pereira dos Santos

Go e Concorrência: A Série

Programação Concorente

Artigos da Série:

Talvez a característica mais legal da linguagem Go seja suas primitivas para escrita de código concorrente e as formas adotadas de tornar segura o uso de variáveis nestes ambientes.

Programação concorrente nunca foi um assunto trivial.

Sempre foi fonte de infindáveis bugs, muitas vezes difíceis de detectar e debugar.

Desenvolvedores de várias gerações lidaram com este assunto fazendo uso de mutexes, semáforos etc, fazendo deste tipo de programação parecer quase uma bruxaria.

Estou iniciando uma série de artigos e vídeos a partir de hoje com o intuito de ajudar desenvolvedores da linguagem Go ou aqueles que desejam iniciar seu aprendizado nela, a produzir software que aproveite de maneira mais eficiente e elegante a concorrência.

Material completamente gratuito.

Falarei sobre:

  • problemas que podem aproveitar concorrência em seu processamento
  • cuidados
  • formas de debug e profiling
  • aspectos técnicos e formais
  • boas práticas e padrões
  • dentre outras coisas

Sinto que falta um material detalhado sobre este assunto para os falantes da língua portuguesa, e essa é uma maneira que encontrei para fechar um pouco o gap.

Espero ajudar, inclusive os desenvolvedores mais novos com material da maior qualidade que eu possa produzir.

Por fim, se você gostou da iniciativa, e puder, com o QR Code abaixo, pode me pagar um café.

Com ele você me envia um PIX com o valor que você escolher.

Ou se preferir, envie usando minha chave: [email protected]

pague-um-cafe Go e Concorrência: A Série
porAndré Luis Pereira dos Santos

Analisando tráfego UDP em Go utilizando Machine Learning – Começando

Como dito em post anterior,estou iniciando um pequeno projeto para verificar a viabilidade de uso de algumas bibliotecas em Go (Golang) para capturar pacotes UDP, analisá-los com um algorítimo de ML (Isolation Forest) e gerar alertas para discrepâncias (outliers).

Esse projeto possui potencial de uso em ferramentas de segurança de redes.

Na prática, ao que parece, nada me impediria de capturar tráfego de outros protocolos e fazer o mesmo, mas decidi iniciar com UDP por simplicidade.

Estou na fase de modelagem utilizando-me da biblioteca GoLearn (https://github.com/sjwhitworth/golearn) de ML e a biblioteca do Google Gopacket (https://github.com/google/gopacket) que me disponibiliza captura e processamento de pacotes de rede e outras facilidades relacionadas.

Vou descrever algumas idéias iniciais, já que estou nelas para daí gerar uma prova de conceito:

  • Captura de pacotes durante tráfego normal da rede
  • Filtragem dos pacotes para obtenção só dos que são UDP
  • Gravação dos pacotes e metadados em arquivo CSV que é a amostra de treino
  • Carregamento do CSV e treino da Isolation Forest
  • Passagem em tempo real de tráfego capturado através da Isolation Forest para obtenção de sua pontuação

Dessa maneira, ao final, cada pacote capturado em tempo real passa pela Isolation Forest “treinada” e obtêm-se sua pontuação indicando conforme a faixa, se aquele pacote representa um outlier (discrepância) ou não, possibilitando a emissão de alertas imediatos.

Lembrando que o algorítimo de Isolation Forest é um algorítimo de aprendizagem não-supervisionada.

Basicamente essa é a ideia. Agora vou partir para modelar uma arquitetura que torne possível a reutilização de componentes neste software e que ao mesmo tempo possibilite alto throghput.

*Photo by Robynne Hu on Unsplash

porAndré Luis Pereira dos Santos

Detecção de anomalias de tráfego em redes com ML e Go

Estou desenvolvendo um pequeno projeto para detecção de anomalias que indiquem tráfego malicioso em redes.

A ideia é capturar o tráfego em tempo real com um software feito em Go utilizando a biblioteca do Google gopacket (https://github.com/google/gopacket).

Após isso, utilizar o algorítimo de machine learning Isolation Forest para detectar anomalias (outliers) no tráfego que é capturado no formato pcap.

O Isolation Forest é relativamente rápido e simples de lidar, além de ser um algorítimo não-supervisionado, o que facilita muito as coisas.

A motivação para o desenvolvimento é dar maior proteção para clientes em suas redes, que muitas vezes misturam servidores e estações de trabalho.

Mais tarde pretendo implementar ações pró-ativas e reativas na rede de forma autônoma com base nesta detecção de anomalias.

Em mais alguns dias subirei um repositório no Github com o código liberado como opensource. 🙂