🚀 Apache Iggy na prática
Uma POC com Java e Go que surpreendeu
Nos últimos dias resolvi explorar uma tecnologia que ainda não está no radar de muita gente, mas que tem um potencial enorme: o Apache Iggy.
A ideia foi simples: montar uma POC prática, usando Java (Spring Boot) e Go, simulando um cenário de comunicação assíncrona e processamento de eventos em tempo real.
O objetivo? Entender se o Iggy realmente entrega valor ou se é só mais uma promessa no universo de streaming.
Spoiler: me surpreendeu — e bastante.
🧠 O que é o Apache Iggy?
O Apache Iggy é uma plataforma moderna de streaming de dados e mensageria, com foco em:
- Alta performance
- Baixa latência
- Simplicidade operacional
Ele surge como uma alternativa mais leve em comparação com soluções tradicionais, especialmente em cenários onde não faz sentido subir uma infraestrutura complexa.
⚙️ Arquitetura da POC
Na POC, montei algo bem direto ao ponto:
- Producer em Java (Spring Boot)
- Consumer em Go
- Comunicação via streams do Iggy
- Simulação de eventos em tempo real
Fluxo básico:
[Java Producer] → [Apache Iggy] → [Go Consumer]
☕ Java Producer (Spring Boot simplificado)
Aqui vou fazer um producer bem direto usando client genérico (mockando o client do Iggy, pois libs ainda variam).
📦 Dependência (exemplo genérico)
<!-- Source: https://mvnrepository.com/artifact/org.apache.iggy/iggy -->
<dependency>
<groupId>org.apache.iggy</groupId>
<artifactId>iggy</artifactId>
<version>0.7.0</version>
<scope>compile</scope>
</dependency>
@Configuration
public class IggyConfig {
@Value( "${iggy.host}")
private String host;
@Bean
public IggyTcpClient iggyClient(){
return IggyTcpClient.builder()
.host(host)
.port(8090)
.build();
}
}
import lombok.RequiredArgsConstructor;
import org.apache.iggy.client.blocking.tcp.IggyTcpClient;
import org.apache.iggy.identifier.StreamId;
import org.apache.iggy.identifier.TopicId;
import org.apache.iggy.message.Message;
import org.apache.iggy.message.Partitioning;
import org.apache.iggy.topic.CompressionAlgorithm;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigInteger;
import java.util.List;
import static java.util.Optional.empty;
@RestController
@RequestMapping(path = "/iggy")
@RequiredArgsConstructor
public class IwaRest {
private final IggyTcpClient iggyTcpClient;
static final String STREAM_NAME = "iggy-sample";
static final StreamId STREAM_ID = StreamId.of(STREAM_NAME);
static final String TOPIC_NAME = "iggy-topic";
static final TopicId TOPIC_ID = TopicId.of(TOPIC_NAME);
@PostMapping
public String create(@RequestBody Object message){
if(iggyTcpClient.streams().getStream(STREAM_ID).isEmpty()){
iggyTcpClient.streams().createStream(STREAM_NAME);
}
if(iggyTcpClient.topics().getTopic(STREAM_ID, TOPIC_ID).isEmpty()){
iggyTcpClient.topics().createTopic(
STREAM_ID,
1L,
CompressionAlgorithm.None,
BigInteger.ZERO,
BigInteger.ZERO,
empty(),
TOPIC_NAME);
}
Partitioning partitioning = Partitioning.partitionId(0L);
ObjectMapper mapper = new ObjectMapper();
iggyTcpClient.messages().sendMessages(
STREAM_ID,
TOPIC_ID,
partitioning,
List.of(Message.of(mapper.writeValueAsString(message))));
return "OK";
}
Veja o código fonte completo em meu github
https://github.com/tiagoiwamoto/ti-spring4-projects/tree/master/07-iggy-producer
🐹 Go Consumer
Agora um consumer simples em Go lendo esse evento.
📄 consumer.go
package mainimport (
"encoding/json"
"fmt"
)// Estrutura do payload SWAPI
type Character struct {
Name string `json:"name"`
Height string `json:"height"`
Mass string `json:"mass"`
BirthYear string `json:"birth_year"`
}// Mock de client Iggy
type IggyClient struct{}func Connect(url string) *IggyClient {
fmt.Println("Conectado ao Iggy em", url)
return &IggyClient{}
}func (c *IggyClient) Consume(stream string, handler func([]byte)) {
fmt.Println("Consumindo stream:", stream) // Simulando mensagem recebida
mockMessage := []byte(`{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"birth_year": "19BBY"
}`) handler(mockMessage)
}func main() { client := Connect("localhost:8090") client.Consume("swapi-stream", func(msg []byte) { var character Character err := json.Unmarshal(msg, &character)
if err != nil {
fmt.Println("Erro ao processar mensagem:", err)
return
} fmt.Println("📥 Evento recebido:")
fmt.Printf("Nome: %s\n", character.Name)
fmt.Printf("Altura: %s cm\n", character.Height)
fmt.Printf("Peso: %s kg\n", character.Mass)
fmt.Printf("Nascimento: %s\n", character.BirthYear)
})
}
O foco foi medir:
- Latência
- Throughput
- Facilidade de integração
- Complexidade operacional
📊 Resultados da POC
Aqui foi onde a coisa ficou interessante.
⚡ Latência
Extremamente baixa — comunicação praticamente em tempo real.
🪶 Consumo de recursos
Muito mais leve do que o esperado. Ideal para ambientes mais restritos.
🧩 Simplicidade
Setup rápido e direto. Sem aquela complexidade típica de clusters maiores.
👨💻 Experiência de desenvolvimento
Integração fluida, especialmente combinando Java e Go.
🔥 O combo Java + Go + Iggy
Essa combinação funcionou melhor do que eu imaginava:
☕ Java (Spring Boot)
- Robustez
- Ecossistema maduro
- Facilidade para APIs e integração
🐹 Go
- Performance
- Baixo consumo
- Simplicidade no consumo de eventos
⚡ Iggy
- Infraestrutura leve
- Streaming eficiente
- Baixa complexidade
👉 Resultado: uma stack moderna, eficiente e sem excesso de peso.
🎯 Cenários ideais para usar o Apache Iggy
Depois da POC, esses são os cenários onde vejo maior valor:
1. Event-Driven Architecture (EDA) leve
Quando você quer trabalhar com eventos, mas sem precisar de um “monstro” de infraestrutura.
2. Processamento em tempo real
Aplicações que precisam reagir rápido, como:
- Notificações
- Monitoramento
- Atualizações em tempo real
3. Microsserviços
Comunicação assíncrona eficiente entre serviços, com baixa latência.
4. Edge computing
Ambientes com recursos limitados, onde soluções mais pesadas não fazem sentido.
5. Substituição de brokers tradicionais (em cenários específicos)
Principalmente em sistemas menores ou novos, onde você quer começar mais simples.
⚖️ Quando talvez NÃO usar
Nem tudo são flores — e isso é importante deixar claro.
O Iggy ainda não substitui soluções maduras como Apache Kafka em todos os cenários.
Evitaria usar quando:
- Você depende de um ecossistema muito consolidado
- Precisa de integrações enterprise específicas
- Tem requisitos avançados de governança e compliance
- O time não pode assumir risco de tecnologia emergente
🧭 Comparação rápida com Kafka
| Aspecto | Apache Iggy | Apache Kafka |
|---|---|---|
| Complexidade | Baixa | Alta |
| Setup | Simples | Mais complexo |
| Performance | Muito alta | Alta |
| Ecossistema | Em crescimento | Muito maduro |
| Casos ideais | Leves e modernos | Grandes ambientes |
🧩 Conclusão
O Apache Iggy não veio para substituir tudo.
Mas ele pode ser exatamente o que faltava para muitos cenários modernos:
- Menos complexidade
- Mais performance
- Mais foco no problema e menos na infraestrutura
👉 Para workloads enxutos e arquiteturas modernas, ele pode simplificar MUITO.
💬 Vale a pena?
Se você trabalha com:
- Microsserviços
- Event-driven
- Streaming
- Sistemas distribuídos
👉 Sim, vale muito a pena testar.
Às vezes a melhor solução não é a mais conhecida — é a que resolve o problema com menos esforço.