Elido
12 min de leituraRecursos
Essencial

Smart links explicados: encaminhamento na edge sem um serviço extra

O que é um smart link, onde corre e as dimensões de encaminhamento que a Elido suporta. Deep dive de engenharia sobre invalidação de cache na edge, semântica de primeira correspondência e quando não usar um

Marius Voß
DevRel · edge infra
Diagrama de uma única ligação curta a ramificar para três destinos com base em país, dispositivo e idioma

Imprimimos 18.000 flyers para um lançamento de produto na região DACH em março. Uma ligação curta no verso, três páginas de destino regionais para onde queríamos enviar as pessoas: /de para visitantes alemães, /fr para a pequena fatia francesa, /en para todos os outros. O responsável de marketing fez a pergunta óbvia: imprimimos três flyers ou um?

Imprime-se um. A ligação trata do encaminhamento.

Um "smart link" é um único URL curto cujo destino é calculado no momento do redirecionamento, e não na altura da criação da ligação. Há apenas um slug. Há vários destinos possíveis. A decisão acontece no mesmo handler que de outra forma emitiria um simples 302 - sem serviço separado a chamar, sem shim JS numa página de destino, sem hop adicional. Este artigo é sobre como isso funciona sob o capô, as seis dimensões de encaminhamento da Elido e os casos em que deve usar uma ferramenta diferente.

As pessoas chegam aos smart links a partir de três experiências anteriores diferentes, e as contrapartidas são diferentes em cada uma.

Redirecionamento simples. Um slug, um destino, zero lógica. O handler de redirecionamento faz uma pesquisa em cache e emite um 302. Não há nada mais rápido em termos de latência; também não pode torná-lo condicional. Esse é o mínimo - qualquer coisa mais sofisticada tem um custo.

Smart link na edge. Um slug, vários destinos possíveis, uma pequena etapa de avaliação de regras inserida entre a pesquisa em cache e a resposta. Como a regra vive no mesmo processo que a pesquisa em cache, o custo é sub-milissegundo (0,3ms p50 / 1ms p95 no caso da Elido). O visitante vê apenas uma ida e volta HTTP. A cache do browser não fica contaminada, porque as respostas 302 não são cacheáveis por defeito de acordo com o RFC 7234 §4.2.2 - um facto que importa aqui, porque o encaminhamento por pedido só faz sentido se cada pedido puder escolher o seu próprio destino.

Router A/B em JavaScript numa página de destino. Uma página HTML neutra renderiza, o JS examina navigator.userAgent ou um serviço de geo-IP, depois window.location = '/foo'. Esta é a pior opção das três. O visitante vê uma renderização HTML, depois um redirecionamento, depois a página real - pelo menos uma ida e volta adicional, muitas vezes duas se a pesquisa geográfica for de terceiros. A indexação SEO fica confusa porque os crawlers veem a página neutra. Os browsers com bloqueio de cookies e extensões de privacidade quebram a metade em JS. As notas de lançamento do Intelligent Tracking Prevention 2.3 da Apple apontam exatamente este padrão: as ligações de rastreamento do lado do cliente via referrer do documento são limitadas, e a mitigação requer participação do lado do servidor. Se está a fazer encaminhamento em JS hoje, já está a pagar a fatura.

O lugar certo para colocar uma decisão de encaminhamento é o mesmo hop que já está a emitir o redirecionamento. É isso que os smart links na edge fazem.

Por que vive na edge - o orçamento de latência#

O nível de redirecionamento da Elido tem um orçamento de latência rígido: p50 de 5ms, p95 de 15ms num cache hit, excluindo o handshake TLS. Esse número não é aspiracional - tudo o que nos leve acima disso é removido. SQL síncrono na via quente, compilação de regex por pedido, I/O bloqueante no evento de clique: tudo removido, tudo movido para workers da via fria.

