Estudo de caso · Stack

Como a Shopify escalou um dos maiores apps em Rails do mundo

A Shopify roda lojas online e físicas de milhões de lojistas. O núcleo ainda é um monólito em Ruby on Rails, organizado em módulos e dividido em pods isolados com MySQL fatiado, rodando em Kubernetes no Google Cloud, com React, GraphQL e React Native do lado do cliente.
Copiar stackshopify.com Plataforma de e-commerce · Canadá · fundada em 2006

A stack da Shopify

Abrir no montador

Linguagem

Biblioteca de interface

  • Reactshopify.engineering

    Monta o painel da Shopify, no lugar do Batman.js feito em casa.

    Por quê: Os recursos e ferramentas para quem desenvolve são muito melhores que os do Batman.js.

Framework full-stack

  • Remixshopify.engineering

    Dá o carregamento de dados e as rotas do Hydrogen, o framework da Shopify para vitrines personalizadas.

    Por quê: Resolve os problemas de carregamento de dados, rotas e erros que quem usava o Hydrogen enfrentava.

Hospedagem

  • Google Cloudshopify.engineering

    Hospeda as cargas de produção da Shopify depois da saída dos data centers próprios.

    Por quê: A Shopify disse que o Google compartilha os valores dela em código aberto, segurança, desempenho e escala.

  • Kubernetesshopify.engineering

    Orquestra os serviços e pods no Google Kubernetes Engine.

    Por quê: A Shopify não tinha como orquestrar, e o Kubernetes, do time que fez o Borg, era a opção mais promissora.

  • OpenRestyshopify.engineering

    Roda o Nginx com Lua como balanceadores de carga programáveis.

Banco de dados

  • MySQLshopify.engineering

    É o banco principal, fatiado para cada pod guardar as suas lojas.

    Por quê: Cada lojista é independente dos outros, o que fez o fatiamento por loja funcionar bem.

  • Vitessshopify.engineering

    Escala na horizontal o MySQL por trás do backend em Rails do app Shop.

    Por quê: Fatia e refatia o MySQL sem quebrar o SQL, e a Shopify queria continuar operando os próprios bancos.

Framework de celular

  • React Nativeshopify.engineering

    É o padrão de todo app novo de celular da Shopify.

    Por quê: Junta iOS e Android num stack só e aproveita o que o time web já sabe de React.

Build e runtime

  • Buildkiteshopify.engineering

    Roda em paralelo os testes do monólito na CI.

    Por quê: Deixa rodar os testes do jeito deles, nas máquinas deles.

Busca de dados

  • Redisshopify.engineering

    Sustenta filas e jobs em segundo plano.

  • Apache Kafkashopify.engineering

    Funciona como o registro de mensagens que alguns serviços usam para conversar.

  • GraphQLshopify.engineering

    É a camada de dados do painel e dos apps de celular.

    Por quê: Impede que a regra de negócio vaze para o cliente.

Framework de servidor

  • Ruby on Railsshopify.engineering

    Roda o monólito central da Shopify, organizado como monólito modular.

    Por quê: A empresa diz que a aposta no Rails moldou o jeito de pensar do time e permitiu lançar produto o mais rápido possível.

Como montaram

A aposta no Rails e o monólito modular

A Shopify nasceu em Ruby on Rails, e a empresa diz que essa aposta moldou o jeito de pensar do time e permitiu lançar produto o mais rápido possível. Mais de mil pessoas já trabalharam no mesmo código.

Em vez de quebrar tudo em microsserviços, um time começou em 2017 a "componentização": reorganizar o código por área do negócio (pedidos, frete, cobrança) e dar a cada componente uma API pública e dados próprios. Escolheram um monólito modular porque microsserviços trazem seus próprios custos, como mais pipelines, latência de rede e refatorações mais difíceis.

Fontes:shopify.engineering shopify.engineering

Pods, MySQL fatiado e Vitess

O MySQL é o banco principal desde o começo. Como cada lojista é independente dos outros, deu para fatiar o banco por loja, e cada pod é uma cópia isolada da Shopify com seus próprios bancos. Um incidente com um Redis compartilhado, apelidado de "Redismageddon", criou a regra de evitar recursos divididos pela plataforma inteira.

O app Shop, voltado ao consumidor, tem umas dez vezes mais usuários do que a Shopify tem lojistas, e precisava de outro modelo. Em 2024 a Shopify contou que levou o backend em Rails dele para o Vitess, que fatia o MySQL sem abrir mão do SQL e deixa a operação dos bancos com eles.

Fontes:shopify.engineering shopify.engineering

Dos data centers próprios para o Google Cloud

Por doze anos a Shopify manteve os próprios data centers. A partir de 2016 começou a ir para o Google Cloud, e em março de 2018 mais da metade das cargas já tinha migrado, com mais de 400 serviços de produção rodando em Kubernetes.

A Shopify escolheu o Kubernetes porque não tinha uma solução de orquestração e essa era a mais promissora, feita pelo time do Borg do Google. Ele também substituiu o Chef e facilitou subir os recursos de cada pod novo.

Fontes:shopify.engineering shopify.engineering

Deixando o próprio Ruby mais rápido

Em vez de largar o Ruby, a Shopify investiu nele. O time criou o YJIT, um compilador just-in-time que entrou no Ruby 3.2, e em 2023 colocou ele em todo o Storefront Renderer, o serviço que monta as vitrines das lojas.

Na produção, as requisições ficaram de 5% a 10% mais rápidas de ponta a ponta, e o gasto extra de memória caiu para cerca de um terço do que era no Ruby 3.1.

Fontes:shopify.engineering

Um stack de React do painel ao celular e às vitrines

O painel começou com jQuery, prototype.js e um framework da casa chamado Batman.js, e depois foi para React e TypeScript, com o GraphQL tirando a regra de negócio do cliente. Em 2020 a Shopify decidiu que todo app novo de celular seria em React Native, porque o conhecimento de React do time web servia e os times chegaram a 99% de código igual entre iOS e Android.

Em 2022 o time do Remix entrou na Shopify, e o Hydrogen, o framework em React para vitrines personalizadas, passou a usar o modelo de carregamento de dados do Remix.

Fontes:shopify.engineering shopify.engineering shopify.engineering

Também detectado no site

Achado na página inicial com as regras abertas do Wappalyzer (HTML, scripts e cabeçalhos). Mostra o que roda no navegador, não o backend inteiro.

  • Cloudflare
  • HSTS
  • HTTP/3