Conhecimento, ganha-se estudando. Entendimento, ganha-se refletindo sobre algo estudado. Sabedoria, ganha-se com a prática.
Nesse capítulo, usaremos alguns dos conceitos discutidos nesse livro para iniciar a elaboração do design arquitetural de um encurtador de URLs. Iremos tratar, obviamente de um cenário fictício.
O que é um “Encurtador de URLs”
URLs longas são mais difíceis de lembrar, manter e compartilhar. O encurtamento de URL é uma técnica, adotada frequentemente, para transformar endereços HTTP em links mais curtos.
O encurtamento de URLs ganhou destaque, primeiro, com a popularização do Twitter – onde, originalmente, havia um limite de 140 caracteres por postagens. A ideia original era “economizar” caracteres nas URLs compartilhadas para permitir a adição de mais informações em um tuíte. Atualmente, a plataforma já oferece esse recurso built-in.
Alguns serviços para encurtamento de URLs geram estatísticas de acessos a partir dos links encurtados. Também tem se tornado comum permitir a personalização da URL curta, facilitando a leitura.
A adoção de um encurtador de URL pode tornar o acesso a um site perceptivelmente mais lento, devido a necessidade de mais requisições HTTP e DNS.
Coletando informações para o Haiku
Architecture Haiku Não sabe o que é um “Architecture Haiku”? Consulte agora esse tópico no capítulo em que tratamos sobre documentação de software. Acessar tópico |
Designs arquiteturais devem atender os objetivos do negócio, respeitando restrições, satisfazendo atributos de qualidade, mitigando riscos e reduzindo custos. Não há trabalho de arquitetura sem explicitação dos requisitos do negócio. |
Em nosso “cenário fictício”, as pessoas do negócio têm (para variar) a expectativa de lançar o serviço no menor prazo possível. Algumas já atuaram em empresas que forneciam serviços semelhantes, por isso, tem bom conhecimento do que funciona e não funciona na área.
As principais features do serviço, segundo descrito pelas pessoas do negócio, são:
- Encurtar URLs; ou seja, fornecida uma URL longa pelo usuário, gerar uma URL muito menor.
- Redirecionamento rápido; ou seja, acessada uma URL encurtada, gerada pela plataforma, redirecionar o usuário para a URL original
Infere-se, por características do que se está oferencendo, que os atributos disponibilidade, escalabilidade e resiliência são aqueles que se destacam.
Atributos de qualidade Disponibilidade, escalabilidade e resiliência são três atributos de qualidade. Quer relembrar o conceito? Consulte agora o tópico onde o explicamos. Acessar tópico |
NÃO há expectativa de gerar estatísticas, permitir alteração ou exclusão de URLs inseridas na plataforma, tampouco permitir customização das URLs geradas.
Definição: Requisito inverso
Requisito Inverso é uma descrição para demandas em uma especificação de escopo negativo, ou seja, de algo que não será feito ou ou expectativa que não será atendida.
Estimam-se 10 milhões de novas URLs sendo encurtadas diariamente. O formato da URL encurtada deverá ser www.abc.com/<id>
. Sendo que a parte id
deve ser uma cadeia o mais curta possível compostas por números (0-9) e letras (a-z, A-Z).
Não é possível discutir escalabilidade e disponibilidade com nenhuma estimativa relacionada a workloads. |
Algumas estimativas de “papel de pão”
Com base nas informações levantadas com o negócio, em nosso cenário fictício, é possível elaborar algumas estimativas, grosseiras, mas já suficientes para orientar algumas decisões de design.
A ideia não é, necessariamente, chegar a precisão decimal, mas “compartilhar a visão” de números mais tangíveis e começar a estabelecer restrições.
A proporção de 10 para 1 em operações de leitura e gravação é uma referência segura, embora conservadora, para a maioria dos cenários. Serve, pelo menos, como um bom ponto de partida. |
Eventualmente, é interessante discutir com o negócio sobre possíveis sazonalidades, como horários com volumes de uso mais altos.
Pessoas do “negócio” têm tremenda validade de “apontar os números”. Daí, a importância de criar um referencial, mesmo que impreciso, como ponto de partida, buscando obviamente aprimorá-los com o andamento do projeto. |
Para começar a dimensionar infra, é importante considerar que os recursos alocados podem estar “consumidos” até 80% durante a execução para evitar riscos de exaustão.
Sempre explicite desdobramentos associados a carga de trabalho que está sendo projetada. Isso facilita no alinhamento do time e no estabelecimento de fitness functions. |
A partir da carga identificada, é possível determinar algumas fitness functions.
Architectural fitness function Architectural fitness functions são fundamentais para o desenvolvimento de arquiteturas evolutivas. Relembre o conceito Acessar tópico |
Organizando informações para gerar as primeiras ADRs
Architecture Decision Record O bom arquiteto garante que decisões sejam tomadas, justificadas e comunicadas! Precisa relembrar o que é uma ADR? Visite o tópico onde introduzimos o conceito. Acessar tópico |
A partir das informações obtidas para formulação do Haiku e dos “números no papel de pão”, já é possível indicar algumas ADRs em status de “aberta para discussão”. Essas ADRs indicariam a “inclinação arquitetural” para diversos aspectos importantes, possibilitando debates com especialistas.
Endpoints
Parece ser adequado desenvolver o serviço como uma API REST. Destacam-se dois endpoints principais.
- Encurtamento de URL com
POST www.abc.com/shorten?url=<long-url>
- Redirecionamento com
POST www.abc.com/<short-url>
Redirecionamentos
Há duas opções básicas de redirecionamento em HTTP:
- Status code 301 – indicando que o recurso endereçado pela URL solicitada foi movido permanentemente para um novo endereço;
- Status code 302 – indicado que o recurso endereçado pela URL solicitada foi movido temporariamente para um novo endereço
Retornar 301 é, de longe, a forma mais econômica de implementar o redirecionamento, afinal, evitará que os servidores do serviço sejam acionados desnecessariamente, uma vez que o browser cliente deverá promover o redirecionamento sozinho.
Retornar 302, por outro lado, não diminui a quantidade de acionamentos, mas habilita fazer tracking de acesso e gerar estatísticas (algo desnecessário, conforme o negócio)
Sempre valide com o negócio o que está indicado nas expectativas antes de tomar decisões que sejam absolutamente difíceis de reverter. |
Pelo indicado, até aqui, nas informações de negócio, o retorno mais adequado é 301.
Tamanho da chave para URLs encurtadas
Cada URL longa deverá ser submetida a uma função de hashing capaz de gerar uma chave encurtada. Essa chave poderá ser composta por números (0-9) e letras (a-z, A-Z), totalizando 62 possíveis caracteres.
Em análise simples, chaves com 6 caracteres de comprimento seriam mais que suficientes para acomodar o período estimado de operação. Entretanto, 7 caracteres seriam suficientes para a eternidade.
Estratégia para geração da chave
Sabendo-se o tamanho adequado da chave (6 ou 7 caracteres) é interessante determinar qual seria a estratégia para geração da chave.
Uma primeira abordagem possível seria utilizar algum algoritmo de hashing como CRC32 ou MD5. O problema é que ambos geram saídas com mais de 7 caracteres (CRC32 tem 8 caracteres e MD5 tem 32 caracteres), demandando alguma estratégia de corte.
Além disso, há riscos de colisões. Ou seja, duas URLs gerando chaves idênticas (risco significativamente ampliado com o necessidade de corte). Na prática, o uso de hashing implica em “idas e voltas” ao banco para detecter chaves já utilizadas em consultas potencialmente onerosas, eventualmente minimizadas pela adoção de técnicas como Bloom Filters.
Bloom Filter
Um Bloom Filter é uma estrutura de dados probabilística, que demanda pouquíssimo espaço, concebida por Burton Howard Bloom em 1970. Ela é utilizada para testar se um elemento está presente em um conjunto sem necessitar consultar a lista completa de elementos presente nesse conjunto.
Eventualmente, a estrutura pode apontar um falso positivo (indicando que um elemento está em um conjunto quando, na verdade, não está). Entretanto, jamais gera um falso negativo.
Quanto mais elementos são adicionados a uma Bloom filter, maiores são as chances de um falso positivo.
Outra alternativa é utilizar o índice inteiro, auto-incrementado, para gerar chaves através de conversão usando base62 (aderente a quantidade de caracteres suportados). A obtenção dos índices contínuos sem gerar gargalos em um sistema distribuído poderia acontecer pela adoção da técnica como HiLo.
HiLo
HiLo é uma técnica extremamente eficiente para gerar sequências numéricas, sem riscos de colisão, em ambientes distribuídos.
Nessa técnica “clientes” HiLo solicitam para um servidor um intervalo de identificadores, por exemplo [0-32] que não será mais fornecido em qualquer futura requisição. Caberá ao servidor, manter controle dos intervalos fornecidos.
Com posse do intervalo, um “cliente” HiLo poderá utilizar seus elementos com segurança.
Entre as duas abordagens, a melhor solução parece ser aquela que utiliza índices auto-incrementados.
Caching
Toda vez que escalabilidade figurar entre os principais atributos de qualidade de um sistema, deve-se considerar a utilização de caching. |
Como a expectativa de que a proporção de leituras e gravações é de 10 para 1, faz sentido considerar a adoção de estratégias de caching. Aparentemente, a melhor solução aparenta ser caching distribuído, eventualmente recorrendo a alguma solução de borda.
Estilo arquitetural e principais tecnologias candidatas
Pontos que ainda necessitam reflexão
O processo de elaboração da arquitetura deve ser incremental. Tão importante quanto relacionar decisões realizadas é indicar claramente o que ainda precisa ser ponderado.
- Rate Limiting, visando mitigar o risco potencial de usuários mal-intencionados enviarem um número esmagadoramente grande de solicitações de encurtamento de URL.
- Escalabilidade para banco de dados e aplicação, afinal, até aqui, consideramos apenas o caminho mais fácil que seria utilizando FaaS.
Proposta inicial de solução
Com base nas informações elementares do Haiku e das ADRs, uma boa proposição de design para implementação, suficiente para iniciar as discussões, seria a indicada no diagrama abaixo.
No diagrama abaixo, uma proposta de solução usando Azure.
Takeaways
A elaboração desse “início de trabalho arquitetural” para um “encurtador de URLs” permite algumas lições importantes:
- Mesmo soluções muito simples se tornam desafiadoras quando envolvem suporte a escala.
- Pensar a arquitetura fica muito mais simples quando parâmetros abstratos, como desempenho e escala, são explicitados em números (mesmo que “de papel de pão”).
- Sempre há mais de uma alternativa para resolver um problema arquitetural e, consequentemente, trade-offs.
- Conhecer boas estruturas/estratégias de dados (como Bloom Filters e HiLo) podem ajudar a viabilizar algumas propostas de design.
- Em tempos de “nuvem”, uma primeira boa “arquitetura de solução” serve como ponto de partida para discussões mais profundas.
Dúvidas ou sugestões? Deixe suas contribuições nos comentários.