As duas razões pelas quais esse orçamento existe:

  1. As redes móveis adicionam o seu próprio imposto. O guia da Apple "Reducing Network Latency" mostra como os atrasos de redes celulares se acumulam em cadeias de redirecionamento. Cada hop adicional acrescenta RTT que a rede do visitante já inflacionou. Quanto menos hops adicionarmos, menos a rede os penaliza.
  2. A proximidade à edge é a alavanca real. O guia da Cloudflare sobre encaminhamento na edge enquadra da mesma forma: a decisão mais barata é aquela tomada no mesmo processo que o writer de resposta, no POP mais próximo do visitante. Não somos únicos a fazer encaminhamento na edge; o que é único é integrá-lo no encurtador de URL em vez de pedir-lhe que implante uma função Workers / Lambda@Edge separada.

Se delegássemos a avaliação de regras para um serviço downstream - digamos, uma hipotética "rules-api" acessível via HTTP - adicionaríamos uma ida e volta na mesma região em cada pedido. Na mesma região isso é cerca de 5ms no mínimo (um salto na mesma região numa rede privada), e no tráfego entre regiões a cauda piora muito rapidamente. O p95 de 15ms não sobrevive à ida e volta. Por isso as regras de smart link são inline, no binário da edge, a avaliar contra matchers compilados que foram construídos quando a ligação foi carregada na cache. Todo o motor de regras tem cerca de 400 linhas de Go.

Esse acoplamento estreito é também a razão pela qual conseguimos edições de regras em tempo real: as alterações de regras propagam-se via um canal pub/sub da cache em memória (link:invalidate) ao qual todos os POPs da edge estão subscritos. O LRU L1 expira dentro de um segundo após a publicação, o próximo pedido repopula a partir do L2, e a nova regra fica ativa. Mais sobre isso abaixo.

As seis dimensões de encaminhamento#

Os smart links da Elido correspondem a seis coisas. Cada uma mapeia para uma entrada específica que a edge tem acesso por pedido.

País. Duas letras ISO 3166-1 alpha-2, derivadas do IP do visitante via geoip. Útil quando tem lojas regionais e o aumento de conversão por país justifica a complexidade de encaminhamento. O problema clássico aqui são os viajantes - um alemão de férias em Espanha acede ao destino espanhol se encaminhar apenas por país. Se a preferência de idioma importa mais do que a localização geográfica, encaminhe por languages. Discutimos o fluxo geoip completo no artigo sobre privacidade nas análises - o IP é truncado antes do armazenamento para manter o lado RGPD limpo.

Dispositivo. mobile, tablet, desktop, analisados a partir da string User-Agent no momento do pedido. O caso de uso pelo qual os marketers recorrem a isto: banners de instalação de aplicações que vão para a App Store no iOS, Play Store no Android e uma página de marketing no desktop. O que deve vigiar: as strings User-Agent no iPad têm sido um alvo em movimento desde que o iPadOS começou a apresentar o UA de Safari para desktop por defeito, e a nossa deteção de tablet acomoda isso, mas não é 100% em todas as versões de browser. Se a diferença entre tráfego de tablet e desktop lhe importa em termos financeiros, instrumente o destino e verifique.

SO. ios, android, macos, windows, linux. A mesma fonte User-Agent que o dispositivo, partição mais restrita. O caso de deep link: encaminhe visitantes iOS para um Universal Link que a aplicação interceta e recua para a App Store; encaminhe Android para a Play Store com dados de referência preservados. É para isso que construímos a integração com o Apple App Site Association.

Idioma. Tag de idioma primária do cabeçalho Accept-Language do visitante. Códigos ISO 639-1 como de, fr, pt. A armadilha: Accept-Language é a preferência do browser, que muitas vezes discorda do geo por IP. Um expatriado francês em Berlim tem country: DE, languages: ["fr", "en"] - se o quer em /fr, encaminhe por idioma; se o quer na loja alemã porque está a fazer testes A/B de preços localizados, encaminhe por país. Sequencie as regras em conformidade.

Hora do dia e dia da semana. Janela HH:MM em qualquer timezone IANA, mais um bitmap days_of_week. Ofertas com janela temporal - uma página de destino de "happy hour" que fica ativa às 17:00 Europe/Berlin de segunda a sexta e recua para a página normal fora dessa janela - são o caso natural. A janela time_start / time_end suporta sobreposição de dia (22:0002:00), o que parece óbvio mas apanhou-nos quando portámos o motor de regras do protótipo que não o tratava. O schema completo está no guia de smart links.

