Trabalhando com Kafka em Rust: visão geral das bibliotecas e exemplos práticos
Apache Kafka é uma plataforma distribuída para processamento de dados em fluxo, amplamente utilizada para construir sistemas de troca de mensagens confiáveis e escaláveis. A linguagem Rust, graças ao seu desempenho e segurança de memória, está se tornando uma escolha cada vez mais popular para escrever aplicações de alta carga que trabalham com Kafka. Neste artigo, vamos explorar as principais bibliotecas para trabalhar com Kafka em Rust, sua instalação e fornecer exemplos simples de código.
Bibliotecas populares para Kafka em Rust
Atualmente, existem duas abordagens principais para trabalhar com Kafka no ecossistema Rust:
- rdkafka — um wrapper sobre a popular biblioteca C librdkafka. Oferece desempenho e funcionalidade máximos, incluindo suporte a todos os recursos modernos do Kafka (transações, idempotência, garantias exatas de entrega).
- Kafka-Rust (kafka) — uma implementação pura do protocolo Kafka em Rust, sem dependências externas. Mais leve na compilação, mas pode ficar atrás em funcionalidade em comparação com o rdkafka.
Para a maioria dos projetos em produção, recomenda-se usar rdkafka, pois é mais maduro, performático e ativamente mantido pela comunidade.
Instalação do rdkafka
Para começar, adicione a dependência ao seu Cargo.toml:
[dependencies]rdkafka = { version = "0.36", features = ["cmake-build"] }tokio = { version = "1", features = ["full"] } # para trabalho assíncronoserde = { version = "1", features = ["derive"] } # para serialização de dadosserde_json = "1" # para trabalhar com JSONA biblioteca rdkafka requer a presença do librdkafka no sistema. Você pode instalá-lo através do gerenciador de pacotes do sistema ou usar a feature cmake-build, como no exemplo acima — neste caso, a biblioteca será compilada automaticamente.
Exemplo: produtor básico (Producer)
O produtor envia mensagens para um tópico Kafka especificado. Aqui está um exemplo simples de um produtor assíncrono usando Tokio:
use rdkafka::config::ClientConfig;use rdkafka::producer::{FutureProducer, FutureRecord};use std::time::Duration;
#[tokio::main]async fn main() { // Criando a configuração do produtor let producer: FutureProducer = ClientConfig::new() .set("bootstrap.servers", "localhost:9092") .set("message.timeout.ms", "5000") .create() .expect("Erro ao criar produtor");
// Enviando mensagem para o tópico "my-topic" let delivery_status = producer .send( FutureRecord::to("my-topic") .payload("Olá, Kafka do Rust!") .key("chave-da-mensagem"), Duration::from_secs(0), ) .await;
match delivery_status { Ok(partition_offset) => println!("Mensagem enviada: {:?}", partition_offset), Err((e, _)) => eprintln!("Erro ao enviar: {}", e), }}Exemplo: consumidor básico (Consumer)
O consumidor lê mensagens de um tópico. Abaixo está um exemplo de consumidor síncrono com confirmação manual (commit):
use rdkafka::config::ClientConfig;use rdkafka::consumer::{Consumer, StreamConsumer};use rdkafka::message::Message;use rdkafka::util::get_rdkafka_version;
fn main() { let consumer: StreamConsumer = ClientConfig::new() .set("group.id", "my-consumer-group") .set("bootstrap.servers", "localhost:9092") .set("enable.auto.commit", "false") // commit manual .set("auto.offset.reset", "earliest") // ler desde o início .create() .expect("Erro ao criar consumidor");
consumer.subscribe(&["my-topic"]).expect("Erro ao assinar");
loop { match consumer.recv() { Ok(msg) => { let paylo Também na biblioteca
Framework CLI para C++: cppcli — criação de aplicações de console
Trabalho com XML em Java: DOM, SAX, StAX e JAXB
Bibliotecas WebSocket Swift: Starscream e URLSessionWebSocketTask
Programação Reativa em C# (.NET) — Observable, Rx.NET e LINQ
Sharp para JavaScript (Node.js): guia completo com exemplos