> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Operando o Streaming Hub

> Faça o deploy do Streaming Hub com Helm em BYOC, rode migrations out-of-band, conecte probes de liveness e readiness, defina a configuração essencial e observe o hub através de OTLP.

Esta página é para operadores que rodam o Streaming Hub na sua própria infraestrutura (BYOC). Ela cobre o deployment, a configuração que importa, o contrato de saúde e desligamento, e como observar o serviço.

## Fazendo o deploy com Helm

***

O Streaming Hub é distribuído como um Helm chart dedicado, `streaming-hub-helm`, separado de qualquer outro chart de produto Lerian. O chart roda o hub em uma de duas formas:

* **`all`** — um único deployment que roda todos os workers de background. É o padrão e o mais simples de operar.
* **`split`** — deployments separados de **ingest** e **delivery** que escalam de forma independente: as réplicas de ingest compartilham um único consumer group Kafka, enquanto as réplicas de delivery processam os jobs de entrega a partir do Postgres.

A forma split é dirigida por processo por `STREAMING_HUB_ROLE` (`all` | `ingest` | `delivery`). A role controla **quais workers de background rodam e quais clients Kafka discam** — ela **não** controla quais rotas HTTP são montadas. Toda role serve a API de control-plane completa e, crucialmente, o endpoint `/readyz` do qual o seu orquestrador e o scrape de métricas dependem. Há uma única imagem e um único binário; a role é uma entrada de deployment, não de build.

## Rodando migrations de banco de dados

***

O Streaming Hub é respaldado por um único banco de dados PostgreSQL de propriedade do hub, e ele **nunca migra a si mesmo**. As migrations de schema rodam **out of band** — como um passo de migração separado (por exemplo, um hook PreSync do ArgoCD) que aplica as migrations versionadas antes do hub iniciar. No boot, o hub apenas *verifica* que a versão de schema que ele espera está presente; ele nunca roda uma migration como efeito colateral de iniciar.

O hub de fato provisiona antecipadamente as suas próprias partições de tabela semanais como uma tarefa de background de rotina — isso é manutenção interna, não uma migration de schema, e não requer ação do operador além de deixar o cron de partições rodando.

## Saúde e desligamento gracioso

***

O Streaming Hub expõe dois endpoints de probe distintos. Conecte cada um ao probe correspondente do Kubernetes:

| Endpoint   | Probe     | Comportamento                                                                                                                                                                                                          |
| ---------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/healthz` | Liveness  | Retorna `200` incondicionalmente assim que o processo está servindo, independentemente da saúde do Postgres, do Kafka ou do roster. Um liveness que falha reinicia o pod, então ele não pode depender de dependências. |
| `/readyz`  | Readiness | Dobra o conjunto completo de probes para a role. `Healthy` ou `Degraded` → `200` (mantido em rotação); `Down` → `503` (retirado da rotação). Uma réplica `Degraded` continua servindo.                                 |

O `/readyz` distingue duas classes de falha. Uma falha de **runtime-probe** — Postgres inacessível, consumidor morto — leva a réplica para **Down** e para fora da rotação. Um **degrader** — latência elevada, lag do consumidor, um buffer de partição fino — prende a réplica em **Degraded**, mas a mantém servindo, porque uma réplica prejudicada não deveria recusar tráfego. O conjunto de probes é role-aware: um pod de role delivery não é marcado como não pronto por não ter consumidor de ingest.

No `SIGTERM`, o hub drena graciosamente. Ele vira o `/readyz` para `NotReady` **primeiro** — antes de parar de servir — e espera uma janela pre-stop limitada para que o orquestrador possa retirar o pod do serviço antes que as conexões sejam cortadas. O `/healthz` permanece `200` o tempo todo, de modo que o pod não é morto no meio da drenagem. Ele então desmonta em ordem segura por dependência (HTTP, depois consumidor, depois dispatcher, depois os apps de background, depois os clients Kafka, depois o pool, depois a telemetria).

<Warning>
  Defina o `terminationGracePeriodSeconds` do deployment igual ou acima do teto de drenagem derivado do hub para o seu `STREAMING_HUB_SHUTDOWN_TIMEOUT`, não um número mágico fixo. No timeout de desligamento padrão de 30 segundos, o teto é cerca de **80 segundos**: a janela pre-stop de 5 segundos, mais o próprio timeout de desligamento, mais um trecho de drenagem do dispatcher no pior caso de `min(timeout, 55s)`, mais uma margem fixa de desmontagem para os componentes restantes. Um grace period abaixo do teto arrisca um `SIGKILL` de uma réplica ainda drenando — seguro para a correção (os jobs em voo são recuperados e re-entregues, deduplicados no consumidor), mas abre mão da drenagem limpa.
</Warning>

O `/version` (identidade do build) e o `/runtime` (um snapshot barato do runtime Go) completam a superfície operacional não autenticada para triagem de incidentes.

## Configuração essencial

***

O Streaming Hub lê a sua configuração de variáveis de ambiente `STREAMING_HUB_*` (mais algumas variáveis compartilhadas `PLUGIN_AUTH_*` e `OTEL_*`). O inventário completo, com todos os defaults, está na referência de ambiente do serviço. As variáveis que você define com mais frequência:

| Variável                               | Default                    | Propósito                                                                                                                                                                   |
| -------------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `STREAMING_HUB_ENV`                    | `local`                    | Ambiente de deployment (`local` \| `staging` \| `production`). Dirige o gate de segurança de produção que rejeita as flags de bypass de dev.                                |
| `STREAMING_HUB_ROLE`                   | `all`                      | Fatia implantável: `all` \| `ingest` \| `delivery`. Controla workers e clients Kafka, nunca rotas.                                                                          |
| `STREAMING_HUB_HTTP_LISTEN_ADDR`       | `:8080`                    | O único endereço de bind do control-plane.                                                                                                                                  |
| `STREAMING_HUB_POSTGRES_DSN`           | *(obrigatório)*            | O DSN do PostgreSQL de propriedade do hub. O boot falha se vazio.                                                                                                           |
| `STREAMING_HUB_KAFKA_BROKERS`          | *(vazio)*                  | Lista de brokers de bootstrap para o stream interno.                                                                                                                        |
| `STREAMING_HUB_TENANT_ID`              | `default`                  | O id do tenant BYOC. Veja o aviso abaixo antes de mudá-lo.                                                                                                                  |
| `STREAMING_HUB_KEK_SOURCE`             | `env`                      | Provedor da key-encryption-key (`env` \| `secretsmanager`).                                                                                                                 |
| `STREAMING_HUB_KEK_REF`                | *(vazio)*                  | O **nome** da variável de ambiente que contém o material da KEK — nunca o material em si.                                                                                   |
| `STREAMING_HUB_MANIFEST_SOURCES`       | *(vazio)*                  | As URLs base de manifest de produtor a partir das quais o catálogo de eventos é construído.                                                                                 |
| `PLUGIN_AUTH_ADDRESS`                  | *(default do plugin-auth)* | A URL base do decision-point do plugin-auth para autorização do control-plane.                                                                                              |
| `PLUGIN_AUTH_ENABLED`                  | `true`                     | A chave-mestra de auth. `false` é um bypass local, **rejeitado em produção**.                                                                                               |
| `STREAMING_HUB_AUTODISABLE_ENABLED`    | `true`                     | Kill switch para desativar automaticamente destinos quebrados.                                                                                                              |
| `STREAMING_HUB_SHUTDOWN_TIMEOUT`       | `30s`                      | A janela de drenagem graciosa. A janela pre-stop mais `min(valor, 55s)` deve permanecer estritamente abaixo do lease de 60 segundos do dispatcher, ou o boot falha fechado. |
| `STREAMING_HUB_MULTI_TENANT_ENABLED`   | `false`                    | `false` é BYOC single-tenant; `true` conecta o roster SaaS multi-tenant.                                                                                                    |
| `STREAMING_HUB_AWS_HUB_PRINCIPAL_ARN`  | *(vazio)*                  | O principal IAM público do hub embutido nos artefatos de setup da AWS. Obrigatório para sinks AWS.                                                                          |
| `STREAMING_HUB_AWS_SETUP_TEMPLATE_URL` | *(vazio)*                  | A URL pública do template CloudFormation para o link de criação rápida da AWS.                                                                                              |
| `OTEL_EXPORTER_OTLP_ENDPOINT`          | *(vazio)*                  | O endpoint do coletor OTLP para o qual a telemetria exporta (sem o prefixo `STREAMING_HUB_`).                                                                               |

**Valores** de segredo nunca pertencem a essas variáveis em produção. A KEK é referenciada pelo *nome* da variável de ambiente na qual a camada de deploy a injeta (`STREAMING_HUB_KEK_REF`); o hub lê o material daquela variável nomeada e nunca o loga. As credenciais SASL, a CA de TLS e as credenciais do tenant-manager seguem a mesma regra — a variável contém o valor em runtime, mas o valor vem do seu secret store, não de um arquivo de configuração commitado.

<Warning>
  **O `STREAMING_HUB_TENANT_ID` é uma armadilha de zero entregas em BYOC.** O hub só aceita eventos cujo `ce-tenantid` corresponde exatamente a este valor; todo outro evento é silenciosamente descartado (`unknown_or_inactive_tenant`), avançando o offset sem linha poison. Se você o definir como qualquer coisa diferente de `default`, você **precisa** confirmar que o produtor emite esse mesmo `ce-tenantid` — caso contrário o hub descarta 100% do stream e não entrega nada, sem erro algum. Um valor não default emite um aviso de startup; preste atenção nele.
</Warning>

## Análise forense de DLQ

***

O `GET /admin/dlq` é a superfície de análise forense do operador para observações de dead-letter. Ele é **cross-tenant por design**: é protegido pelo escopo admin do lib-auth, não carrega **nenhum** shim de tenant e retorna registros de todos os tenants, então não faz parte da API `/v1` voltada ao cliente. As observações de dead-letter que ele lê são **apenas observabilidade** — são capturadas dos tópicos de dead-letter dos produtores upstream e nunca são re-entregues pelo hub. Use-o para investigar por que os registros falharam upstream; ele não os reprocessa.

## Reconciliador de tópicos

***

O reconciliador de tópicos é um detector de drift **somente leitura**, habilitado por padrão (`STREAMING_HUB_RECONCILER_ENABLED`). A cada passagem ele compara os tópicos ativos do broker, o catálogo de eventos e os destinos distintos das assinaturas, e sinaliza três tipos de drift: **tópicos fantasma** (um tópico seguido sem entrada no catálogo), **assinaturas mortas** (um tipo de evento e major assinado sem entrada viva no catálogo) e violações de **lag-versus-retenção**.

Ele **detecta, nunca corrige** — emite gauges apenas de contagem e logs estruturados, e não grava nenhum estado no broker ou no banco de dados. Quando desabilitado, ele não gera goroutine alguma e não disca client admin algum, então o caminho desabilitado não custa nada; desabilitá-lo perde um alarme operacional, mas nunca afeta a entrega.

## Observabilidade

***

O Streaming Hub exporta suas métricas, traces e logs através de **OTLP** (lib-observability), apontado para o coletor em `OTEL_EXPORTER_OTLP_ENDPOINT`. É lá que vivem as métricas `streaming_hub_*` de verdade.

<Note>
  O endpoint `/metrics` é **quase vazio por design**: ele serve apenas o gauge estático `streaming_hub_build_info`. Faça o scrape das métricas reais do hub a partir do seu coletor OTLP, não de `/metrics`.
</Note>

A identidade do tenant nunca é um label de métrica — ela vive em atributos de span e campos de log — de modo que a cardinalidade das métricas permanece limitada não importa quantos tenants um deployment atenda.

## Próximos passos

***

<CardGroup cols={2}>
  <Card title="Como o Streaming Hub funciona" icon="diagram-project" href="/pt/streaming-hub/how-streaming-hub-works">
    Os detalhes internos de entrega por trás das superfícies operacionais acima.
  </Card>

  <Card title="Gerenciando assinaturas" icon="gear" href="/pt/streaming-hub/managing-subscriptions">
    As operações de control-plane que os seus tenants usam.
  </Card>
</CardGroup>