Host da referência. A parte hostname do cabeçalho Referer, normalizada. Útil para destinos conscientes de parceiros: visitantes provenientes de partner.example acedem a uma página de destino com co-branding; todos os outros acedem ao padrão. Menos útil do que costumava ser - os browsers modernos removem o Referer agressivamente quando a página de referência define Referrer-Policy: no-referrer ou quando a navegação cruza contextos HTTPS de uma forma que a política não permite. Trate as regras de referência como um sinal suave, nunca como autenticação.

Isso é tudo. Seis dimensões cobrem as decisões de encaminhamento de marketing que vimos em três anos de conversas com clientes. As omissões deliberadas são a identidade do utilizador (não a conhecemos no redirecionamento), cabeçalhos HTTP arbitrários (o custo-benefício não é suficiente para as poucas equipas que pediram) e divisões aleatórias (use a rotação de variantes em vez disso, que é uma funcionalidade separada).

Semântica de primeira correspondência; fallback sempre obrigatório#

As regras são um array. A edge percorre-as por ordem. A primeira regra cujo bloco match está completamente satisfeito ganha, e o seu destination_url é o destino do redirecionamento. O destination_url de nível superior da ligação é o fallback incondicional. Recusamos criar um smart link sem um - um smart link nunca produz um 404, por design.

A forma mínima viável:

{
  "destination_url": "https://acme.example/en",
  "targeting_rules": [
    {
      "match": { "countries": ["DE", "AT", "CH"] },
      "destination_url": "https://acme.example/de"
    },
    {
      "match": { "languages": ["fr"] },
      "destination_url": "https://acme.example/fr"
    }
  ]
}

Os visitantes DACH acedem a /de porque a regra 1 corresponde primeiro. Um expatriado francês em Berlim tem country=DE, por isso também acede a /de - a regra 1 corresponde antes de a regra 2 ter hipótese. Se quiser o expatriado francês em /fr, troque as regras para que a regra de idioma seja verificada primeiro. A ordem no dashboard é a ordem que avaliamos.

Construtor de regras do dashboard da Elido, três regras empilhadas por ordem de avaliação: visitantes DACH, falantes de francês, fallback da aplicação iOS. Cada regra tem campos de país / dispositivo / browser / destino / etiqueta, com um botão Avançado para SO, idioma, hora do dia e regex

Duas implicações disto que vale a pena dizer em voz alta:

  • As regras mais abrangentes ficam por último. Uma regra sem condições match corresponde a tudo; se estiver em primeiro lugar, nenhuma regra abaixo dela é acionada. O dashboard valida isto e avisa, mas a API não, por isso as regras criadas por script precisam de uma verificação de sanidade.
  • A exclusão mútua é da sua responsabilidade. Se duas regras corresponderem ao mesmo visitante, a primeira ganha silenciosamente. Não há erro, nenhum flag, nenhuma métrica. Considerámos emitir um aviso no momento de carregamento da ligação quando duas regras são detetáveis como sobrepostas, e isso está no roadmap para o próximo lançamento menor. Por agora: leia as suas regras de cima para baixo e confie na ordem.

O custo: propagação de invalidação de cache#

Cada decisão de encaminhamento tem uma janela de propagação. As regras de smart link editadas no dashboard propagam-se pelas caches L1 nos três POPs da Elido em aproximadamente 1 segundo na via feliz. Aproximadamente, porque:

  • O LRU L1 em cada POP mantém ligações com regras com um TTL de 60 segundos (a arquitetura de cache está documentada aqui). O TTL é o limite superior - mesmo sem uma publicação de invalidação, uma entrada obsoleta desaparece dentro de um minuto.
  • A publicação de invalidação é via pub/sub da cache em memória. Os POPs da UE e do Leste dos EUA partilham um cluster de cache; a Ásia-Pacífico tem o seu próprio. A propagação entre regiões é essencialmente a latência de replicação da cache mais o processamento pub/sub do nosso subscriber, que foi inferior a 1 segundo p99 nas nossas métricas no último trimestre.
  • Um POP que perdeu a sua subscrição da cache recua para o TTL de 60 segundos. Alertamos para a perda de subscrição; o serviço de plantão tem 5 minutos de cliques em buffer antes do WAL entrar em ação.

