três anos de scala em produção: desafios, aprendizados e dores de cabeça
TRANSCRIPT
![Page 1: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/1.jpg)
Três anos de Scala em Produção: desafios, aprendizados e dores de
cabeçaFelipe Hummel Onilton Maciel
![Page 2: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/2.jpg)
• Site profissional de monitoramento de notícias
• Coletando diariamente +30K sites
• 140M de notícias
• 5M/mês
• +20 máquinas no EC2
• 2 Devs Backend + 3 Devs PHP/Frontend/Aplicação
• 3 anos com Scala em produção
• 30K linhas de código Scala
![Page 3: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/3.jpg)
Como começamos em Scala?
• 2010/2011
• Scala 2.7 => Scala 2.8
• Início na Spix em Janeiro de 2012
• busk.com
• Código legado em Ruby
• Ninguém viu, ninguém sabia
• Código feito por “consultoria"
• O que fazer?
![Page 4: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/4.jpg)
Como começamos em Scala?
• Movemos a Busca para o ElasticSearch usando Scala.
• Resolvemos contornar o código Ruby (nada contra)
• ElasticSearch pega direto do BD ao invés de conversar com o Coletor de noticias
• Coletor de Feed RSS deixava notícias passarem (intervalo de coleta fixo gerava atrasos)
• Começamos a implementar o nosso coletor em Scala + Akka
![Page 5: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/5.jpg)
Busk => NewsMonitor
• busk.com foi fechado e pivotamos para o NewsMonitor (profissional)
• Decisão de reaproveitar código legado em Ruby ou criar novo
• Em Scala? Ruby? Python?
![Page 6: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/6.jpg)
Busk => NewsMonitor
• busk.com foi fechado e pivotamos para o NewsMonitor (profissional)
• Decisão de reaproveitar código legado em Ruby ou criar novo
• Em Scala? Ruby? Python?
• Escolhemos PHP
• Por boas razões no momento
![Page 7: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/7.jpg)
CrawlerSlaveCrawlerSlave
Elastic SearchElastic Search
MySQL
Arquitetura
FeedCrawler
SiteCrawler
CrawlerSlave
Stark (processamento) Indexer
MySQL Redis SearchAPI
Elastic Search
![Page 8: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/8.jpg)
Arquitetura
Stark (processamento) Indexer
SearchAPI
autocomplete
SocialCrawler
CrawlerSlaveCrawlerSlave
FeedCrawler
SiteCrawler
CrawlerSlave
MySQLMySQL Redis
Elastic SearchElastic SearchElastic Search
![Page 9: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/9.jpg)
![Page 10: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/10.jpg)
![Page 11: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/11.jpg)
Scala: 2.7 ao 2.12• 2.9 Maio/2011 <— NewsMonitor
• 2.10 - Janeiro/2013
• String interpolation, value classes, scala.concurrent
• Pressão da comunidade para fazer upgrade
• Muitas libs exigindo 2.10 (macros, macros, macros!)
• Começamos a migrar em agosto de 2013. Mas 100% 2.10 só em agosto de 2014.
![Page 12: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/12.jpg)
Scala: 2.7 ao 2.12• 2.11 - Abril/2014
• Poucas novas features (case class > 22)
• Pouca pressão para fazer upgrade
• Maioria das libs cross-compilando 2.10/2.11
• Retro-compatibilidade bem melhor que 2.9 => 2.10
• 2.12 - Janeiro/2016 ???
• Java 8 only.
• Melhor performance de lambdas?
• @interface traits
• Vamos de 2.10 => 2.12?
![Page 13: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/13.jpg)
Scala: 2.7 ao 2.12• Retro-compatibilidade melhorou bastante
• Linguagem vai mais devagar agora
• Libs que param no tempo ainda podem ser problema (cross-compila aí fazendo favor!)
• Caso Querulous (https://github.com/twitter/querulous)
• Ótimo wrapper do JDBC feito pelo Twitter
• 3 anos sem commits (niver semana passada)
• Oficialmente compilado só pra 2.9
• Vários forks com ports para 2.10
• Caso Goose (https://github.com/GravityLabs/goose)
• Forks com PRs e compilação pra 2.10
![Page 14: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/14.jpg)
Deploy e Ops• Simples (mas automatizado)
• SSH
• git pull
• sbt compile (sbt start-script)
• sudo restart crawler
• Deploys elásticos
• Gerar AIM/docker/algo ou gerar fat-jar (sbt-assembly)
• Hoje, geramos AIMs mas queremos mudar pra fat-jar.
![Page 15: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/15.jpg)
SBT• Simple Build Tool?
• Sintaxe um pouco esotérica
• Nunca tivemos muitos problemas
• Usamos apenas build.sbt
• Um projeto por repositório. Sem multi-projects
• Dica: sempre especificar versão do SBT no project/build.properties
• Sempre: sbt ~compile OU sbt ~test OU sbt “~test-only …”
![Page 16: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/16.jpg)
Compilador• Compilação é lenta
• Compilação incremental (sbt ~compile) resolve na maior parte do tempo
• Mudar algo importante do projeto gera uma compilação lenta
• Crawler com 9.1K linhas
• sbt clean compile => 1min 27segs
• Projetos maiores devem sofrer mais
![Page 17: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/17.jpg)
Estilo de Scala• Muitas formas de escrever o mesmo código
• Um mais cool, outro mais funcional, outro mais imperativo
• Qual usar?
![Page 18: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/18.jpg)
Estilo de Scala
![Page 19: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/19.jpg)
Estilo de Scala<— Usamos<— Usamos
<— Usamos<— Usamos
<— Usamos
![Page 20: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/20.jpg)
Estilo de Scala
![Page 21: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/21.jpg)
Estilo de Scala
![Page 22: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/22.jpg)
Estilo de Scala• Empolgação é nossa inimiga
• Typeclasses são legais mas não precisamos criar uma implementação própria pra serialização, pra JSON, pra concorrência, pra….
• Implicits são legais mas toda função ter implicit é NÃO
• UrlFetcher no Crawler funcionou muito bem
• Macros são legais. Nunca chegamos a criar novos
• Implicit conversions são legais mas podem gerar código aparentemente mágico
• Se usar, é bom limitar o escopo onde é utilizado
• Densidade de código
![Page 23: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/23.jpg)
Dicas• Cuidado com default parameter
• Dois parâmetros do mesmo tipo com default
• Adicionar parâmetro com default e esquecer de mudar os lugares que precisavam passar
• null não kct! Option sempre
• Toda equipe tentar seguir o mesmo padrão
• Code review ajuda a manter estilo
![Page 24: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/24.jpg)
Estilo de Scala• ScalaStyle (https://github.com/scalastyle/scalastyle)
• Scapegoat (https://github.com/sksamuel/scalac-scapegoat-plugin)
• Wart remover (https://github.com/typelevel/wartremover)
• Linter (https://github.com/HairyFotr/linter)
• CPD (https://github.com/sbt/cpd4sbt)
• Abide (https://github.com/scala/scala-abide)
• Caminhando pra ser “O" oficial agora
![Page 25: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/25.jpg)
Estilo de Scala• scalacOptions += “-deprecation"
• scalacOptions += “-unchecked” (unchecked type-args)
• scalacOptions += “-feature” (reclama de features avançadas)
• scalacOptions += “-Xlint" (faz checagens de boas práticas)
• Tem gente que usa: scalacOptions += "-Xfatal-warnings"
![Page 26: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/26.jpg)
Akka• Framework para concorrência baseada (principalmente)
em Actors
• Actors são objetos "especiais"
• Você não chama um método de um Actor de fora dele
• Você manda uma mensagem (objetos imutáveis) para ele e em algum momento no futuro ele vai processar
• Qualquer código dentro de um Actor é garantido que só vai rodar em condições thread-safe
![Page 27: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/27.jpg)
Akka
![Page 28: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/28.jpg)
Akka e NewsMonitor• Nossos Crawlers são 100% Akka
• Começamos no Akka 2.0
• 2.0 tinha coisas pouco desenvolvidas
• Como usar? Melhores práticas? Boas arquitetura?
• Remoting. Actors em máquinas diferentes
• Meu conhecimento de Akka
• Hoje: Akka 2.3
• Muito mais maduro
• Akka Cluster
![Page 29: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/29.jpg)
Akka :)• Simplifica muito o modelo mental para trabalhar com concorrência
• Cria "bolhas" onde você pode ser mutável à vontade (com moderação)
• Muito bom quando você tem Actors de vida longa e com estado mutável
• Não precisa lidar com criação/manutenção de filas (na maior parte do tempo)
• Tunar threadpools (dispatchers) não é necessário no início e é bem fácil (via config)
• O código do Actor não contém (quase) nada de lógica lidando com concorrência, threads ou threadpool
![Page 30: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/30.jpg)
Akka :(• Toma conta do código (framework)
• A relação entre actors não é tão óbvia no código quanto a relação entre objetos num código tradicional (perca de tipagem)
• Você pode acabar tunando ExecutionContexts e ThreadPool de qualquer forma. E não é trivial (independente do Akka).
• Mais "difícil" de testar
• Dá pra isolar algumas coisas e criar determinismo
• No final das contas tudo é concorrente
• Debugar é bem diferente
• Rastrear de onde uma coisa veio, pra onde vai…
![Page 31: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/31.jpg)
Akka Dicas• Não criar Actor pra executar código trivial achando que vai ser mais eficiente
• Actors tem overhead
• É comum precisar de pelo menos um Dispatcher específico pra IO
• Bulkhead: separar Dispatchers por uso para evitar starvation e garantir responsividade
• Evita que o problema de uma área atrapalhe outras
• eventually {} nos testes
• O isolamento de actors não é desculpa pra usar coisas mutáveis por toda parte
• vars não são proibidas dentro de um Actor mas é possível evitar
• Toda estrutura de dados deve ser "owned" por um Actor
• Pode ser mutável, contanto que não vaze para fora do Actor
![Page 32: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/32.jpg)
Quando Usar Akka• Quando o problema é inerentemente concorrente/paralelo
• Crawler é um bom exemplo
• Actors de vida longa e com estado mutável
• Não tão necessário se tudo o que precisa é rodar uns jobs em background.
• Dá pra ir longe com: ExecutionContexts + Future
• Mais simples de entender (e mais familiar para boa parte dos devs)
• Casos mais simples e tradicionais de "Processamento de Request" (APIs/RPCs em geral) podem ser resolvidos com Futures
![Page 33: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/33.jpg)
Outras libs• Scalatra: usamos em todas APIs
• Similar ao Sinatra (Ruby)
• Mais simples quase impossível
• Funciona muito bem para APIs
• ScalaTest
• Metrics (https://github.com/dropwizard/metrics)
• HTTP
• Dispatch (http://dispatch.databinder.net/). DSL curiosa
• WS (acoplado ao Play)
![Page 34: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/34.jpg)
Conclusões• Programação funcional é o futuro
• Options >>> null
• Case classes: parece pouco mas mudam a forma de programar
• Muito fácil se aproveitar das bibliotecas já existentes em Java
• IDE: Sublime/Eclipse/IntelliJ
• Como somos uma equipe minúscula (2), não encontramos vários problemas
• Escolhas se estivéssemos começando hoje
• Scala + SBT de certeza
• Scalatra para APIs simples. Play para uma aplicação completa (NewsMonitor)
• Querulous nunca mais. Slick? ScalikeJDBC?
• Akka no Crawler de certeza. Com Akka Cluster talvez não usaria fila externa
![Page 35: Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça](https://reader033.vdocuments.mx/reader033/viewer/2022042819/55c9a812bb61eb141c8b4655/html5/thumbnails/35.jpg)
Dúvidas?