Tradução: para fluxos de marketing onde 60 segundos de encaminhamento obsoleto é aceitável, não precisa de pensar nisto. Para fluxos onde a obsolescência importa - uma rotação de aviso legal, uma divisão de coorte de faturação onde o destino errado cobra a moeda errada - a abordagem é status=disabled primeiro, depois reativar após um minuto, depois publicar a nova regra. Adicionámos um endpoint GET /v1/links/{id}/status para que um pipeline CI possa verificar a conclusão da propagação antes de acionar um switch downstream.

Três casos onde a ferramenta certa não é um smart link.

A renderização do lado do servidor do destino é melhor. Se a variante tem de ser injetada na resposta HTML - por exemplo, localização de preços que depende do estado autenticado do visitante, ou uma página de destino que obtém um hero específico de coorte do seu CMS - isso é trabalho para o próprio servidor do destino, não para o redirecionamento. O redirecionamento escolhe para onde enviar o visitante; o destino escolhe o que renderizar. A lógica de encaminhamento que vive na edge não consegue ver a sua sessão de autenticação, e integrá-la forçosamente exigiria ou vazar a sessão para a via de redirecionamento (o que não faremos) ou fazer proxy através da edge (o que não fazemos por causa do orçamento de latência). Renderize variantes na origem.

Testes A/B estatisticamente rigorosos. Os smart links encaminham por pedido, não por visitante. Se um visitante chegar duas vezes em cinco minutos a partir do mesmo dispositivo, pode ver dois destinos diferentes sob uma regra aleatória, o que é o comportamento correto para "enviar 50% do tráfego móvel para A e 50% para B" mas o comportamento errado para "medir se a variante A converte melhor do que a variante B ao longo de uma janela de 4 semanas". Para isso, precisa de um cookie de variante estável e de uma ferramenta de experimentação que faça as estatísticas adequadamente. PostHog, GrowthBook e LaunchDarkly fazem tudo isso. Nós não, e não vamos fazer - as ferramentas são um trabalho diferente. Use a rotação de variantes com round_robin para amostragem de baixo risco e recorra a uma plataforma de experimentação quando precisar de defender o resultado.

Encaminhamento consciente de identidade. Os smart links são deliberadamente stateless. Avaliam contra country | device | OS | language | time | referrer e nada mais. Se precisar de encaminhar com base no nível de um utilizador com sessão iniciada, nas suas feature flags ou em qualquer coisa que requeira pesquisar "quem é esta pessoa", a via de redirecionamento é a camada errada. Resolva a identidade na origem e sirva a variante a partir daí. Ou, se realmente precisar de uma decisão no momento do redirecionamento, crie ligações curtas por utilizador via API - cada utilizador autenticado tem o seu próprio slug, o destino do slug é correto para esse utilizador no momento da criação, e nunca precisa de fazer resolução de identidade na via quente.

O que vem a seguir#

Se quiser experimentar a forma das regras com os seus próprios dados, o guia de documentação percorre o schema JSON e o editor do dashboard. O construtor de regras encontra-se na página de edição de qualquer ligação no dashboard - Ligações → ⋯ → Segmentação.

Duas melhorias a chegar no próximo lançamento menor: uma hierarquia de fallback para languages (para que pt-BR recue graciosamente para pt, depois para en, sem escrever três regras) e uma passagem de análise estática no momento de guardar a ligação que sinaliza regras sobrepostas para que o dashboard possa avisar antes de a regra entrar em vigor. Ambas são trabalho de implementação, sem alterações de schema. Se tiver uma forma de regra que não suportamos e achar que devemos, o canal de feedback está no fundo da página de funcionalidades de smart links.

Relacionado no blog#

Experimente Elido

Cole uma URL, obtenha um link curto

Sem cadastro. O link vive 30 dias. Cadastre-se para mantê-lo para sempre.

Grátis, sem necessidade de registo · 2 por dia

Experimente o Elido

Encurtador de URL hospedado na UE: domínios personalizados, análises profundas e API aberta. Plano gratuito - sem cartão de crédito.

Tags
smart links
edge routing
url shortener
conditional links
device targeting

Continuar lendo